linux 软中断的使用
软中断保留给系统中对时间要求最严格以及最重要的下半部使用。目前只有两个子系统直接使用了软中断 (网络和SCSI)内核定时器和tasklet也是建立在软中断上的 编译期间在<linux/interrupt.h>定义一个枚举类型来静态的申明一个软中断 注册你的处理程序 open_softirq();//注册中断处理函数 例如: open_softirq(NET_TX_SOFTIRQ,net_tx_action); open_softirq(NET_RX_SOFTIRQ,net_rx_action); 这里会有共享数据的问题,要有严格的锁保护,甚至是处理程序内部的变量。 在中断处理函数当中触发软中断是最常见的形式。 中断挂起函数: raise_softirq(); 软中断与中断处理程序一起完成中断的上半部与下半部 tasklet的实现: 其本身也是软中断,有两类中断代表 HI_SOFTIRQ和TASKLET_SOFTIRQ 结构体的定义在<linux/interrupt.h>当中 struct tasklet_struct{ struct tasklet_struct *next; unsigned long state; atomic_t counjt; //引用计数器(什么鬼) void (*func)(unsigned long); //tasklet处理函数 unsigned long data ;//给tasklet处理函数的参数 }; 这里要注意的是count成员是tasklet的引用计数器,如果不为0,则tasklet禁止,不允许执行 为零是被激活,,并且被设置为挂起状态时,tasklet才能够执行 tasklet 由tasklet_schdule()和task_hi_schedule()进行调度。 tasklet是实现寻常设备下半部的最佳选择。tasklet可以动态创建,使用方便。 使用tasklet 如果进行静态的创建,使用<linux/interrupt.h>中定义的两个宏当中的一个 DECLEAR_TASKLET(name,func,data); DECLEAR_TASKLET_DISABLE(name,func,data); //参数由data变量给出,区别在于计数器的初始值不同。DECLEAR_TASKLET()默认激活,DECLEAR_TASKLET_DISABLE()默认未激活。 DECLEAR_TASKLET(my_tasklet,my_tasklet_handler,dev); 等价于: struct struct_tasklet my_tasklet{ NULL, 0, ATOMIC_INIT(0), my_tasklet_handler, dev; }; 编写自己的tasklet处理函数; void tasklet_handler(unsigned long data); //规定的函数类型 由于使用软中断实现,所以tasklet不能睡眠,所以不能在tasklet中使用信号量或者其他阻塞式的函数。tasklet运行时允许相应 中断,所以要做好预防工作,如果tasklet和中断处理程序之间共享了某些数据的话,两个相同的tasklet不会同时运行。 今天的记录先到这里。爱你YZ。