1.中断
#中断使得硬件得以发出通知给处理器,本质上是一种电信号
#中断随时可以产生,内核随时会被打断
#不同设备的中断不同,每个中断都通过一个唯一的数字标识,称为IRQ(中断请求)
2.中断处理程序
#响应中断的时候,内核会执行一个函数(中断处理程序或中断服务例程)
#在Linux中,中断程序为普通的C函数
3.上半部和下半部的对比
#中断处理分为两部分:上半部和下半部
#上半部:中断处理程序,接收到一个中断,立刻执行
#下半部:允许稍后完成的工作
4.注册中断处理程序
#中断处理程序是硬件驱动程序的组成部分,如果设备使用中断,那么相应的驱动就注册一个中断处理程序
#驱动程序通过request_irq()函数注册一个中断处理程序,并激活给定的中断线
requset_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
1.中断处理程序标识
#第一个参数irq表示要分配的中断号
#第二个参数handler是一个指针,指向处理这个中断的实际中断处理程序
#第三个参数flags可以为0,也可以为:
-IRQF_DISABLED:该标志被设置后意味着处理中断处理程序本身之间期间中断所有其他中断
-IRQF_SAMPLE_RANDOM:此标志表明这个设备产生的中断对内核熵池有贡献,内核熵池负责从各种随机事件导出真正的随机数
-IRQF_TIMER:该标志是特别为系统定时器的中断处理准备的
-IRQF_SHARED:此标志表明可以在多个中断处理程序之间共享中断线
#第四个参数name是与中断相关的设备的ASCII文本表示
#第五个参数dev用于共享中断线
#request_irq()成功执行会返回0,如果返回非0,则有错误
#request_irq()函数可能会睡眠,因此,不能在中断上下文或其他不允许阻塞的代码中调用该函数
2.一个中断例子:
request_irq():
if(request_irq(irqn, my_interrupt, IRQF_SHARED, "my device", my_dev)){
printk(KEEN_ERR, "my_device: cannot register IRQ %d\n", irqn);
return -EIO;
}
3.释放中断处理程序
#卸载驱动程序时,需要注销相应的中断处理程序,并释放中断线,调用:
void free_irq(unsigned int irq, void *dev)
如果这条中断线不是共享的,则函数删除中断处理程序并禁用中断线
如果这条中断线是共享的,则只删除*dev对应中断处理程序,只要在删除了该中断线上的所有中断处理程序后,才会禁用中断线
5.编写中断处理程序