中断和中断处理
一些简单基础的概念就不过多介绍了,着重说一些比较新的和重要的东西
上半部与下半部
我们对中断处理程序有两个要求:一是运行速度快,而是完成的任务量多。鉴于两者此消彼长的关系,我们将中断处理分为两部分
上半部:接受一个中断,就立即执行,但只做有严格时限的工作,例如对中断进行应答或复位硬件,这些工作都是在所有中断被禁止的情况下完成的。在本章,我们主要讨论上半部的工作
下半部:能够允许稍后完成的工作都会推迟到下半部去。在下章,我们主要讨论下半部的工作。
注册中断处理程序
第一个参数是中断号,第二个是指向中断处理程序的指针。
中断处理程序的标志:第三个参数是flag。第四个参数是与中断相关的设备的ASCII文本。第五个参数用于共享中断线。卸载驱动程序时,需要注销相应的中断处理程序。
编写中断处理程序
中断处理程序的类型与request_irq中handler所要求的参数类型匹配,dev也与其匹配,此外dev还可能是指向中断处理程序的一个数据结构。
值得注意的是,Linux中的中断都是无需重入的,当一个中断处理程序正在执行时,相应的中断线在所有的处理器上都会被屏蔽,这意味着在同一中断线上不会接受其他中断,同时,同一个中断处理程序绝不会被同时调用以处理嵌套中断。
共享的中断处理程序:共享的中断处理程序与非共享的处理程序的差异主要有:(1)flags标志必须设置为IRQF_SHARED标志(2)dev必须唯一并且不能使NULL(3)中断处理程序必须区分他的设备发生了中断还是共享线的其他设备发出的中断。
中断上下文
当执行一个中断处理程序时,内核处于中断上下文。中断上下文不可以被睡眠,不能从中断上下文中调用某些函数。重要的一点是中断上下文必须要尽可能迅速简洁的完成工作。
中断处理器的实现
中断处理系统在Linux中的实现非常依赖体系结构。上图中,硬件产生一个中断的电信号,中断电信号先经过中断控制器,如果是未被屏蔽的,则继续发往处理器,如果处理器未禁止该中断,则处理器会立刻停止正在做的事,关闭中断系统,通过do_IRQ()到内存中指定位置开始执行代码。
中断控制
Linux中提供了一系列接口来控制中断状态:或禁止当前处理器的中断系统,或屏蔽掉整个机器一条中断线。这样做的原因往往是需要提供同步,确保某个中断处理程序不会抢占当前代码。此外,还可以获取某种锁来防止来自其他处理器的并发访问。
禁止和激活中断:用于禁止当前处理器上的本地中断,随后又激活的语句:
但是操蛋的是如果之前已经禁止中断,我们将不能再次禁止,或者无条件的激活中断。所以:
禁止指定中断线:
前两者禁止中断线,第一个等待处理程序运行完毕,而第二个不等待,第四个等待一个特定的中断处理程序的退出,第三个函数对前两个函数禁止的中断线进行激活,是可嵌套的,如果前两个函数调用了两次,那么第三个函数也必须在同一中断线上调用两次才能激活这个中断线。
中断系统的状态:Linux提供了几个借口来检查中断系统的状态: