大多数设备驱动程序都要使用中断,因此有必要了解linux的中断管理机制,Linux的中断管理机制包含中断服务例程的注册。
【中断的注册】
Linux使用request_irq()函数为中断服务例程分配一个硬件中断号并登记相应的中断程序处理例程,即所谓的注册中断,该函数在include/linux/sched.h里声明,request_irq()函数原型如下:
Int request_irq(unsigned int irq,void(*handler)(int irq,void*dev_id,struct pt_regs*regs),unsigned long inflags,const char *devname,void*dev_id);
函数的参数如下:
irq:要分配的硬件中断号。
handler:向系统登记的中断处理例程,这是一个回调函数,中断发生时,系统调用这个函数,传入的参数包括硬件的中断号,dev_id,,寄存器值。dev_id是request_ird函数传递给系统的参数的参数dev_id.
irqflags:标记中断处理属性的标志位,常用SA_INTERRUPT标志和SA_SHIRQ标志,二者可以通过位或者与运算一起使用。SA_INTERRUPT标志是快速中断标志位,如果设置了该标志,则屏蔽所有中断,中断处理程序进行快速处理,否则不屏蔽所有中断,进行慢速处理。SA_SHIRQ标志是中断共享标志位,如果设置了改标志,多个设备共享改中断。
dev_name:驱动设备的字符串名称,用来在/pro/interrupts中显示中断的所有者。
dev_id:用于共享中断号的非NULL标识,若中断没有被共享,dev_id可以设置为NULL。共享中断号时,该标识必须是全局唯一的,在释放中断时会用到它。驱动程序也可以用它来指向自己的私有数据区。一般将它设置为这个设备device结构本身,中断处理程序可以用dev_id找到相应的产生这个中断的设备。
函数成功,则返回0,返回一个负值表示出错,如返回-EBUSY表示另一个驱动已
占用了所请求的中断号。
【中断的释放】
Linux使用free_irq()函数释放中断,free_irq()的函数原型如下:
void free_irq(unsigned int irq,void*dev_id);
irq是要释放的中断号,dev_id是在注册中断时使用的设备标识。调用free_irq()的位置是设备最后一次被关闭、硬件被告知不用再中断处理器之后。