liniux2.6软中断

上传人:cn****1 文档编号:504340569 上传时间:2023-06-21 格式:DOC 页数:9 大小:86KB
返回 下载 相关 举报
liniux2.6软中断_第1页
第1页 / 共9页
liniux2.6软中断_第2页
第2页 / 共9页
liniux2.6软中断_第3页
第3页 / 共9页
liniux2.6软中断_第4页
第4页 / 共9页
liniux2.6软中断_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《liniux2.6软中断》由会员分享,可在线阅读,更多相关《liniux2.6软中断(9页珍藏版)》请在金锄头文库上搜索。

1、6.1下半部下半部的任务就是执行与中断处理密切相关但中断处理程序本身不执行的工作。对于在上半部和下半部之间划分工作,尽管不存在某种严格的规则,但还是有一些提示可供借鉴:(1)如果一个任务对时间非常敏感,将其放在中断处理程序中执行。(2)如果一个任务和硬件相关,将其放在中断处理程序中执行。(3)如果一个任务要保证不被其它中断打断,将其放在中断处理程序中执行。(4)其它所有任务,考虑放在下半部执行。当我们开始尝试写自己的驱动程序的时候,读一下别人的中断处理程序和相应的下半部会令你受益匪浅。现在的问题是:下半部具体放到以后的什么时候去做呢?下半部并不需要指明一个确切时间,只要把这些任务推迟一点,让他

2、们在系统不太繁忙并且中断恢复后执行就可以了。通常下半部在中断处理程序一返回就会马上执行。下半部执行的关键在于当它们运行的时候,允许响应所有中断。6.1.1为什么要用下半部?因为在中断处理程序运行的时候,当前的中断线会被屏蔽,如果一个处理程序是SA_INTERRUPT类型,它执行的时候会禁止所有本地中断(而且把本地中断线全局屏蔽掉),再加上中断处理程序要与其它程序甚至是其它的中断处理程序异步执行。具体放到以后什么时候去做呢?在这里,“以后”仅仅用来强调不是“马上”而已,下半部并不需要指明一个确切时间,只是把这些任务推迟一点,让它们在系统不太繁忙并且中断恢复后执行就可以了,通常下半部在中断处理程序

3、一返回就会马上执行,下半部执行的关键在于当它们运行的时候,允许响应所有的中断。6.2软中断软中断是用软件方式模拟硬件中断的概念,实现宏观上的异步执行效果,tasklet也是基于软中断实现的。异步通知所基于的信号也类似于中断。硬中断是外部设备对CPU的中断软中断通常是硬中断服务程序对内核的中断。信号则是由内核(或其它进程)对某个进程的中断。6.2.1软中断的实现软中断是在编译期间静态分配的。不像tasklet那样能被动态的注册或去除。软中断由softirq_action结构表示,它定义在中:struct softirq_action void( *action)(struct softirq_a

4、ction *); /*待执行的函数*/Void*date; /传递给函数的参数*/ ;在kernel/softirq.c中定义了一个包含有32个该结构体的数组。static strcut softirq_action softirq_vec32; 每个注册的软中断都占据该数组中的一项。(1)软中断处理程序:软中断处理程序action的函数原型如下:void softirq_handler(struct softirq_action *)当内核运行一个软中断处理程序的时候,它就会执行这个action函数,其唯一的参数为指向相应的softirq_action结构体的指针。一个软中断不会抢占另外一

5、个软中断,实际上,唯一可以抢占软中断的是中断处理程序,不过,其它的软中断甚至是相同类型的软中断可以在其它处理器上同时执行。(2)执行软中断:一个注册的软中断必须在被标记后才会执行。这被称作触发软中断(raising the softirq)。通常,中断处理程序会在返回前标记它的软中断,使其在稍后被执行。软中断被标记后,可以用softirq_pending()检查到这个标记并按照索引号将softirq_pending()的返回值的相应位置1。在合适的时刻,该软中断就会运行,在下列地方,待处理的软中断会被检查和执行:在处理完一个硬中断以后在ksoftirqd内核线程中在那些显式检查和执行待处理的软

6、中断的代码中,如网络子系统中不管是用什么办法唤起,软中断都要在do_softirq()中执行,该函数很简单,如果有待处理的软中断,do_softirq()会遍历每一个,调用它们的处理程序。软中断在do_softirq()中执行。do_softirq()经过简化后的核心部分:u32 pending = sofeirq_pending(cpu);if(pending) struct softirq_action *h = softirq_vec;softirq_pending(cpu) = 0;do if(pending&1) h-action(h); /调用action函数 h+; pendin

7、g=1; while(pending);6.2.2使用软中断软中断保留给系统中对时间要求最严格以及最重要的下半部使用。内核定时器和tasklets都是建立在软中断上的,如果你想加入一个新的软中断,首先要想想为什么用tasklet实现不了,tasklet可以动态生成,由于它们对加锁的要求不高,所以使用起来也很方便,当然,对于时间要求养并能自己高效的完成加锁工作的应用,软中断会是正确的选择。1、分配索引:在编译期间,可以通过中定义的一个枚举类型来静态的声明软中断。2、注册处理程序:接着,在运行时通过调用open_softirq()注册软件中断处理程序,该函数有三个参数:索引号、处理函数和data域

