R14 or LR(Link Register)
HardFault调试的思路
- 先在出错误的地方打断点,让程序的状态固定下来;
- 由于
HardFault
属于异常,所以出现HardFault
后,LR
的值一定是0xFFFFFFFx
,这样就可以根据其值,判断程序进入这个异常之前的状态了; - 根据
LR
的ReturnStack
值,可以知道在进入异常前,程序使用的是PSP
还是MSP
; - 在确定了进入异常之前使用的
SP
后,就可以根据这个SP
的值找到现在的栈顶; - 为什么要找到栈顶呢?因为在进入异常或中断前,
MCU
会将LR
中的返回地址入栈,所以找到栈顶,就能找到这个返回地址了; - 在
MDK
中,通过在View -> Memory Windows -> Memory 1
中搜索相应SP
的值就可以查看栈顶的数据了; - 然后再栈顶地址附近找到一个
0x08xxxxxx
的值,这个值就是进入异常前代码的地址; - 在
MDK
中,可以通过View -> Disassembly Window
,然后右击,选择Show Disassembly at address...
,然后输入上面找到的地址回车就可以跳转到相应的代码处了。
注意
- 只有在程序进入
中断
或者异常
后,LR的值才会变成0xFFFFFFFx
,否则保存的还是返回地址; - 如果没有进入
中断
或者异常
,可以直接根据LR
的值在Show Disassembly at address...
窗口搜索,定位到调用这个函数的代码;
参考
STM32硬件错误调试
How to read the link register (LR) for an ARM Cortex M series device
Cortex-M3 & M4 权威指南