STM32意外复位问题调试

最近在使用STM32座项目时遇到一个奇怪的问题。系统一开始运行很正常但是在长时间运行之后会随机的出现STM2单片机无故产生复位的问题。因为在调试的过程中收获颇多,所以打算记录一下这一次的调试过程。

首先做问题分析,既然单片机在运行一段时间之后会产生复位。那具体是什么原因引起的单片机复位呢?拍脑子一想会不会是没有及时喂狗导致看门狗溢出引起的复位。为了证明这一点我们查询了stm32的数据手册有关于复位源的介绍

由上面的描述我们可以知道在RCC_CSR中记录了单片机复位的类型。因此我们只要在单片机启动时去读取该寄存器中的对应状态位即可判断出单片机上一次是因为何种原因产生复位的。注意:RCC_CSR寄存器是需要软件清除的。如果已经产生的复位标志没有被清除他会一直被存储,即使不在有对应的复位产生该复位标志还是一直存在。所以我们在使用其判断上一次复位类型时需要先软件清除方可使用。

通过上面的方法果然确定了复位的原因是由看门狗溢出引起的复位。那到底是什么原因引起的看门狗溢出?在线调试发现是因为产生了hardfault错误系统进入了hardfault的while循环所以没有喂狗而导致看门狗溢出引起系统复位。

为什么会引起hardfault错误呢?这个真的很奇怪哎。不过不怕只要我们能定位到单片机在引起hardfault错误前执行了什么程序应该就能进一步去判断问题引起的原因。这里介绍一下在keil中定位的方法。当进入Hard Fault断点后,菜单栏Peripherals >Core Peripherals >Fault Reports打开异常发生的报告,查看发生异常的原因。

由上面的的报告可知发生了BUS FAULT,并将Fault的中断服务转向Hard Fault。接下来我们点击View选择Call Stack窗口。然后在Call Stack的HardFault_Handler上右键Show Caller Code,这时候我们就能定位到是因为那条语句引起的HardFault错误了。

主要原因是自己在定义数组长度时使用了变量。导致的HardFault错误。修改对数组的定义。取消使用变量来初始化数组长度后。问题得到解决。