当前位置:网站首页>Keil环境下STM32定位hardfault位置方法和遇到的情况
Keil环境下STM32定位hardfault位置方法和遇到的情况
2022-07-17 20:46:00 【何事误红尘】
目录
一、概述
调试过程中难免会遇到各种异常,hardfault算是比较常见的一种。在最开始学习的时候,一度很害怕这种情况,不知道怎么定位,摸不清是哪里导致了问题,全靠猜测。网上有很多定位hardfault问题的教程,基本大差不差,方法就那些。
最近有点时间,我也整理下。本章主要记录下我实践过的hardfault定位办法。后续遇到hardfault相关问题,也一并补充到本文中,方便自己查阅。
主要参考的文档为《CM3权威指南CnR2.pdf》。
二、方法一:Call Stack + Locals
这种方法我认为是最简单的,只需要分两步:
- 进入仿真后全速运行,进入hardfault后,在Call Stack + Locals窗口,找到HardFault Handler,右键选择Show Caller Code:

- 程序会自动跳转到出问题的代码,重点分析上下文即可。

三、方法二:Show Code at Address
这是搜索到的教程里,描述最多的方法。就是通过SP指针找到PC指针,然后去跳转,也只需要三步即可:
- 同样是仿真进入hardfault异常,此时重点关注寄存器部分。将SP指针放到memory窗口中,因为寄存器是32位,调整成long型显示看起来更方便,截图时忘记调了。依次是R0~R3、R12、LR、PC、XPRS 寄存器的值,对比Keil左侧寄存器的值,也可以看出来STM32是小端模式。所以找到第六个,即PC寄存器的值:

- 拿到了PC寄存器的值,在Disassembly窗口,右键选择Show Disassembly at Address:

- 在弹出的框中输入PC寄存器的值,然后Go To,程序就会跳转到出现异常的位置。其实应该输入PC值-1(忘记哪里看到过了,找到了再补充原因):

3.1 需要通过LR判断SP?
搜到的大部分教程,并不直接使用SP寄存器的值。都是先通过R14(LR)的值,判断将MSP(R14(LR) = 0xFFFFFFE9)或PSP(R14(LR) = 0xFFFFFFFD)的值作为SP值来使用。但是在权威指南中:
而且既然可以通过LR来判断,说明寄存器已经更新完成了,直接使用SP指针不就可以了吗?(这里就暂时存疑吧,我先这样去理解了)
3.1.1 关于MSP和PSP
MSP和PSP都是堆栈指针:
那么如何控制使用MSP还是PSP呢?再看:
这里的CONTROL[1]是指CONTROL寄存器,在Keil仿真时左侧的寄存器里也能够找到它:
CONTROL寄存器选择使用MSP/PSP,发生异常时,通过R14(LR)判断异常前使用的MSP还是PSP。
3.1.2 为什么LR可以去判断
在《权威指南》中给出如下解释:

从这里可以看出,网上教程里根据0xFFFFFFE9和0xFFFFFFFD判断使用MSP还是PSP的依据。实际上是根据bit2判断的,所以有人留言说自己既不是0xFFFFFFE9也不是0xFFFFFFFD,该取哪个指针。
3.2 这样定位的原因 – 入栈
再说下为什么通过SP去找PC可以实现定位呢?Keil左侧的寄存器里本身已经有一个PC了呀?R14寄存器的描述如下:
从黄色高亮的注释语句可以得出,Keil左侧的PC是hardfault函数的地址,对于定位问题并没有帮助。
再顺便记录下STM32的入栈。栈是向下增长的:


四、遇到的hardfault情况
4.1 地址不对齐导致的hardfault
做IAP升级功能,发现只要写flash,一跳转函数就直接进入hardfault。最后发现是传参时,buf没有四字节对齐:
keil本身是默认4字节对齐的呀,仿真查看最开始传入的参数指针也是4字节对齐的。经过查找,是串口解析数据后,去掉了7个字节的包头,传入data部分,就导致了地址不对齐。在函数内定义局部变量,把传入的数据拷贝到后再使用:
4.2 访问地址越界
划分64K片上flash空间,最后2K作为参数存储区。在填写参数起始地址的时候,直接写成了64K(0x08010000),结果读取参数进入hardfault。
边栏推荐
- Ranking and evaluation of the second "green tree Cup" Mathematics Competition
- 4 a company has branches in six cities C1, C2, C3... C6. The connection between cities Ci and CJ (I, j=1,2,3,... 6) and the cost are listed in the following weighted adjacency matrix C
- O'Neill's RPS curve compilation method (original by Dr. Tao)
- Introduction:Multiple DataFrames
- Huawei Technologies:Jonatan Krolikowski | 从设计到部署零接触深度强化学习WLANs
- 谷歌浏览器开发者工具的使用(掌握!)
- Ranking of top ten ERP software systems at home and abroad!
- Huawei technologies:jonathan Krolikowski | from design to deployment, zero contact deep reinforcement learning WLANs
- matplotlib绘制多折线图(解决matplotlib中文无法显示问题)
- [7.15] code source - [neat array 2] [ternary cycle] [reverse pair on tree] [sequence of cochlea]
猜你喜欢

Colliding Mice碰撞老鼠工程分析

Version announcement | Apache Doris 1.1 release version officially released!

华为无线设备配置静态负载均衡
![[7.13] code source - [hungry meals] [path count 2] [function sum]](/img/0a/d0510848c473679a4c93132968ddce.png)
[7.13] code source - [hungry meals] [path count 2] [function sum]

负载均衡有哪几种实现方式?

2022年中国AI医学影像行业概览报告

Redis源码与设计剖析 -- 4.跳跃表

QT use qlisview to realize QQ login history list

华为无线设备配置用户CAC

Ranking of top ten ERP software systems at home and abroad!
随机推荐
Event preview | Apache Doris x Apache seatunnel joint meetup to start registration!
2022年中国AI医学影像行业概览报告
No.4 bits, bytes, information storage
主流erp系统排名,主流erp系统对比
A review of classical must see for Nonconvex Optimization Problems "from symmetry to geometry", University of Rochester, et al
洛谷P3522 [POI2011]TEM-Temperature 题解
Some puzzles about data dictionary
CBS类型PVC回收策略
STL string output and modification
asterisk: rejected because extension not found in context ‘from-ipphone‘
Google Earth engine - 1992 present mixed coordinate ocean model, water temperature and salinity (global ocean data set HYCOM)
新建一个eureka client
洛谷P2422 良好的感觉 题解
Introduction:Multiple DataFrames
No.2 compilation preliminary
Robotics at Google:Laura Graesser | i-Sim2Real:在紧密的人机交互循环中强化学习机器人策略
009 面试题 SQL语句各部分的执行顺序
分析并HOOK SSHD来劫持密码
看一看try{}catch{}
函數初認識-下