中断

转自:

https://blog.csdn.net/SunnyBeiKe/article/details/6975442

https://blog.csdn.net/smallfish_love/article/details/50759192

中断,本质上是一个电信号,早期的计算的并没有中断这一概念,这使得CPU与外围设备的交互变得困难,CPU需要不断的轮询,以探测外围设备是否有数据需要处理。这浪费大量的资源。中断的出现,将CPU从这一任务中解放出来,CPU与外设的处理,变为异步,它可以喝着茶,听着音乐,然后等待外设的报告。

Linux中的中断,除了包含外围设备引发的硬中断外,还有更多宽泛的概念,如CPU引发的同步中断或异常、软中断等。不过本文如未特别注明,都是描述外围设备发出的异步中断。

事实上,外围设备并不能直接发中断给CPU。是的,老大随时来看我轮询一下,浪费他的时间与精力,我也不能想找老大就找老大,得找他的小蜜,外设借助一个称为“中断控制器”的中间组件来完成请求。这个过程叫IRQ(中断请求),中断控制器在处理完相应的电工任务后,将中断请求转发到CPU的中断输入。例如,下图展示了一个典型的x86平台的8259A中断控制器:

中断.jpg

根据中断来源分为:内部中断(来自于CPU内部,如中断指令、溢出等)和外部中断(来自于外设,如读写完成中断)

根据是都可屏蔽分成:可屏蔽中断和不屏蔽中断(NMI),可屏蔽中断通过中断屏蔽字被屏蔽,屏蔽后,该中断不再的导向响应;不屏蔽中断不能被屏蔽。

根据中断入口跳转方法的不同,分成向量中断和非向量中断

采用向量中断的CPU通常给不同的中断号分配不同的中断号,当检查到某中断号的中断到来后,就自动跳转到与该中断号对应的地址执行。不同中断号的中断有不同的入口地址。非向量中断的多个中断共享一个入口地址,进入该入口地址后再通过软件判断中断标志来识别具体是哪个中断。也就是说,向量中断由硬件提供中断服务程序的入口地址,非向量中断由软件提供中断服务程序的入口地址。

Linux中断处理程序架构

设备的中断会打断内核中进程的正常调度和运行。

Linux内核的中断机制:为了在中断执行时间尽可能段和中断处理完成大量工作之间找到一个平衡点,Linux将中断处理程序分成两个半部,顶半部(top half)和底半部(bottom half)。

中断-----→上半部(紧急的硬件操作)----调度------→下半部(延缓的耗时操作)

顶半部完成尽可能少的比较紧急的功能,往往只是简单读取寄存器的中断状态并清除中断标志后就进行“登记中断”的工作。“登记中断”意味着将底半部处理程序挂到该设备的底半部执行队列中。这样,顶半部执行的速度会很快,可以服务更多的中断请求。

所以底半部来完成中断时间的绝大多数任务(几乎是中断要做的所有事情),而且可以被新的中断的打断,这是底半部和顶半部最大的区别,因为顶半部往往设计成不可中断。底半部一般不再硬件中断服务程序中执行。但是也不能僵化的认为Linux设备的驱动程序一定就是分成两部分,要是中断要处理的工作本身很少,则完全可以直接在顶半部全部完成。

Linux中断编程

中断申请(申请IRQ)-----request_irq()

释放IRQ------free_irq()

使能和屏蔽IRQ

disable_irq()       disable_irq_nosync()     enable_irq()

底半部机制:Linux实现底半部机制主要方式有   tasklet 工作队列  软中断


猜你喜欢

转载自blog.csdn.net/lyq_csdn/article/details/80545557