mcu hardfault
一、定位思路:
找到哪一行指令引起了hardfault,即找到hardfault前最后一条指令的pc值。(当前pc值已经在hardfault处理函数中了,肯定不是想要找的位置~)。根据arm架构的知识(
),硬件会自动帮我们把这个返回值压入栈中,因此,需要先找到栈,进而找到“返回地址”,进而通过汇编代码找到对应位置。
二、详细过程:
1、根据lr寄存器的值确认使用的哪个栈(msp or psp)
由于发生中断后,lr会被更新成一种特殊的值,称为“EXC_RETURN”,并且在异常返回时使用。EXC_RETURN的二进制值这是一个高28位全为1的值,只有[3:0]的值有特殊含义
根据bit2,可以确认使用的是msp,还是psp
2、根据当前栈,找到“返回地址”
注意:armv7架构下,这里的返回地址并不一定是发生错误时候的pc值。
同步异常:返回地址并一定是发生错误时候的pc值
异步异常:返回地址是发生错误时候的下一条指令地址。thumb指令集下就是pc+2
3、查找出错位置对应的源码
反汇编
使用gnu工具,例如addr_to_line
小结:
三、辅助工具:
上述过程中,问题的关键是找到栈帧。如果实时调试,可以通过ide直观地看到寄存器,也可以dump相关栈的内存。如果是离线模式下,就需要在hardfault服务函数中,把这些关键寄存器的值以及栈的内容dump出来,才可以进一步分析。可以参考部分开源的实现。
四、可能引起hardfault的原因:
如何抓取到mcu的死机现场 - 小华半导体官方技术支持论坛
ref:
https://www.segger.com/downloads/application-notes/AN00016
https://www.keil.com/appnotes/files/apnt209.pdf
第6期BSP驱动教程:MDK专题进阶,Cortex-M内核芯片Hardfault硬件异常调试分析定位_哔哩哔哩_bilibili
How to debug a HardFault on an ARM Cortex-M MCU | Interrupt
Cortex-M 处理器 hardfault 定位方法和步骤(基于Keil mdk) - 薛定谔我的猫 - 博客园
嵌入式开发笔记——调试组件SEGGER_HardFaultHandle - 树·哥 - 博客园
Ending the Embedded Software Dark Ages: Let’s Start With Processor Fault Debugging! - Embedded Artistry Cortex-M系列HardFault_Handler()最强分析“CmBacktrace”-CSDN博客
https://s-o-c.org/cortex-m0-stack-frames-and-registers-during-hardfault/