8、存放的数值。例如网络子系统,通过以下方式注册自己的软中断:open_softirq(NET_TX_SOFTIRQ, net_tx_action,NULL);open_softirq(NET_TX_SOFTIRQ, net_rx_action,NULL);软中断处理程序的执行的时候,允许响应中断,但自己不能睡眠。3、触发你的软中断:通过在枚举类型的列表中添加新项以及调用open_softirq()进行注册以后,新的软中断处理程序就能够运行。raise_softirq()函数可以将一个软中断设置为挂起状态,让他在下次调用do_softirq()函数时投入运行。一个例子:raise_softirq(

9、NET_TX_SOFTIRQ);这会触发NET_TX_SOFTIRQ软中断。它的处理程序net_tx_action()就会在内核下一次执行软中断时投入运行。该函数在触发一个软中断前要禁止中断,触发后再恢复回原来的状态。在中断处理程序中触发软中断是最常见的形式。这样,内核在执行完中断处理程序后,马上就会调用do_softirq。于是软中断开始执行中断处理程序留给它去完成的剩余任务。6.3 Tasklet tasklet是利用软中断实现的一种下半部机制。它和进程没有任何关系。它和软中断本质上很相似,行为表现也相近,但是,它的接口更简单,锁保护也要求较低。软中断和tasklet怎样选择呢?通常你应该

10、用tasklet,软中断一般用的很少,它只在那些执行频率很高和连续性要求很高的情况下才需要,而tasklet却有更广泛的用途。6.3.1 Tasklet的实现因为tasklet是通过软中断实现的,所以它本身也是软中断。(1)tasklet结构体:tasklet由tasklet_struct结构表示。每个结构体单独代表一个tasklet,它在中定义:struct tasklet_struct struct task_struct *next; /*指向链表中的下一个tasklet */ unsigned long state; /* tasklet的状态 */ atomic_t count; /

11、* 引用计数器 */ void (*func) (unsigned long); /* tasklet处理函数 */ unsigned long data; /*给tasklet处理函数的参数 */;结构体中的func成员是tasklet的处理程序,data是它唯一的参数。state成员只能在0、TASKLET_STATE_SCHED和TASKLET_STATE_RUN之间取值。TASKLET_STATE_SCHED表明tasklet已经被调度,正准备投入运行,TASKLET_STATE_RUN表示该tasklet正在运行。只有count为0时,tasklet才被激活,否则被允许,不允许执行。

12、调度tasklet 已调度的tasklet存放在两个单处理器数据结构:tasklet_vec和task_hi_vec中。它们都是由tasklet_struct结构体构成的链表。链表中的每个tasklet_struct代表一个不同的tasklet。tasklet是由tasklet_schedule()和tasklet_hi_schedule()函数进行调度的,它们接受一个指向tasklet_struct结构的指针作为参数。Tasklet的实现通过软中断来实现的,tasklet_schedule()调度函数执行一些初始工作,紧接着唤起TASKLET_SOFTIRQ或HI_SOFTIRQ软中断,这样

13、在下一次调用do_softirq()时就会执行tasklet。那么do_softirq()函数什么时候执行呢?do_softirq()会尽可能早的在下一个合适的时机执行,由于大部分tasklet和软中断都是在中断处理程序中被设置成待处理状态,所以最近一个中断返回的时候看起来就是执行do_softirq()的最佳时机。因为TASKLET_SOFTIRQ和HI_SOFTIRQ已经被触发了,所以do_softirq会执行相应的软中断处理程序。Tasklet_action()和Tasklet_hi_action()两个处理程序就是tasklet处理的核心。总结:所有的Tasklets都通过重复运用TA

14、SKLET_SOFTIRQ或HI_SOFTIRQ这两个软中断实现,当一个tasklet被调度时,内核就会唤起这两个软中断中的一个,随后,该软中断会被特定的函数处理,执行所有已调度的tasklet,这个函数保证同一时间里只有一个给定类别的tasklet会被执行(但其它不同类型的tasklet可以同时执行),所有这些复杂性都被一个简洁的接口隐藏起来了。6.3.2使用tasklet声明你自己的tasklet可以静态创建,也可以动态创建,分别对应直接引用和间接引用。选择哪种方式取决于你到底是有(或者是想要)一个对tasklet的直接引用还是间接引用,静态创建一个tasklet(也就是有一个直接引用),

15、使用下面中定义的两个宏中的一个:DECLARE_TASKLET(name, func, data)实现了定义名称为name的tasklet并将其与func这个函数绑定,而传入这个函数的参数为data。DECLARE_TASKLET_DISABLED(name, func, data);DECLARE_TASKLET(my_tasklet, my_tasklet_handler, dev);运行代码实际上等价于:struct tasklet_struct my_tasklet = NULL, 0, ATOMIC_INIT(0), my_tasklet_handler, dev ; 这样就创建了一个名为my_tasklet,处理程序为tasklet_handler并且已经被激活的tasklet。还可以通过一个间接引用(一个指针)赋给一个动态创建的tasklet_struct结构的方式来初始化一个tasklet:Tasklet_init(t,tasklet_handler,dev);/*动态而不是静态创建*/

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号