解决STM32 HardFault
- Cortex-M3/M4/M7 Fault Exceptions
- 问题的产生
- 理论背景
- 锁定问题的位置
Cortex-M3/M4/M7 Fault Exceptions 问题的产生 无论是在什么平台,什么环境下写代码,都免不了利用一些工具去调试Bug。诸如在Windows下利用vs开发,会使用IDE集成的调试器,或者在linux下进行C开发,使用gdb打印段错误的栈信息。而使用Keil进行嵌入式编程的时候,我们也会遇到很多诸如‘段错误’的情况,这个时候我们就需要利用环境的工具去了解发生了什么样的问题,然后定位问题发生的位置,并解决问题。
理论背景 大部分嵌入式设备使用的STM32芯片采用的都是Cortex-M3核,架构采用错误异常的机制来检测问题,当核心检测到一个错误时,异常中断会被触发,并且核心会跳转到相应的异常终端处理函数执行,错误异常的终端分为以下四种:
- HardFault
- MemManage
- BusFault
- UsageFault
>void HardFault_Handler(void)
>{
>/* Go to infinite loop when Hard Fault exception occurs */
>while (1)
{
}
>}
【IDE|STM32 HardFault 调试定位】这个时候我们按照正常的调试步骤,去菜单栏View中找到Call Stack Window,打算看看自己bug的位置的时候,却赫然发现Call Stack中只有HardFault_Handler一个函数的栈信息。从View中打开Registers Window,可以看到LR的值为0xFFFFFFF9,显然这是一个非法的值,IDE无法通过这个地址还原到上一级的代码段,所以显示的只有当前函数的信息,因为Cortex-M3的堆栈寄存器是banked,所以观察LR的Bit[2]位,其为0,所以当前的堆栈指针用的是MSP,点开View中的Memory Windows,将MSP的地址输入Address文本框,根据下图中找到在异常之前压入栈的信息:
文章图片
找到LR,在汇编的视图右键打开Show Disassembly at Address,输入从堆栈中找到了LR寄存器内的地址信息,往上退一个指令,或者就是这个指令导致了程序进入了异常。
推荐阅读
- 2 万字带你了解 Selenium 全攻略
- 开源工具将 Markdown 转为脑图,还支持 VSCode 和 Vim
- 知名开源项目 Faker.js 被清空项目仓库代码
- JDK|jdk与jre的区别
- Android从入门到精通|Android零基础入门第12节(熟悉Android Studio界面,开始装逼卖萌)
- VsCode打不开终端
- vscode插件快餐教程(5) - 代码补全
- wemos|VSCode+PlatformIo IDE实现Wemos D1 Mini(ESP8266)接入阿里云物联网平台
- 10 款 Linux 环境下的开源替代工具