我正试图在我的代码中检索IRQ处理程序的返回地址。 我的目标是使用WDT_IRQHandler(),在看门狗定时器到期之前以及用于调试目的的复位之前保存PC的值。我也正在用其他IRQ测试这种方法,以检查我是否掌握了这个想法。 但似乎我没有。检索ARM Cortex M0上的异常的返回地址
我已阅读documentation可用。 我明白,当发生异常时,8个寄存器被推送到堆栈: R0,R1,R2,R3,R12,LR,PC和XPSR。
我也读过堆栈自动双字对齐。所以在我看来,检索返回地址就像:
- 使用__builtin_frame_address(0)检索sp地址;
- 增加了堆栈PC(0x18)的偏移量,并读取值,这应该是处理程序返回时将恢复到PC的值。
使用附加的调试器进行检查,情况似乎并非如此,该内存地址的内容并不总是指向闪存区域,甚至不指向有效区域,并且在任何情况下它都不是该值PC将在POP指令之后承担。
该代码工作正常,所以我认为这是我了解它如何工作的问题。
如果我检查拆卸,在一些的IRQ常数弹出(?)之前加入到SP
00001924: 0x000009b0 ...TE_IRQHandler+280 add sp, #36 ; 0x24
00001926: 0x0000f0bd ...TE_IRQHandler+282 pop {r4, r5, r6, r7, pc}
在其他的IRQ不会发生这种情况。
据我所知,可能会发生更多寄存器被推入堆栈,所以我如何确定在哪个偏移量来检索PC?
如果我在代码仍然在IRQ处理程序中时检查SP周围的内存转储,我可以发现返回地址,但它总是位于一个奇怪的位置,与SP相比具有负偏移量。我无法理解如何获得正确的地址。
谢谢。对于点1)我想我可以使用__get_MSP()和__get_PSP()从C中检查MSP和PSP。对于2)我知道推后代码可以将本地变量添加到堆栈,并且这些在编译时已知,所以我不能依赖于固定的偏移量。 我会尝试你的方法。 – Vitomakes
@Vitomakes从C中检查'MSP'和'PSP'并不能告诉你哪一个是正确的。当然,如果你只使用'MSP'(非常常见),那么你可以跳过检查。 –
cortex M0不支持“ITE”和“MRSEQ/MRSNE”,并且编译器抱怨处于拇指模式并且无法使用TST。但我明白了,我会把它整理出来 – Vitomakes