[STM32F3]

如何找到导致程序出现HardFault的代码

[复制链接]
4475|4
手机看帖
扫描二维码
随时随地手机跟帖
quray1985|  楼主 | 2016-1-28 20:30 | 显示全部楼层 |阅读模式
下午在社区群里和小伙伴聊天时谈到如果程序Fault时如何找到是哪句代码出现的问题,也就是说怎么找到程序运行到何处时出现Fault的。之前一直使用一种方法感觉不错,分享给有需要的同学。
大致的思想是当程序出现Falut时会跳转到相应的Fault中断里面,此时压入到堆栈的信息应该就是出现问题代码运行出错Fault的信息,我们要做的就是找到此时压入堆栈的LR的值。为了模拟Fault,我们将0写到地址0里面,此时debug下全速运行,程序就会进入到Fault函数中。
我们在Fault中断函数中添加一个软断点,这样做的好处是debug模式下全速运行,当程序跑飞(Fault时)会自动停在这里,否则我们还要手动停止运行才能发现程序进入了Fault中断函数。



为了方便查看程序程序的Fault时的相关信息,我们将错误信息打印到keil的debug Viewer窗口中
M3/M4内核的MCU的压栈的模式如下,我们根据下面的寄存器的存放顺序来取出压入到堆栈的寄存器的值。

同时将Fault中断时的函数重载如下,用来输出更多的信息,同时判断了是使用MSP还是使用PSP,


具体的void Hard_Fault_Handler(uint32_t stack[])函数根据寄存器SCB->CFSR判断并输出是那种Fault:
faultjpg.jpg (71.47 KB, 下载次数: 0)
下载附件
2015-7-4 19:12 上传





quray1985|  楼主 | 2016-1-28 20:31 | 显示全部楼层
最后使用函数stackDump(stack);输出出现Fault时的堆栈的值,取值的顺序是根据上面说的M3/M4内核压栈的顺序得到的:



下面我们在debug模式下全速运行如下代码,main函数如下:其中的        *(uint32_t*)paddr = 0; 会导致Fault并进入中断,

在debug模式下全速运行,不要设置任何断点,最后程序程序会在debug viewer中输出出错Fault的相应的寄存器的值并停止在__ASM volatile("BKPT #01");,此处得到的LR的值就是我们要找的LR的。

此时打开汇编窗口,在汇编窗口里面右键show Disassembly at Address选项输入LR的值然后回车

调转到的汇编的地方就是导致程序出现Fault的地方,注意M3/M4内核使用Thumb指令,要求最低bit为1,
faultjpg.jpg (130.26 KB, 下载次数: 0)
下载附件
2015-7-4 19:35 上传




上面的过程大致就是找到程序出现Fault跑飞时的方法,基本上能定位到出错的代码,使用OS时要注意判断是哪个SP在起作用。

使用特权

评论回复
quray1985|  楼主 | 2016-1-28 20:31 | 显示全部楼层
附件中是例程

CM3_Fault_Handler-master.zip

4.02 KB

F303RE_Fault_Handler.rar

396.61 KB

使用特权

评论回复
500days| | 2016-1-31 11:40 | 显示全部楼层
请问楼主,产生这个硬件错误的原因是什么呢?

使用特权

评论回复
sfd123| | 2017-7-26 11:41 | 显示全部楼层
500days 发表于 2016-1-31 11:40
请问楼主,产生这个硬件错误的原因是什么呢?

原因很多的,譬如我遇到过一个就是系统时钟配置不合理,导致有时hardfault有时又没问题!正确就一种,但是错误可以千奇百怪!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

156

主题

1488

帖子

5

粉丝