收藏官网首页
查看: 8863|回复: 0

关于stm32 HardFault_Handler

65

主题

123

帖子

787

积分

高级会员

Rank: 4

积分
787
跳转到指定楼层
楼主
发表于 2016-3-30 13:59:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
校园创客福利
STM32开发的时候,出现了HardFault_Handler硬件异常,也就是死机,尤其是对于调用了os的一系统,程序量大,检测堆栈溢出,以及数组溢出等,找了半天发现什么都没有的情况下,估计想死的心都有了。如果有些程序开始的时候一切没有问题,但是运行几个小时候,会发现死机了,搞个几天下来估计蛋都碎了一地吧。。。
一般来说运行操作系统  是以下几个问题
1.开始的时候给ucos分配的堆栈太小了,随着项目做多了,这类问题一般很容易解决
#define TASK_IO_SIZE  300
#define TASK_IO_PRIO 6
OS_STK  TASK_IO_STK[TASK_IO_SIZE];
比如修改300到 1000,做开发的时候 如果ram允许,尽量大些,免的麻烦

2.数组溢出
这类问题一般在通信中,接受数据的时候,特别是长度不定的时候
比如协议为     :开始  功能码  长度  数据1  数据2 。。结束
长度决定了后面的数据多少,在分配接受缓冲的时候   ,突然来了个错误的长度比如255
但是我们分配buffer[100],只定义了100,这样数组就溢出了
所有在放数据之前要对长度进行判断是否合理,以后 如果有长度 或者索引就要想到溢出。。

3.使用了非法的指针 ,比如空指针 ,编译对的 但是运行就错了
u8 *p = null;
*p = 1;        把0地址的数据强制设置为1,  不错才怪

4.使用 OS_ENTER_CRITICAL();
使用了 OS_ENTER_CRITICAL(); 却忘了OS_EXIT_CRITICAL(); 退出临界区
特别是在这个函数OS_ENTER_CRITICAL();  调用了子函数 也有的这类情况,很容易忘记关闭的这样就造成了“死机现象”
因此如果调用的话  建议在函数中加入OS_CPU_SR  cpu_sr = 0u;局部变量 在管理临界区   os的内核程序也是这么用的  ,而且要注意,临界区一般用于全局变量的写操作,时间要非常快的,任务中的变量可以不用添加 。

备注:STM32出现HardFault_Handler故障的原因主要有两个方面:
1、内存溢出或者访问越界。这个需要自己写程序的时候规范代码,遇到了需要慢慢排查。
2、堆栈溢出。增加堆栈的大小。

出现问题时排查的方法:

1、发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。由于异常发生时,内核将R0~R3、R12、Return address、PSR、LR寄存器依次入栈,其中Return address即为发生异常前PC将要执行的下一条指令地址,因此在堆栈中反数第三个字即为出错位置。

2、默认的HardFault_Handler处理方法是B .将它改成BX LR直接返回的形式。然后在这条语句打个断点,一旦在断点中停下来,说明出错了,然后再返回,就可以返回到出错的位置的下一条语句那儿。
这个有时候可能需要在反汇编模式下调试,因为可以是程序跑飞一会儿才出现HardFault_Handler。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表