微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Linux 2.4.x内核软中断机制

Linux 2.4.x内核软中断机制

时间:04-06 来源: 点击:

当然,我们还是可以定义并使用自己的task queue,而不用tq_immediate,在drivers/char/serial.c中提到的tq_serial就是串口驱动自己定义的:

static DECLARE_TASK_QUEUE(tq_serial);

此时就需要自行调用run_task_queue(&tq_serial)来启动其中的函数了,因此并不常用。

3.tasklet

这是比task queue和bottom half更加强大的一套软中断机制,使用上也相对简单,见下面代码段:

1: void foo_tasklet_action(unsigned long t);2: unsigned long stop_tasklet;3: DECLARE_TASKLET(foo_tasklet, foo_tasklet_action, 0);4: void foo_tasklet_action(unsigned long t)5: {6: //do something7:8: //reschedule9: if(!stop_tasklet)10: tasklet_schedule(&foo_tasklet);11: }12: void foo_init(void)13: {14: stop_tasklet=0;15: tasklet_schedule(&foo_tasklet);16: }17: void foo_clean(void)18: {19: stop_tasklet=1;20: tasklet_kill(&foo_tasklet);21: }

这个比较完整的代码段利用一个反复执行的tasklet来完成一定的工作,首先在第3行定义foo_tasklet,与相应的动作函数foo_tasklet_action相关联,并指定foo_tasklet_action()的参数为0。虽然此处以0为参数,但也同样可以指定有意义的其他参数值,但需要注意的是,这个参数值在定义的时候必须是有固定值的变量或常数(如上例),也就是说可以定义一个全局变量,将其地址作为参数传给foo_tasklet_action(),例如:

int flags;DECLARE_TASKLET(foo_tasklet,foo_tasklet_action,&flags);void foo_tasklet_action(unsigned long t){ int flags=*(int *)t;...}

这样就可以通过改变flags的值将信息带入tasklet中。直接在DECLARE_TASKLET处填写flags,gcc会报"initializer element is not constant"错。

第9、10行是一种RESCHEDULE的技术。我们知道,一个tasklet执行结束后,它就从执行队列里删除了,要想重新让它转入运行,必须重新调用tasklet_schedule(),调用的时机可以是某个事件发生的时候,也可以是像这样在tasklet动作中。而这种reschedule技术将导致tasklet永远运行,因此在子系统退出时,应该有办法停止tasklet。stop_tasklet变量和tasklet_kill()就是干这个的。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top