关于STM32等ARM程序Fault中断错误分析与解决办法

HardFault_Handler出现的情况一般有两种:
一种是:数组越界
一种是:堆栈溢出,程序指针指飞
一种是:falsh内存写入错误,错误把写入地址写到了程序存储区,造成Fault错误

现象:最近在用Keil对STM32的程序进行仿真时出现下面的现象。

1、仿真时,程序有时会跑飞,也就是说程序在执行一会儿就不知道执行到哪里了。

2、停止仿真时,程序会停在HardFault_Handler函数里的死循环while(1)中。

可能原因:由于定义变量太多,堆栈溢出

解决办法:将定义的局部变量尽量定义为全局变量。

理论原因:在C编译器中,局部变量和函数参数名是存在栈中的,全局变量和静态局部变量是存在静态区。局部变量太多,栈满了就会导致溢出。
方法一

在中断HardFault_Handler中的while()处打上断点,让程序执行到此处停止。
在这里插入图片描述
在Registers里面找到R14(LR)的值,我的这里是:0xFFFFFFF9
说明一下:
0xFFFFFFF9对应的是要看MSP寄存器
0xFFFFFFFD对应的是要看PSP寄存器
所以这里需要查找的内存地址是MSP的值:0x20008828

在这里插入图片描述
在memory里面查找MSP的值:0x20008828,然后在对应的行里面找到地址,地址一般格式都是:0x0800BA68这样的。
在这里插入图片描述
4.在Disassembly里面右键选择Show Code at Address,把找到的地址输进去进行搜索,然后就会找到相对应的代码,这里的代码就是在进入循环中断之前的时候的情况,仔细查看这部分函数被调用或者数组内存使用情况。
在这里插入图片描述
方法二

在中断HardFault_Handler中的while()处打上断点,让程序执行到此处停止。
在这里插入图片描述
在keil中打开Call Stack + Locals,然后在HardFault_Handler上 右键选择:Show Caller Code,就会跳转到进入循环中断之前的函数处。仔细查看这部分函数被调用或者数组内存使用情况。
在这里插入图片描述
当单片机有需要用到内部Flash时,一定要注意Flash所使用的地址是否被程序的代码地址所覆盖,因此,选择Flash地址时一定要看看MAP文件中所占用的RAM资源是否超出了Flash的地址,建议Flash选择的地址片要稍微大一些。以避免出错。之前我就是移植UCOSIII+LWIP时,反复进入Fault中断函数,最后Debug发现时Flash写入的地址片太小了,占用到了主程序的Flash空间了。

注意:值得说明的是,Fault中断错误引起原因可能是多方面的,可能是硬件错误,线连接错误或者元器件损坏等都有可能;软件程序方面也可能是多原因的,比如内存溢出,数组越界,野指针,,指针错误等,rom内存占用,程序大小溢出RAM等。因此,Fualt错误需要具体判断具体分析!方式仅供参考。

参考链接:https://www.amobbs.com/thread-5730375-1-1.html
参考链接:https://www.pianshen.com/article/458298021/

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值