linux tasklet函数,Tasklet - Linux内核学习之中断_Linux教程_Linux公社-Linux系统门户网站...

[概述]

Tasklet是软中断的特殊实现。Tasklet通常是下半部处理的优选机制,它在性能和易用性之间有着很好的平衡。较softirq,tasklet不需要考虑SMP下的并发问题,而又比workqueue有着更好的性能。

不同类型的tasklet可以在不同的处理器上同时执行,但同类型的tasklet不能同时执行。这就避免了并发问题。

ksoftirqd内核线程有着类似工作者线程一样的职责,它会周期的遍历软中断的向量列表,如果发现哪个软中断向量挂起了(pending),就执行相应的处理函数,

关于tasklet的实现同样可以拜读LKD3,这书真的很经典。

[实例]

staticstructinput_dev *button_dev;

staticstructtasklet_structbutton_tasklet;

在做实际的驱动开发的时候,不推荐使用全局变量,因为全局变量是造成竞争条件的主要原因。

[中断处理程序]

staticirqreturn_t button_interrupt(intirq,void*p)

{

tasklet_schedule(&button_tasklet);

returnIRQ_RETVAL(IRQ_HANDLED);

}

调用tasklet_schedule函数,把button_tasklet加入到tasklet_vec(软中断向量)链表中,并触发软中断,这样在下一次调用do_softirq函数时就会执行button_tasklet。Button_tasklet会在尽短的时间内执行。

[tasklet处理函数]

voidtasklet_handler(unsignedlongdata)

{

/*get pin value  */

intval = s3c2410_gpio_getpin(S3C2410_GPG(0));

input_report_key(button_dev,KEY_1, val);

input_sync(button_dev);

}

因为是靠软中断实现的,所以tasklet不能睡眠,这意味着不能在tasklet中使用信号量和其他可能发生阻塞的函数。但是tasklet运行时允许响应中断。

staticint__init button_init(void)

{

interr;

if(request_irq(BUTTON_IRQ, button_interrupt,

IRQ_TYPE_EDGE_BOTH,DEV_NAME, (void*)button_dev)) {

printk(KERN_ERR"cannotallocate irq");

return- EBUSY;

}

……

tasklet_init(&button_tasklet,tasklet_handler, 0);

debug("initialized\n");

return0;

}

动态初始化tasklet:

void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long), unsigned long data)

t:tasklet_struct结构体指针

func:tasklet处理函数指针

data:func的参数

静态初始化tasklet:

#define DECLARE_TASKLET(name, func, data) \

struct tasklet_struct name = { NULL, 0,ATOMIC_INIT(0), func, data }0b1331709591d260c1c78e86d0c51c18.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值