HardFault_Handler异常(死机)的处理

在系统开发的时候,出现了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的内核程序也是这么用的 ,而且要注意,临界区一般用于全局变量的写操作,时间要非常快的,任务中的变量可以不用添加 。

常见的就上面几种了,说说硬件异常了 怎么来发现,这个才是主要的

举个例子:

a.仿真,运行程序的时候点红色X进入异常


 

b.调出堆栈窗口,也就是黑匣子


 

c.查找问题

d.找出出错的函数


e.解决问题

f  一些思考

很久之前在研究stm32 库源码的时候  发现基本上  每个函数进入之前都做了参数的检测,当初还觉得检查不检查貌似没什么大的作用,自己使用的时候注意就好了,现在是不是改变看法了吗?编程的时候很多问题,在参数检查的时候被过滤掉了,这样在开发大型项目的时候,可以给您免去很多不必要的麻烦,反而会提供开发效率哦

当然网上也有很多,检查寄存器LR SP等地址 来反推出最后运行的汇编函数调用地址的,但是肯定没有上面的直观。                                                                                                                             

11) Call Stack + Locals 窗口

局部变量

Call Stack + Locals 窗口被合并在一个集成窗口中,每当程序停止时会显示调用栈和当前函数的所有局部变量。

如果可能,局部变量的值会显示,否则显示 < not in scope >。菜单中的View/Call Stack Window 用来切换 Call Stack + Locals 窗口显示或隐藏。

运行并停止 Blinky,点击 Call Stack + Locals 选项卡。

下图展示了Call Stack + Locals 窗口。 



窗口中显示了当前活动函数的名称和局部变量列表。随同每个函数的名字会显示它被哪个函数或中断/异常调用。 
当函数退出时,会从列表上移除。 
最早调用的函数会出现在列表的底端。 
这个列表只有在程序停止运行时有效。

点击 Step In 图标 或按 F11 键。

当单步运行到不同的函数时,观察它们在窗口上显示的变化。如果陷入到Delay 函数的循环当中,可以用Step Out 或Ctrl+F11 键快速退出。

点击几次 Step In,观察其他函数。

右键点击一个函数名,尝试 Show Callee Code 和 Show Caller Code 选项。 


 

点击 Step Out 图标 退出所有函数,返回 main()。

提示: 如果单步调试(Step In)不工作,点击Disassembly 窗口使它成为焦点,可能需要点击一行反汇编代码来执行汇编级别的单步运行。如果焦点在源代码窗口上,则是执行 C 语言代码级别的单步运行。

提示: 可以在程序停止运行时,通过 Call Stack + Locals 窗口来修改变量的值。

提示: 上述是标准的“Stop and Go”调试过程。ARM Coresight 调试技术还可以做很多更强大的事情,比如在程序运行中显示并实时更新全局或静态变量,而不需要修改程序。由于局部变量通常存储在 CPU 寄存器中,不能在程序运行时实时显示,需要转换成全局或静态变量使得作用域不会消失。

问题查找方法:

HardFault_Handler解决方法 - 百度文库 (baidu.com)

STM32 | 遇到HardFault问题如何定位? - 知乎 (zhihu.com)

  • 22
    点赞
  • 103
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值