本帖最后由 小夏天的大西瓜 于 2025-2-25 12:48 编辑
02 lockup的原因
许多的情况都有可能导致Cortex-M0处理器被锁定:
● 在NMI服务中产生错误,出现两个异常错误
● 在HardFault服务中产生错误(双重faults)
● 在NMI处理或者HardFault处理时包含了SVC操作
● 在复位序列(初始的MSP与PC读取)中产生总线错误响应
● 异常返回期间,使用了主栈指针(MSP)进行xPSR出栈时,产生了总线错误
除了出现错误的情况,在NMI或者HardFault处理中使用SVC也会导致锁定,这是因为SVC优先级总是比这些异常的要低,因此会被阻止。由于程序错误不能被HardFault异常处理,所以系统进入到锁定状态。
锁定状态也可以由复位期间的总线系统错误引发。
如果在操作Flash期间,处理器产生了总线错误,这就意味着处理器无法确认栈指针的初始值或者无法确认复位向量。在这些情况下,处理器无法进行正常的操作,必须进入到锁定状态。
如果在异常处理时产生了总线错误响应,即使进入的时HardFault或者NMI,入口不会引发锁定,不过一旦进入HardFault或者NMI异常处理后,总线错误响应就会引发锁定。因此,对于高可靠性的系统,由于C编译器可能会在处理代码的开始添加栈操作,所以HardFault处理程序最好不要用C语言实现:
HardFault_Handler
push {R4,R5} ;如果MSP被破坏,该指令会引起锁死
在异常退出且使用MSP的xPSR出栈期间,总线错误响应则可能会引起锁定。在这种情况下,由于xPSR无法确定,因此处理器无法获取到系统的正确优先级。因此系统就处于了锁定状态,并且除了复位或者暂停调试外无法将系统复位。
但是在调试阶段也许还能让系统起死回生:如果连接了调试器,则可以喊停(halt)处理器,然后手工修改PC的值。然而这也往往是无力的:因为上下文没有了——所有的寄存器,以及中断系统,都已经物是人非,需要重新初始化,才能返回到正常的操作中。
如果当场就复位了,则所有寄存器的值都归位了,不再有机会去查明当时的情况。
如果不是关键系统,则可以使用一个看门狗复位,它可以使系统从锁定状态中复位。
还要注意的是,如果在响应NMI或HardFault的入栈/出栈阶段触发了总线fault,则不会导致锁定,只是会悬起总线fault。
|