【嵌入式Linux驱动程序-基础篇】- tasklets机制

Tasklets机制

tasklet在某些方面类似于内核定时器,它们一直在中断时间运行,它们一直运行在调度它们的同一个CPU上,并且它们接收到一个unsigned long参数。不像内核定时器,我们无法请求在一个指定的时间执行函数,需要通过调度tasklet,当我们简单的调用调度后,内核将在一个适当的时间去执行。这个行为对于中断处理特别有用,即“上下半部(前后半部)”。实际上,一个tasklet就像一个内核定时器,在一个“软中断”的上下文中执行(以原子模式),在使能硬件中断时执行异步任务的一个内核机制。

1 tasklet结构声明

一个tasklet用tasklet_struct结构进行表示,我们在使用前需要初始化该结构,初始化能够通过调用一个特定的函数或者通过某些宏定义声明结构。

#include <linux/interrupt.h>

// 动态初始化tasklet_struct结构(前提已经通过分配或其他方式获得的tasklet_struct结构)
void tasklet_init(struct  tasklet_struct *t, void (*func)(unsigned long), unsigned long data);


// 静态初始化tasklet_struct结构
DECLARE_TASKLET(name, func, data);
DECLARE_TASKLET_DISABLED(name, func, data);

tasklet提供了许多特性:

  • 一个tasklet能够被禁止并且之后被重新使能;它不会执行直到被它被使能与被禁止相同的次数。
  • 如同定时器,一个tasklet可以注册它自己。
  • 可以一个tasklet被调度执行以正常的优先级或者高优先级。后一组一直是首先执行。
  • tasklet可能立即运行,如果系统不再重载下,但是从不会晚于下一个时钟滴答。
  • 一个tasklet可能和其他tasklet并发,但是对它自己是严格地串行的,即同样的tasklet从不同时运行在超过一个处理器上。同样,一个tasklet常常在调度它的同一个CPU上运行。

2 tasklet禁止接口

void tasklet_disable(struct tasklet_struct *t);

这个函数禁止给定的tasklet。tasklet可能仍然被tasklet_schedule调度,但是它的执行被延后直到这个tasklet被再次使能。如果这个tasklet当前在运行,这个函数忙等待直到这个tasklet退出;因此,在调用disklet_diskable后,你可以确保这个tasklet在系统任何地方都不在运行(即在SMP上不存在tasklet运行)。


void tasklet_disable_nosync(struct tasklet_struct *t);
禁止这个tasklet,但是没有等待任何当前的函数退出,当它返回,这个tasklet被禁止并且不回在以后被调度知道重新使能,但是它可能仍然运行在另一个CPU当这个函数返回时。

void tasklet_enable(struct tasklet_struct *t)

使能一个之前被禁止的tasklet,如果这个tasklet已经被调度,它会很快运行,一个对tasklet_enable的调度必须匹配每个对tasklet_disable的调用,因为内核跟踪每个tasklet的“禁止次数”。

 

3 tasklet使能接口

void tasklet_schedule(struct tasklet_struct *t);
调度tasklet执行,如果一个tasklet被再次调度在它有机会运行前,它只运行一次。但是,如果它在运行中被调度,它在完成后再次运行;这个保证了其他事件被处理当中发生的事件收到应有的注意。这个做法允许一个tasklet重新调度它自己。

注:只要tasklet没运行前,多次调度,其只运行一次。然而在运行中,若被调度,则其完成后将会再执行多一次。


void tasklet_hi_schedule(struct tasklet_struct *t);

调度tasklet在更高优先级执行,当软中断处理运行时,它处理高优先级tasklet在其他软中断之前,包括“正常的”tasklet。理想地,只有具有地响应周期要求(例如填充音频缓冲)应当使用这个函数,为避免其它软件中断处理映入的附加周期。


void tasklet_kill(struct tasklet_struct *t);

这个函数确保了这个tasklet没有再次调度来运行;它常常被调用当做一个设备整备关闭或者模块卸载时,如果这个tasklet被调度来运行,这个函数等待直到它已执行。如果这个tasklet重新调度它自己,你必须阻止在调度tasklet_kill前它重新调度自己。


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值