中断
中断(Interrupt)机制,即处理器在顺序执行程序指令流的过程中突然被别的请求打断而中止执行当前的程序,转而去处理别的事情,待其处理完了别的事情,然后重新回到之前程序中断的点继续执行之前的程序指令流,其要点如下
中断请求、中断源
打断处理器执行程序指令流的的“别的请求”便称之为中断请求(Interrupt Request),“别的请求”的来源便称之为中断源(Interrupt Source),中断源通常来自于外围设备。
中断服务程序
处理器转而去处理的“别的事情”便称之为中断服务程序(Interrupt Service Routine ISR)。
保存现场、恢复现场
中断处理是一种正常的机制,而非一种错误情形。处理器收到中断请求之后,需要保存当前程序的现场,简称为保存现场。等到处理完中断服务程序后,处理器需要恢复之前的现场,从而继续执行之前被打断的程序,简称为恢复现场。
中断仲裁、中断优先级
可能存在多个中断源同时向处理器发起请求的情形,因此需要对这些中断源进行仲裁,从而选择哪个中断源被优先处理,这种情况称为中断仲裁,可以给不同的中断分配优先级以便于仲裁,因此中断存在中断优先级的概念。
中断嵌套
如果处理器在处理某个中断过程中(执行该中断的 ISR之中),此时有一个优先级更高的新中断请求到来,此时处理器如何处理分两种情况
- 第一种可能是处理器并不响应新的中断,而是继续执行当前正在处理的中断服务程序,待到彻底完成之后才响应新的中断请求,这种称为处理器不支持中断嵌套
- 第二种可能是处理器中止当前的中断服务程序,转而开始响应新的中断,并执行新的中断的中断服务程序,如此便形成了中断嵌套(即前一个中断还没响应完,又开始响应新的中断),并且嵌套的层次可以有很多层。
Note:
- 需要注意的是,假设新来的中断请求的优先级比正在处理的中断的优先级低(或者相同),则不管处理器是否支持中断嵌套,都不应该响应这个新的中断请求,处理器必须完成当前的中断服务程序之后才考虑响应新的中断请求(因为新中断请求的优先级并不比当前正在处理的中断优先级高)。
中断咬尾
处理器内核正在处理某个中断的过程中,可能有新中断请求到来,但是 新中断的级别
低于或者等于 当前正在处理的中断级别
,因此,新中断不能够打断当前正在处理的中断(因此不会形成嵌套)。
当处理器完成当前中断之后,理论上需要恢复上下文,然后退出中断回到主应用程序,然后重新响应新的中断,响应新的中断又需要再次保存上下文。因此,存在着一次背靠背的恢复上下文
和保存上下文
操作,如果将此背靠背的恢复上下文
和保存上下文
省略掉,则称之为中断咬尾
,
如下图所示,显而易见,中断咬尾可以加快多个中断的背靠背处理速度。
中断的向量处理模式和非向量处理模式
非向量处理模式
非向量处理模式,该中断被处理器内核响应后,处理器会直接跳入到所有非向量中断共享的入口地址,Cortex-A 系列中断通常为非向量处理模式
。
在非向量处理模式,该中断被处理器内核响应后,处理器会直接跳入到所有非向量中断共享的入口地址。
例如 GIC 中的, IRQ_Handler
,所有的 GIC 中断都有同一个入口地址,在 IRQ_Handler
中再进行软件分发。
对于非向量处理模式的中断而言,由于在跳入和退出中断服务程序之前,处理器要进行上下文的保存和恢复,因此进行中断咬尾
能够节省显著的时间(节省一次背靠背的保存上下文和恢复上下文)。
向量处理模式
向量处理模式,该中断被处理器内核响应后,处理器会直接跳入该中断的向量入口(Vector Table Entry)存储的目标地址,即该中断源的中断服务程序(Interrupt Service Routine,ISR)
Cortex-M
系列通常为向量处理模式,每一个中断都有自己的中断入口
异常
异常(Exception)机制,即处理器在顺序执行程序指令流的过程中突然遇到了异常的事情而中止执行当前的程序,转而去处理异常,其要点如下
- 处理器遇到的“异常的事情”称为异常(Exception)。异常与中断最大的区别在于中断往往是一种外因,而异常是由处理器内部事件或程序执行中的事件引起的,比如本身硬件故障,程序故障、非法指令,或者执行特殊的系统服务指令而引起的,简而言之是一种内因
- 与中断服务程序类似,处理器也会进入异常服务处理程序。
- 与中断类似,可能存在多个异常同时发生的情形,因此异常也有优先级,并且也可以发生多重异常的嵌套。
广义上的异常
如上一节所述,中断和异常最大的区别是起因内外有别。除此之外,从本质上讲,中断和异常对于处理器而言基本上是一个概念。
中断和异常发生时,处理器将暂停当前正在执行的程序,转而执行中断和异常处理程序;返回时,处理器恢复之前被暂停的程序。
因此中断和异常的划分是一种狭义上的划分。从广义上讲,中断和异常都被认为是一种广义上的异常。处理器广义上的异常,通常只分为同步异常(Synchronous Exception)和异步异常(Asynchronous Exception)。有些处理器将广义上的异常也叫做 Trap。
同步异常
同步异常是指由于执行程序指令流或者试图执行程序指令流而造成的异常。这种异常的原因能够被精确定位于某一条执行的指令。
同步异常另一个通俗的表现便是,无论程序程序在同样的环境下执行多少遍,每一次都能精确的复现出来。
例如,程序流中有一条非法的指令,那么处理器执行到该非法指令便会产生非法指令异常(Illegal Instruction Exception),能被精确地定位于这一条非法指令,并且能够被反复复现。
异步异常
异步异常是指那些产生原因不能够被精确定位于某条指令的异常。
异步异常另一个通俗的表现便是,程序在同样的环境下执行很多遍,每次发生异常的指令 PC 都可能会不一样。
最常见的异步异常是外部中断,外部中断的发生是由外围设备驱动的,一方面外部中断的发生带有偶然性,另一方面中断请求到达处理器之时,处理器的程序指令流执行到具体的哪一条指令带有偶然性。因此一次中断的到来可能会巧遇到某一条“正在执行的不幸指令”,而该指令便成了“背锅侠”。在它的指令 PC 所在之处,程序便停止执行,并转而响应中断去执行中断服务程序。但是当程序重复执行时,却很难会出现同一条指令反复“背锅”的精确情形。
对于异步异常,根据其响应异常后的处理器状态,又可以分为两种:
精确异步异常(Precise Asynchronous Exception)
指响应异常后的处理器状态能够精确反映为某一条指令的边界,即某一条指令执行完之后的处理器状态。外部中断是最常见的精确异步异常。
非精确异步异常(Imprecise Asynchronous Exception)
指响应异常后的处理器状态无法精确反映为某一条指令的边界,即可能是某一条指令执行了一半然后被打断的结果,或者是其他模糊的状态。读写存储器出错是一种常见的非精确异步异常,例如,写数据到 cache,然后该 cache 很久之后才被替换出来,写回外部存储器,但是写回外部存储器返回结果出错。此时处理器可能已经执行过了后续成百上千条指令,到底是哪一条指令当时写的这个地址的 cache ,不可能被精确定位。
异常处理流程
本文主要参考《手把手教你设计 CPU——RISC-V处理器》文章来源:https://www.toymoban.com/news/detail-517132.html
参考链接
https://www.rvmcu.com/quickstart-show-id-1.html#24
https://www.rvmcu.com/quickstart-show-id-9.html文章来源地址https://www.toymoban.com/news/detail-517132.html
到了这里,关于【ARM】-异常与中断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!