中断底半部机制之tasklet详解

tasklet 的使用较简单,我们只需要定义tasklet 及其处理函数并将两者关联,例如:

void my_tasklet_func(unsigned long); /*定义一个处理函数*/
DECLARE_TASKLET(my_tasklet, my_tasklet_func, data);
/*定义一个tasklet 结构my_tasklet,与my_tasklet_func(data)函数相关联*/

代码 DECLARE_TASKLETmy_tasklet,my_tasklet_func,data)实现了定义名称为my_tasklet tasklet并将其与my_tasklet_func()这个函数绑定,而传入这个函数的参数为data。my_tasklet的类型为struct tasklet_struct。

在需要调度 tasklet 的时候引用一个tasklet_schedule()函数就能使系统在适当的时候进行调度运行,如下所示:

tasklet_schedule(&my_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, struct pt_regs *regs)
{
    ...
    tasklet_schedule(&xxx_tasklet);/*在合适的时机调用底半部*/
    ...
}

/*设备驱动模块加载函数*/
int __init xxx_init(void)
{
    ...
    /*申请中断*/
    result = request_irq(xxx_irq, xxx_interrupt, SA_INTERRUPT, "xxx", NULL);
    ...
}

/*设备驱动模块卸载函数*/
void __exit xxx_exit(void)
{
    ...
    /*释放中断*/
    free_irq(xxx_irq, xxx_interrupt);
    ...
}

上述程序在模块加载函数中申请中断(第24 行),并在模块卸载函数中释放它(第33 行)。

对应于xxx_irq 的中断处理程序被设置为xxx_interrupt()函数,在这个函数中,第15 行的tasklet_schedule&xxx_tasklet)调度的tasklet 函数xxx_do_tasklet()在适当的时候得到执行。上述代码第 12 行显示中断处理程序顶半部的返回类型为irqreturn_t,它定义为int,中断处理程序顶半部一般返回IRQ_HANDLED

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值