Linux實現底半部機制主要有tasklet,工作隊列和軟中斷。
1.tasklet
tasklet的使用較簡單,我們只需要定義tasklet及其處理函數並將兩者關聯。使用模版如下:
/*定義tasklet和底半部函數並關聯*/
void xxx_do_tasklet(unsigned long);
DECLARE_TASKLET(xxx_tasklet,xxx_do_tasklet,0);
/*中斷處理底半部*/
void xxx_do_tasklet(unsigned long)
{
........
}
/*中斷處理頂半部*/
irqreturn_t xxx_interrupt(int irq,void *dev_id)
{
..........
tasklet_schedule(&xxx_tasklet);
...........
return IRQ_HANDLED;
}
/*設備驅動模塊加載函數*/
int __init xxx_init(void)
{
.......
/*申請中斷*/
result = request_irq(xxx_irq,xxx_intertupt,IRQF_DISABLED,"xxx",NULL);
.........
}
/*設備驅動卸載模塊函數*/
void __exit xxx_exit(void)
{
.........
/*釋放中斷*/
free_irq(xxx_irq,xxx_interrupt);
...........
}
2.工作隊列使用模板
/*定義工作隊列和關聯函數*/
struct work_struct xxx_wq;
void xxx_do_work(unsigned long);
/*中斷處理底部*/
void xxx_do_work(unsigned long)
{
...............
}
/*中斷處理頂半部*/
irqreturn_t xxx_interrupt(int irq,void *dev_id)
{
..........
schedule_work(&xxx_wq);
...........
return IRQ_HANDLED;
}
/*設備驅動模塊加載函數*/
int __init xxx_init(void)
{
.......
/*申請中斷*/
result = request_irq(xxx_irq,xxx_intertupt,IRQF_DISABLED,"xxx",NULL);
.........
/*初始化工作隊列*/
INIT_WORK(&xxx_wq,(void(*)(void *)) xxx_do_work,NULL);
.........
}
/*設備驅動卸載模塊函數*/
void __exit xxx_exit(void)
{
.........
/*釋放中斷*/
free_irq(xxx_irq,xxx_interrupt);
...........
}