品味内核中断上下半部
在《初尝内核中断》里我们了解了Linux内核中断模块的实现,也体验了一番共享中断的魅力,但上面这样的中断程序把任务都交到了服务子程序里去处理,这在单片机等性能要求不高的嵌入式系统里还好,但在我们的Linux等多任务嵌入式系统里,那这可是大大的浪费效率的做法,故而在Linux的内核中断里有上下半部的处理模式,将响应中断后最紧要的内容处理完后,就把不慌不忙的内容交到下半部去处理,即上半部处理最急需处理的内容,这样不需要非得该中断处理完再去响应同一中断线上的另一个中断请求了,效率也提上来了。 总的来说,上半部(top half)主要是处理与硬件交互等急切的事件,然后就把交互来的数据或请求等需求处理交到下半部(bottom half)去处理,下半部就处理这些比较费时的内容,并且还有可能被打断,下半部的执行由Linux Kernel去安排其时机。 Linux下半部机制由softirq、tasklet和工作队列等来实现,由于softirq与tasklet很相似,在中断里也较少使用,我们这里就学习下tasklet和工作队列(workqueue,在嵌入式Linux较常使用)机制。 1.tasklet机制 tasklet(小任务)也是在软中断(softirq,不是软件中断)的基础上实现的,但两个相同的tasklet是不会同时执行的,就算在不同的处理器上也不行。多次被调试时,tasklet也只运行一次。 在Linux Kernel源码的include/linux/interrupt.h文件里,关于tasklet有如下的结构体: struct tasklet_struct { struct tasklet_struct *next; unsigned long state; atomic_t count; void (*func)(unsigned long); unsigned long data; }; 其中,next指向下一个tasklet,state表示当前tasklet的状态,有同一文件里有如下枚举: enum { TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ TASKLET_S...