中断就是程序在正常执行过程中被打断,暂时停止运行当前代码而跳转去执行相应的服务代码,在完成相应的服务任务之后继续执行之前被打断的程序。在驱动程序中,硬件在需要时向内核发出信号。相比轮询模型而言,中断模型避免了让cpu周期性地重复执行,节省了cpu时间,提高了效率。

    Linux下的中断体系机构或者说当中断来临后,cpu做了哪些工作,通过分析内核代码,可以得出以下总结,即中断体系结构:

当中断来临,cpu中断处理流程:

a.中断向量调用入口函数asm_do_IRQ,传入中断号irq

b.asm_do_IRQ函数根据终端号irq调用irq_desc[irq].handle_irq,它是这中断处理函数的入口,对于电平触发中断,入口函数为handle_level_irq,对于边沿触发中断,入口函数为handle_edge_irq

c.入口函数首先清楚中断,若入口函数是handle_level_irq要屏蔽中断

d.逐个调用用户在irq_desc[irq].action链表中注册的中断处理函数

e.入口函数如果是handle_level_irq要打开中断

    在Linux系统下,每个(类)中断都对应着一个irq_desc结构体,这个结构体中包含有中断的名称、标志、状态,并且包含着中断的入口函数。在irq_des结构中,还包含有一个action结构,用户注册的每一个中断处理函数都会对应着一个action,一个中断可以有多个中断处理函数,这些多个处理函数则是会链接成一个链表。

    中断的体系结构已经由内核制定好,当在驱动中需要使用中断模型时,只需要向内核注册相应中断的处理函数和触发标志等等,在卸载时注销中断即可。

用户注册中断处理函数:

int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)//根据中断号找到irq_desc数组项,,然后在action链表中添加一个表项。

//irqflags是中断的标志,在linux/interrupts.h中有宏定义

//irq_handler_t handler是用户自己定义的中断处理函数

注销中断:

void free_irq(unsigned int irq, void *dev_id)//注销中断

void disable_irq(unsigned int irq)//禁止中断

void enable_irq(unsigned int irq)//使能中断

通过以上这几个函数,则可以为驱动程序添加中断服务。