HardFault分析
分析
根据cortex m3/m4权威指南,arm提供了几个寄存器用于判断进入HardFault是由什么原因引起的:
1. HardFault Status Register(0xE000ED2C)
如果BIT30被置位,说明HardFault的产生来自bus fault,memory management fault或者usage fault,具体原因还需要查看下面这个寄存器
2. Configurable Fault Status Register(0xE000ED28)
此寄存器的四个字节根据不同的fault原因分为下面三个部分:
- MemMange Fault
- Bus Fault
- Usage Fault
在进入HardFault以后,通过对上方两个寄存器的分析,可以大致判断进入HardFault的原因。
3.栈帧
除了知道进入HardFault的原因,还能分析出程序是运行到哪个地址进入的HardFault,这就需要了解栈帧的知识,具体原理可以看本文,接下来直接说步骤:
1.进入HardFault后,读取LR的值,此时获得EXC_RETURN的内容,通过BIT2确认栈帧是保存在MSP里还是PSP里,并能得到下列内容(地址从低到高):
R0 | R1 | R2 | R3 |
---|---|---|---|
R12 | LR | PC | xPSR |
其中PC位置的内容就是进入HardFault前一刻的程序地址
举例
- 对于arm-gdb,可以通过上面的原理自己写个gdb脚本打印fault信息,这里提供一个demo。
- 对于keil,可以看窗口中Fault Report里提示的信息,并根据SP寄存器的内容定位栈帧里的数据。