内容整理自较早前的微机原理学习笔记,重点梳理了实现硬件中断机制所依赖几个数据结构和硬件原件。
为什么需要中断?中断机制的出现是为了协调处理器与外部设备速度不一致的问题,以提高处理器的利用率。
试想我们打开了文本编辑器,处理器就不干活了,等着键盘输入,这会浪费多少处理器计算资源?
另一种方式是处理器忙自己的,等有输入时再通知处理器。这种异步通知处理器就是利用的中断机制。
从工作流程上看有点类似Java语言通过try-catch捕获InterruptedException,主流程收到其他线程的打断通知后转向处理异常情况。
通常有两种模式感知外部事件的发生。一种是主动的检测,每隔一段去询问一次,即轮询,另一种是被动的,当事件发生时由对方通知自己。处理器接受中断信号采用的轮询方式。
处理器的控制单元是一个时序逻辑电路,同时也是一个有限状态机(FSM) [1],基础的FSM有三个状态FETCH、DECODE、EXECUTE,它表示处理器执行一条指令的有序序列是:从内存读取指令 -> 解释指令 -> 执行指令。
后来在计算机设计上出现了中断机制,就在原来FSM的基础上增加了一个新状态——中断,
处理器执行一条指令的流水线就变成了从内存读取指令 -> 解释指令 -> 执行指令 -> 检测中断。
由此可见,检测中断事件发生在每一次CPU指令周期中
在物理实现中,CPU上有两个引脚NMI和INTR [2],专门用于接收外部设备的中断信号。不过由于CPU的引脚数量有限,给每个外设预留一个引脚是不现实的。
所以在外设和处理器中间还有一个硬件,叫做可编程中断控制器(Programmable Interrupt Controller,PIC),外设通过电路向PIC发送一个中断信号,然后PIC再发送给处理器。PIC是可编程的,意味着可以调整每个引脚对应的外部设备,以及当同时发生多个中断时,设置中断的优先级。
中断只是一个电信号,不能传递更多的数据,那么处理器要如何知道怎么处理一个中断请求(interrupt request,IRQ)?
处理逻辑放在中断处理程序(interrupt service routine, ISR)中,该程序是硬件驱动的一部分。我们在安装键盘驱动、鼠标驱动时也向操作系统注册了ISR。
虽然中断类型有很多,处理器倒也不用预先记录每个ISR在什么位置。操作系统在启动时会创建一个中断向量表(interrupt vector table,IVT),这个数据结构是中断ID到ISR入口地址的映射,存放在一个操作系统和处理器都知道的固定内存位置。根据约定,在内存地址空间中,最低的1K空间,即00000H到003FFH为中断向量表。当中断发生时,处理器根据中断ID获取到ISR程序的入口地址,开始执行中断处理程序。
Arduino Interrupts Tutorial:https://www.youtube.com/watch?v=QtyOiTw0oQc
视频中作者用Arduino单片机演示了硬件实现中断的细节,很值得一看,会让你对硬件中断有个直观的认识。
可编程的中断控制器:https://en.wikipedia.org/wiki/Programmable_interrupt_controller
中断控制器的几号引脚对应哪个外部设备是可以编辑的,所以是可编程的。
以及同时发生多个中断请求时,也由中断处理器确定优先级。
《计算机系统》Computer Systems:An Integrated Approach to Architecture and Operating Systems
本文的内容主要来自这本书的第四章和第六章。这是一本很棒的微机原理教材。
中断处理程序词条:https://en.wikipedia.org/wiki/Interrupt_handler
CPU怎么检测到中断的?https://segmentfault.com/q/1010000009330782
这个讨论里有提到中断引脚以及中断控制器
轻量级线程词条:https://en.wikipedia.org/wiki/Light-weight_process
里面有讲到调度器激活
Oracle Solaris编写驱动程序文档:https://docs.oracle.com/cd/E38902_01/html/E38873/interrupt-1.html
这是写给编写Solaris操作系统驱动程序的开发人员的说明文档,文中比较详细的解释了怎么编写中断处理程序。
简单阅读一下,可以增加对中断处理程序的直观认识。
如果同时发生两个中断CPU怎么处理?
《计算机组成与体系结构》Computer Organization and Architecture: Designing for Performance
第七章有详细讲解中断处理器的细节
中断词条:https://zh.wikipedia.org/wiki/中斷