你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

经典案例解析 | STM32芯片异常复位

[复制链接]
木木&点点 发布时间:2019-3-28 21:38
本帖最后由 点点&木木 于 2019-4-12 09:51 编辑


问题描述
某STM32用户反馈,当使用STM32L4芯片的时候,程序运行一段时间后,会忽然复位。复位后程序继续运行,但是还会继续复位,原因不详。

问题解析
01
初步确定复位的原因,是硬件复位,如外部NRST被拉低,还是软件复位,包括软件直接调用复位,或者看门狗复位,还是低功耗模式如standby模式被唤醒时产生中断。

02
查看复位状态寄存器了解复位大方向,然后做进一步得拆解分析。

03
目前客户项目的复位原因是因为看门狗复位,即客户使用了IWDG,但由于某种原因没有及时喂狗,导致IWDG超时复位。初步怀疑由于客户软件的问题,程序跑飞,进入异常处理。

因为客户的异常处理函数中并没有做任何动作,导致独立看门狗IWDG复位。基于此,我们先关闭IWDG,然后在所有的异常处理中,先加入死循环并打上断点,对异常原因进行捕捉。

1.png

04
正如我们所猜测,的确是由于程序跑飞导致。程序停在了voidHardFault_Handler(void) 。
通过查看SP以及回溯栈里面的内容,找到了对应的LR,具体方法如下:
2.png
如上图所示,当产生异常时,如果call stack窗口显示不出来的话,只能根据core的寄存器手动回溯栈,以找到出错时的指针。根据ARM core的说明,SP+6,即红框的部分,为中断处理后LR和PC,据此可以追溯函数异常时的位置。

05
根据出错时的PC和LR,发现是浮点运算的函数,初步判断是因为浮点运算导致,比如没有对齐导致的Hardfault,但实际检查发现,并不是浮点运算的问题。

06
问题一时陷入了僵局。但有一点是确定的,是因为栈的区域被异常覆盖或者改写导致产生hardfault。

07
由于问题可以稳定复现,采取逐个排除法最终发现了问题的所在:
当把一个局部数组变量改为全局数组时,问题消失!
由于局部数组变量是保存在栈当中,所以怀疑是对这个局部数组变量使用不当导致了栈被覆盖或者改写。
追查这个局部变量数组:
3.png
经检查发现,这个原先是8bit的局部变量的数组,在最后被强制转换成了uint32_t*类型的指针,由于是指针,在对其进行++或--操作时,都是按照4字节宽带操作的,这就相当于扩大了4倍,覆盖了后面的栈的内容,导致了程序跑飞。

  小结  
当芯片异常复位或者进入异常处理 (如Hard fault, Mem Manage, Bus fault等)时,首先考虑的是,如何快速的复现这个问题,当问题被稳定复现的时候,可以通过调试工具在异常处理的地方打上断点停留,这样就可以获取到栈指针SP,通过SP去看栈里面的内容去回溯栈。当然,如果栈的内容被无端改写时,栈里面的内容,如保存的LR就没有太大的参考意义。不过,可以通过观察栈里面的内容,去估测是哪个模块或者函数异常修改了栈的内容,进而定位最终的问题源。


收藏 1 评论5 发布时间:2019-3-28 21:38

举报

5个回答
maxtch 回答时间:2019-3-29 00:13:25
内存跑飞基本都是开发人员代码不过关导致的。这个漏洞很容易被人抓住转化成安全漏洞的。
木木&点点 回答时间:2019-3-29 08:47:09
maxtch 发表于 2019-3-29 00:13
内存跑飞基本都是开发人员代码不过关导致的。这个漏洞很容易被人抓住转化成安全漏洞的。 ...

哈,大佬出现了。确实存在这种安全隐患
一代睡神的崛起 回答时间:2019-3-29 09:19:13
get到了
千千结 回答时间:2019-3-29 10:35:52
上周刚遇到了这个问题,使用了一个数据池,结果访问的时候没有使用4字节对齐导致复位了,弄了好久好久
木木&点点 回答时间:2019-3-29 12:23:14
银天蓝 发表于 2019-3-29 10:35
上周刚遇到了这个问题,使用了一个数据池,结果访问的时候没有使用4字节对齐导致复位了,弄了好久好久 ...

实践出真知

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版