EXC_RETURN

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wowocpp/article/details/84857594

EXC_RETURN是用于程序从异常中断中返回的。

根据Cortex-M3的异常处理流程,当发生异常时,CPU先将核心寄存器压入当前堆栈(如果当前是线程模式,则压入PSP堆栈,如果当前是Handler模式,则压入MSP堆栈),然后CPU会将LR设置为一个特殊的值,比如0xFFFFFFFD,然后切换到Handler模式,切换成MSP堆栈,最后进入异常处理例程(异常处理例程总是使用MSP堆栈)。在异常处理例程完成后需要从中断返回时,就将LR的值载入到PC中(通常是BX LR指令,也可以是MOV PC,LR指令,或者POP {…, PC}等指令,只要能将LR赋给PC即可),由于LR的值是0xFFFFFFFD,CPU检测到向PC中载入的是这个特殊值时,就知道是中断返回,于是做中断返回的动作(与压入动作相反:从堆栈中弹出核心寄存器的值,恢复到线程模式或Handler模式等)。

这里这个特殊的值(0xFFFFFFFD)就是EXC_RETURN,它的特点是高28位全部是1,只有低4位可变化,不同的低4位表示不同的中断返回动作。

这个值是CPU在进入异常处理前自动设置的,只有3个值是合法的:

0xFFFFFFF1 表示中断返回时从MSP堆栈恢复寄存器值,中断返回后进入Handler模式,使用MSP堆栈,(相当于从中断返回到另一个中断)。

0xFFFFFFF9 表示中断返回时从MSP堆栈恢复寄存器值,中断返回后进入线程模式,使用MSP堆栈(这种用于不使用PSP只使用MSP堆栈的情况)。

0xFFFFFFFD 表示中断返回时从PSP堆栈恢复寄存器值,中断返回后进入线程模式,使用PSP堆栈(这是常见的,OS处理完中断后返回用户程序)。

可以看到,中断返回依赖于LR中的值,在此项目中,LR的值变成了0xFFFFFFF5,显然也是一个EXC_RETURN值,但这个值与上面3个都不同,是非法的,所以引起了INVPC错误。

进入中断时LR的值是CPU自动设置的,不会有错,为什么退出中断时LR值变成非法的了呢?只有一个原因:中断例程修改了LR的值,改错了。

原文来自:https://blog.csdn.net/_xiao/article/details/78475195 

猜你喜欢

转载自blog.csdn.net/wowocpp/article/details/84857594