程序运行过程中,系统外部、系统内部或者现行程序本身若出现紧急事件(定时器、设备IO、…),处理机立即中止现行程序的运行,自动转入相应的处理程序(中断服务程序),待处理完后,再返回原来的程序运行,这整个过程称为程序中断。
中断通常被定义为一个事件,该事件能够改变处理器执行指令的顺序。
这样的事件与 CPU 芯片内外部硬件电路产生的电信号相对应,使CPU和硬件设备进行通信。
提高计算机系统效率(并发性):计算机系统中处理机的工作速度远高于外围设备的工作速度。通过中断可以协调它们之间的工作。当外围设备需要与处理机交换信息时,由外围设备向处理机发出中断请求,处理机及时响应并作相应处理。不交换信息时,处理机和外围设备处于各自独立的并行工作状态。
维持系统可靠正常工作:现代计算机中,程序员不能直接干预和操纵机器,必须通过中断系统向操作系统发出请求,由操作系统来实现人为干预。主存储器中往往有多道程序和各自的存储空间。在程序运行过程中,如出现越界访问,有可能引起程序混乱或相互破坏信息。为避免这类事件的发生,由存储管理部件进行监测,一旦发生越界访问,向处理机发出中断请求,处理机立即采取保护措施。
满足实时处理要求:在实时系统中,各种监测和控制装置随机地向处理机发出中断请求,处理机随时响应并进行处理。
提供故障现场处理手段:处理机中设有各种故障检测和错误诊断的部件,一旦发现故障或错误,立即发出中断请求,进行故障现场记录和隔离,为进一步处理提供必要的依据。
中断使得计算机系统具备应对对处理突发事件的能力,提高了CPU的工作效率,如果没有中断系统,CPU就只能按照原来的程序编写的先后顺序,对各个外设进行查询和处理,即轮询工作方式,轮询方法貌似公平,但实际工作效率却很低,却不能及时响应紧急事件。
中断:
1、适用于处理对响应要求非常高的事件
2、适用于处理持续时间非常短的事件
3、适用于低功耗的应用
4、程序设计较复杂
轮询:
1、适用于处理对事件响应要求低的场合
2、程序设计简单
中断处理是由内核执行的最敏感的任务之一,因为它必须满足下列约束:
出于1)和3)的约束,中断的设计一般将中断处理程序分为两部分执行(即上半部和下半部函数)。上半部为中断被禁止的临界区,执行关键而紧急的任务,如把接收到的帧拷贝到输入队列,以便下半部函数执行时能进行处理。
不同的设备对应的中断不同,每一个中断都通过一个唯一的数字标识。这些数字表示的中断值被称为中断请求(IRQ, Interrupt Request)线,也可称为IRL(Interrupt Request Lines)。
在响应一个特定中断时,内核会执行一个函数,这个函数叫做中断处理程序(Interrupt Handler),也可称为中断服务程序(Interrupt Service Routine, ISR)。
中断源的识别标志,可用来形成相应的中断服务程序的入口地址或存放中断服务程序的首地址称为中断向量。
中断向量表(interrupt vector table, IVT)就是中断向量的列表,在内存中保存(1K),其中存放着 256个中断源所对应的中断处理程序的入口地址。
中断优先级可以是固定的或编程指定的,
在某一时刻有几个中断源同时发出中断请求时,处理器只响应其中优先权最高的中断源。
当处理机正在运行某个中断服务程序期间出现另一个中断源的请求时,如果后者的优先权低于前者,处理机不予理睬,反之,处理机立即响应后者,进入所谓的“嵌套中断”。
中断嵌套是指中断系统正在执行一个中断服务时,有另一个优先级更高的中断提出中断请求,这时会暂时终止当前正在执行的级别较低的中断源的服务程序,去处理级别更高的中断源,待处理完毕,再返回到被中断了的中断服务程序继续执行的过程。
上述过程中前四项操作是由硬件完成的,后两项是由软件完成的。
从 中断实现的角度 看,分为硬中断和软中断。
实现:CPU 在每个指令周期的最后,会留一个 CPU 周期去查看是否有中断信号,若有,则把中断号取出、去中断向量表中寻找中断处理程序、跳过去执行。
触发:外部硬件直接给CPU引脚发送中断号信息,从而引起中断。
实现:OS有一个单独的守护进程,不断轮询内存中的一组标志位(如BitMap),如果哪个标志位有值了,那去这个标志位对应的软中断向量表数组的相应位置,找到软中断处理函数,然后跳过去执行。
触发:其他软件通过设置这些标记位触发中断。
这些硬中断方式都可以打断程序或任务的执行,它们的触发都是为了给CPU一个中断信号,且CPU收到信号后的后续处理流程一样——即暂停执行当前程序或任务、根据中断号去中断表中找到对应的中断处理程序并执行、执行完后返回继续执行原程序或任务。
硬中断可进一步分类:
Fault(故障):可恢复的错误。发生此中断时,CPU 将机器状态恢复到异常之前的状态,之后调用中断处理程序,结束后返回。常见的如缺页异常。
Trap(陷阱):有意的异常。通常是调试程序中用 int3 指令主动触发。
Abort(终止):不可恢复的异常。直接将此程序从进程表中去掉。
从 中断触发的角度 看,分为硬件中断和软件中断。
硬件中断(Hardware Interrupt): 通过硬件触发的中断
软件中断(Software Interrupt): 通过软件触发的中断
为了提高系统的实时性和并发性,Linux内核将中断处理程序分为上半部(top half)和下半部(bottom half)。
上半部:
就是中断处理函数,处理一些寄存器操作、时间敏感任务,以及“登记中断”通知内核及时处理下半部的任务,确保中断处理函数快进快出。
下半部:
如果中断处理过程比较耗时,则下半部负责处理中断任务中的大部分工作,如一个总线通信系统中数据处理部分。
比如,上半部将数据 copy 到内存中,下半部就执行对数据的处理。
Linux中断上下部分区别:
1)上半部由外设中断触发,下半部由上半部触发。
2)上半部不会被其他中断打断,下半部是可以被打断的。
3)上半部分处理任务要快,主要任务、耗时任务放在下半部。
中断上下部分的设计原则:
1)与硬件相关的操作,如操作寄存器,必须放在上半部。
2)对时间敏感、要求实时性的任务放在上半部。
3)该任务不能被其他中断或者进程打断的放在上半部。
4)实时性要求不高的任务、耗时任务放在下半部。
参考资料:
深入理解系统中断(INTERUPT)
中断_百度百科
STM32 中断
Linux中断的上半部和下半部