资源描述:
《LINUX 操作系统 第6章 中断和中断处理程序.ppt》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、第6章中断和中断处理程序6.1中断、陷阱和异常中断(interrupt):设备发出的中断,此类中断的发生是无法预测的,它是被动的。用户空间和系统空间都可能发生中断。陷阱(trap):由软件产生的中断,它是由专设的指令,如X86的“intn”在程序中有意设置的,他是主动的。陷阱只发生在用户空间。异常(exception):由于违规操作产生的,如除法操作DIV的除数为0。多半是不小心,而不是故意的,也是被动的。系统调用,通过int0x80实现,同“陷阱”。2中断、陷阱和异常共同点:CPU对它们的响应过程基本一致。即:在执行完当前指令后,或者在执行当前指令的中途
2、,就根据中断源所提供的“中断向量”,在内存中找到相应的服务程序的入口地址,并调用该服务程序。“中断”的向量是由软件或硬件设置好了的;陷阱的向量是在“自陷”指令中发出的(intn中的n);而各种异常的向量则是CPU的硬件结构中预先规定好的。因此,在实践中常常将它们作为统一的模式加以考虑和实现,而且常常统称为“中断”。3中断中断使硬件得以与处理器进行通信。中断随时可能发生,因此内核随时可能因为新到来的中断而被打断。不同的设备对应的中断不同,每个中断都通过一个唯一的数字标识,从而使得操作系统能够对中断进行区分。这些中断值通常被称为中断请求(IRQ)线,通常IR
3、Q都是一些数值量。46.2中断处理程序在响应一个特定中断的时候,内核会执行一个函数——中断处理程序(或叫中断服务例程)。一个设备的中断处理程序是它的设备驱动程序的一部分。中断处理程序与其他内核函数的真正区别:中断处理程序是被内核调用来响应中断的,它们运行于中断上下文中。5中断随时可能发生,因此中断处理程序也就随时可能执行。所以必须保证中断处理程序能够快速执行,这样才能保证尽可能快地恢复中断代码的执行。因此,尽管对硬件而言,迅速对其中断进行服务非常重要;但对系统的其它部分而言,让中断处理程序在尽可能短的时间内完成运行也同样重要。6上半部与下半部对中断处理程序
4、而言,既想它运行得快,又想它完成的工作量多,鉴于这两个目的之间的矛盾,一般把中断处理分为两个部分:上半部:中断处理程序,接收到一个中断,它就立即开始执行,但只做有严格时限的工作。这些工作都是在所有中断被禁止的情况下完成的。下半部:能够被允许稍后执行的工作推迟到下半部执行。下半部在开中断的情况下执行。7上半部和下半部分开的例子例:网卡接收数据包应在上半部完成的工作:应答硬件,拷贝最新的网络数据包到内存,读取网卡上更多的数据包。可以在下半部完成的工作:处理和操作数据包。86.3注册中断处理程序中断处理程序是驱动程序的组成部分。驱动程序通过以下函数注册并激活一个
5、中断处理程序。intrequest_irq(unsignedintirq,irqreturn_t(*handler)(int,void*,structpt_regs*),unsignedlongirqflags,constchar*devname,void*dev_id)9request_irq()的参数第1个参数irq:要分配的中断号。第2个参数handler:一个指针,指向处理这个中断的实际中断处理程序。第3个参数irqflags:可以为0,也可以是SA_INTERRUPT,SA_SAMPLE_RANDOM,SA_SHIRQ其中的一个或多个标志的位掩码
6、。第4个参数devname:与中断相关的设备的ASCII文本表示法。第5个参数dev_id:主要用于共享中断线。10request_irq()的返回值若成功执行,返回0;如果返回非0值,表示有错误发生,在这种情况下,指定的中断处理程序不会被注册。注意:request_irq()函数可能会睡眠,因此,不能在中断上下文或其它不允许阻塞的代码中调用该函数。11使用request_irq()函数if(request_irq(irqn,my_interrupt,SA_SHIRQ,“my_device”,dev)){printk(KERN_ERR“my_device
7、:cannotregisterIRQ%d,”,irqn);return–EIO;}12释放中断处理程序卸载驱动程序时,需要注销相应的中断处理程序,并释放中断线。可以调用voidfree_irq(unsignedintirq,void*dev_id)来释放中断线。如果指定的中断线不是共享的,那么,该函数删除处理程序的同时将禁用这条中断线。如果中断线是共享的,则仅删除dev_id所对应的处理程序,而这条中断线本身只有在删除了最后一个处理程序时才会被禁用。136.4编写中断处理程序典型的中断处理程序声明:staticirqreturn_tintr_hand
8、ler(intirq,void*dev_id,structpt_r