首页 理论教育 STM系列单片机中断/异常进入步骤

STM系列单片机中断/异常进入步骤

时间:2023-11-23 理论教育 版权反馈
【摘要】:图3.38中断请求过快导致一部分请求错失的情况图3.39在执行ISR时中断悬起再次发生入栈响应异常的第一个步骤,就是自动保存现场的必要部分:依次把xPSR、PC、LR、R12以及R3~R0由硬件自动压入适当的堆栈中,如果当响应异常时,当前的代码正在使用PSP,则压入PSP,即使用线程堆栈;否则压入MSP,使用主堆栈。表3.15入栈顺序以及入栈后堆栈中的内容图3.40内部入栈序列Cortex-M3在看不见的内部打乱了入栈的顺序,这是有深层次的原因。

STM系列单片机中断/异常进入步骤

当Cortex-M3开始响应一个中断时,会经历以下几个步骤:

①入栈:把8个寄存器的值压入栈;

②取向量:从向量表中找出对应的服务程序入口地址

③选择堆栈指针MSP/PSP,更新堆栈指针SP,更新连接寄存器LR,更新程序计数器PC。

图3.38 中断请求过快导致一部分请求错失的情况

图3.39 在执行ISR时中断悬起再次发生

(1)入栈

响应异常的第一个步骤,就是自动保存现场的必要部分:依次把xPSR、PC、LR、R12以及R3~R0由硬件自动压入适当的堆栈中,如果当响应异常时,当前的代码正在使用PSP,则压入PSP,即使用线程堆栈;否则压入MSP,使用主堆栈。一旦进入了服务例程,就将一直使用主堆栈。

假设入栈开始时,SP的值为N,则在入栈后,堆栈内部的变化见表3.15。又因为AHB接口上的流水线操作本质,地址和数据都在经过一个流水线周期之后才进入。另外,这种入栈在机器的内部,并不是严格按堆栈操作顺序,但是机器会保证正确的寄存器将被保存到正确的位置,如图3.40和表3.15的第3列所示。

表3.15 入栈顺序以及入栈后堆栈中的内容

(www.xing528.com)

图3.40 内部入栈序列

Cortex-M3在看不见的内部打乱了入栈的顺序,这是有深层次的原因。先把PC与xPSR的值保存,就可以更早地启动服务例程指令的预取——因为这需要修改PC;同时,也做到了在早期就可以更新xPSR中IPSR位段的值。

为什么把R0~R3、R12由硬件自动压入适当的堆栈中,而忽略R4~R11呢?原来,在ARM中,有一套C函数调用标准约定(《C/C++Procedure Call Standard for the ARM Architecture》,AAPCS,Ref5)。该约定使中断服务例程能用C语言编写,编译器优先使用被入栈的寄存器来保存中间结果(当然,如果程序过大也可能要用到R4~R11,此时编译器负责生成代码来将它们入栈)。R0~R3、R12最后被压入堆栈,是为了可以更容易地使用SP基址来索引寻址,访问由R0~R3、R12传递的数据,以及为了LDM等多重加载指令,因为LDM必须加载地址连续的一串数据。

(2)取向量

当数据总线(系统总线)在执行入栈操作时,指令总线(I-Code总线)从向量表中找出正确的异常向量,然后在服务程序的入口处预取指。由此可以看到各自都有专用总线的好处,即入栈与取指这两个工作能同时进行。

(3)更新寄存器

在入栈和取向量的工作都完毕之后,执行服务例程之前,还要更新一系列的寄存器:

①SP:在入栈中会把堆栈指针(PSP或MSP)更新到新的位置。在执行服务例程后,将由MSP负责对堆栈的访问;

②PSR:IPSR位段(地处PSR的最低部分)会被更新为新响应的异常编号;

③PC:在向量取出完毕后,PC将指向服务例程的入口地址;

④LR:LR的用法将被重新解释,其值也被更新成一种特殊的值,称为“EXC_RETURN”,并且在异常返回时使用。EXC_RETURN的二进制值除了最低4位外全为1,而其最低4位则有另外的含义(见3.7.8节)。

以上是在响应异常时通用寄存器的变化。另外,在NVIC中,也伴随着更新了与之相关的若干寄存器。例如,新响应异常的悬起位将被清除,同时其活动位将被置位。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