Bootstrap

单片机STM32死机问题分析及解决方案总结

1、程序卡死在非中断的程序中,含有for while等循环体函数参数不正确导致,例如memcpy CRCcheck等。
现象:程序主逻辑无法执行,但是各个中断服务程序能够正常运行。
解决方法:
1)在中断程序中点灯或者打印,判断中断程序是否能够正常运行;
2)keil的debug模式在线调试运行,即可知道程序卡死位置。
3)在2)无法满足时,在程序主逻辑中打印或者点灯,多次编译烧录,判断卡死位置。

2、程序卡死在中断中,中断程序中没有清除中断标志位,或者中断服务程序的触发频率太高,中断没有执行完毕又触发了中断标志位,单片机在循环执行中断服务程序。
例如在高频率的中断服务程序中增加printf打印信息容易造成该现象。
现象:程序主逻辑无法执行,部分中断程序也无法执行。
解决方法:
1)在问题发生时,调整没有执行的中断程序的优先级为最高优先级,例如SysTick中断优先级、TIMER有限级等,在该对应中断服务程序中点灯或者低频定时打印,观察是否执行。
2)如果执行,则说明肯定卡死在中断中,仔细检查所有的中断程序。仍无法判断问题点,则逐步降低调整优先级的中断服务程序,直到其不被执行,确定问题程序优先级,缩小范围,再找问题。

3、程序进入HardFault,HardFault本身也是一个中断,只不过其中断优先级为-1,高于一切用户可设置中断。
产生原因(常见的均为地址类问题):
1)访问了单片机无法到达的地址;
2)访问地址不对齐,尤其是在*(int *) *(float *)等多字节强制取值时容易出现,检测强制取值的地址是否为四字节对齐。
3)PC指针跑飞,该现象在我多年经验中只遇到过一次,是在强干扰情况下,芯片PC指针突然变为非常异常值,芯片直接进入HardFault。该情况实际很少遇到,通常情况下芯片不会无缘无故跑飞,多数都为自身程序问题。
解决办法(出现问题后只能断电重启,但可以找出造成问题的点):
1)代码中增加HardFault中断服务程序,在中断向量表中可以找函数名称。
2)服务程序中增加特殊的点灯提示即可。后期任何进入HardFault的问题都能一目了然。
3)HardFault中断服务程序中可以保存芯片信息到Flash中,以便重新上电时检查问题点,保存的信息主要是进入HardFault前的PC指针,通过在该PC指针在.map文件中查找对应区间的函数,即可确认是什么函数造成了HardFault。该操作的详细步骤自行百度。

4、芯片不停的高频重启(此处不讨论硬件造成的问题),不是所有的地址异常等都会进入HardFault,有些是造成芯片重启。
现象:
1)看上去芯片主程序、中断程序、HardFault 什么都不执行了。
解决方法:
1)在main()函数的最开始(注意要先配置外设),增加点灯和延时处理,或打印。观察上电后是否有输出。并且反复输出,或者灯闪烁。
2)逐步调整点灯位置,确认造成死机点。
3)在程序执行到main之前,是先执行芯片的RESET中断服务程序,这之间会初始化中断向量表,初始化堆栈等,在.s文件中有相应的汇编代码。如果死在main之前,可尝试在RESET中断服务程序中直接操作寄存器,配置时钟和GPIO外设,控制点灯,观察是否能够点亮,以确认问题。

5、其他,芯片主时钟未开启、时钟晶振配置与实际晶振器件不服,等等等等等等等等等等等等等等等等都可能造成死机。
解决方法:
1)熟读STM32用户手册;
2)熟读《CotexM3权威指南 》 或者 《CotexM3 M4权威指南》
3)祈祷,自求多福!

;