一、什么是中断
对连接在其上的外设进行管理是一个操作系统所应该包含的核心任务之一。但是外设的速度跟CPU的速度显然不在一个数量级上,所以一般采取中断的方式对外设进行管理。内核在平时处理其他事务,当硬件有需要时再向内核发出请求,内核此时再对其进行处理,通过这种办法有效的提高了CPU的利用率和处理效率。中断的本质是一种特殊的电信号,由硬件发向处理器。并且中断不必与处理器时钟同步,这意味着中断可以随时产生,内核也会因为随时到来的中断而被打断。
二、中断与异常
在操作系统中,常常会遇到“异常”,异常与中断的区别在于,异常是与处理器时钟同步的,并且异常不是由硬件产生,而是处理器在编程失误时,或者在执行期间需要依靠内核进行处理时,处理器就会产生一个异常。总结为异步中断,同步异常。
三、中断处理流程
在Linux中,一般将中断切分为两部分,中断处理程序是上部分(Top Half),它一接收到中断就立即执行一个严格时限的工作,这些工作都是在所有中断都被禁止的情况下完成的。
被允许稍后完成的工作会推到下半部(Bottom Half),如果一个设备要使用中断,那么设备驱动程序就要注册一个驱动。设备驱动通过request_irq()函数注册一个中断处理程序,并激活对应的中断线。
request_irq()函数原型:
int request_irq(unsigned int irq,irq_handler_t handler,
unsigned long flag,const char *name,
void *dev)
irq :要分配的中断号
handler :指向这个中断的实际中断处理程序的指针
flag :中断处理程序标志
name :与中断相关的设备的ASCII文本
dev :用于共享中断线,如果中断线已在使用,或者没有制定共享,就会报错
注意:不能在中断上下文或者其他不允许阻塞的代码中调用request_irq(),因为在调用过程中,内核需要在/proc/irq中创建对应项,设置项时会调用proc_mkdir()函数,而这个函数又会调用proc_create()函数,proc_create()会调用kmalloc(),kmalloc()是可以睡眠的!
在卸载驱动程序时,需要注销对应的中断处理程序,并释放中断线。
通过调用 void free_irq(unsigned int irq,void *dev)
irq:中断处理程序
dev:中断线
如果在给定的中断线上没有中断处理程序,则注销响应的处理程序,并禁用该中断线。