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);
...........
}