Tasklet机制

一、tasklet使用

Tasklet的使用比较简单,只需要定义tasklet及其处理函数并将两者关联

例子:

Void my_tasklet_func(unsigned long)

DECLARE_TASKLET(my_tasklet,my_tasklet_func,data) //原型在 二中有描述

代码DECLARE_TASKLET实现了定义名称name为my_tasklet的tasklet并将其与my_tasklet_func这个函数绑定,而传入这个函数的参数为data。

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

Tasklet_schedule(&my_tasklet)

下面给出驱动模板

 

[cpp]  view plain  copy
  1. void xxx_do_tasklet(unsigned long);  
  2.   
  3. DECLARE_TASKLET(xxx_tasklet,xxx_do_tasklet,0);  
  4.   
  5. void xxx_do_tasklet(unsigned long)  
  6.   
  7. {  
  8.   
  9. ……  
  10.   
  11. }  
  12.   
  13. irqreturn_t xxx_interrupt(int irq,void *dev_id,struct pt_regs *regs)  
  14.   
  15. {  
  16.   
  17.       ……  
  18.   
  19.       tasklet_schedule(&xxx_tasklet);  
  20.   
  21.       ……  
  22.   
  23. }  
  24.   
  25. int _init xxx_init(void)  
  26.   
  27. {  
  28.   
  29.       ……  
  30.   
  31.       result=request_irq(xxx_irq,xxx_interrupt,SA_INTERRUPT,”xxx”,NULL)  
  32.   
  33.       ……  
  34.   
  35. }  
  36.   
  37. void _exit xxx_exit(void)  
  38.   
  39. {  
  40.   
  41.       ……  
  42.   
  43.       free_irq(xxx_irq,xxx_irq_interrupt);  
  44.   
  45.       ……  
  46.   
  47. }  


二、tasklet函数详解

它对于中断处理特别有用:硬件中断必须尽快处理, 但大部分的数据管理可以延后到以后安全的时间执行。

tasklet 以一个数据结构形式存在,使用前必须被初始化。初始化能够通过调用一个特定函数或者通过使用某些宏定义声明结构:



 

[cpp]  view plain  copy
  1. #include <linux/interrupt.h>   
  2. struct tasklet_struct  
  3. {  
  4.     struct tasklet_struct *next;  
  5.     unsigned long state;  
  6.     atomic_t count;  
  7.     void (*func)(unsigned long);  
  8.     unsigned long data;  
  9. };  
  10. void tasklet_init(struct tasklet_struct *t,  
  11.  void (*func)(unsigned long), unsigned long data);  
  12.   
  13. #define DECLARE_TASKLET(name, func, data) \  
  14. struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }  
  15. #define DECLARE_TASKLET_DISABLED(name, func, data) \  
  16. struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data }  
  17.   
  18. void tasklet_disable(struct tasklet_struct *t);   
  19. /*函数暂时禁止给定的 tasklet被 tasklet_schedule 调度,直到这个 tasklet 被再次被enable;若这个 tasklet 当前在运行, 这个函数忙等待直到这个tasklet退出*/  
  20. void tasklet_disable_nosync(struct tasklet_struct *t);   
  21. /*和tasklet_disable类似,但是tasklet可能仍然运行在另一个 CPU */  
  22. void tasklet_enable(struct tasklet_struct *t);   
  23. /*使能一个之前被disable的 tasklet;若这个 tasklet 已经被调度, 它会很快运行。 tasklet_enable 和tasklet_disable必须匹配调用, 因为内核跟踪每个 tasklet 的"禁止次数"*/   
  24. void tasklet_schedule(struct tasklet_struct *t);   
  25. /*调度 tasklet 执行,如果tasklet在运行中被调度, 它在完成后会再次运行; 这保证了在其他事件被处理当中发生的事件受到应有的注意. 这个做法也允许一个 tasklet 重新调度它自己*/  
  26. void tasklet_hi_schedule(struct tasklet_struct *t);   
  27. /*和tasklet_schedule类似,只是在更高优先级执行。当软中断处理运行时, 它处理高优先级 tasklet 在其他软中断之前,只有具有低响应周期要求的驱动才应使用这个函数, 可避免其他软件中断处理引入的附加周期*/  
  28. void tasklet_kill(struct tasklet_struct *t);   
  29. /*确保了 tasklet 不会被再次调度来运行,通常当一个设备正被关闭或者模块卸载时被调用。如果 tasklet 正在运行, 这个函数等待直到它执行完毕。若 tasklet 重新调度它自己,则必须阻止在调用 tasklet_kill 前它重新调度它自己,如同使用 del_timer_sync*/  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值