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

基于STM32的看似无法唤醒的一种异常现象分析

[复制链接]
STMCU小助手 发布时间:2023-7-26 16:10
1. 引言
STM32 G0 系列产品具有丰富的外设和强大的处理性能以及良好的低功耗特性,被广泛用于各类工业产品中,包括一些需要低功耗需求的应用。
2. 问题描述

4 c7 l1 ?5 _, Y5 ^
用户使用STM32G0B1 作为汽车多媒体音响控制器的控制芯片,用来作为收音机频道存贮和各种检测控制。在实验室条件下模拟汽车频繁打火的情形进行测试,连续工作72 小时实验中,进入STOP 模式后,会出现无法再继续运行的情况(屏幕没有显示输出,外部中断无反应)。
+ \9 u9 J  b- @4 f- p" _4 G2 e

" M/ e" V0 b5 Z  L* o
3. 问题重现
' a1 K1 U: i' X) V

  D* h& _% R, d
通常调查问题时采取调试监控的方式。但是用户产品是在检测外部掉电时,测外部电压(汽车ACC 电源,轿车12V)下降后,立刻进入低功耗模式,然后通过RTC 和外部中断(PC13 下降沿触发即汽车打火上电)唤醒MCU 继续工作。
" Q& i  H. T( Q' |
那么既然是已经进入低功耗模式,并且在几十个小时内才会出现故障,通常的用ST-LINK 在线调试方式显然很困难重现问题,即使幸运的遇到了故障,也很容易错过引起故障的代码部分,看到了现象却无法定位。
& F7 ^( g% G/ |/ X
在此种情况下,正面分析出问题的可能性极小,况且用户代码量超过200k。这时候采用排除法不失为一种可行的办法。通过增加测试样本数量,进行并行测试提高定位效率。
( t9 X3 j1 \- V" f, d
图1 是为了方便说明问题,模拟用户关键程序。主要是进入STOP 前后外设的处理,来复现故障现象。

8 q( y% b3 t0 z+ Y& l
微信图片_20230726160330.png
图1 模拟ACC掉电唤醒程序

2 b' S& c3 Y4 }! h# r+ r
在经过一段时间的实验,并从增加和减少该段代码的排除中,最后验证并定位到下面的代码引起故障发生。

. P4 V: Z0 J' P/ {
微信图片_20230726160331_2.png
图2 定位到引起的故障代码

# z, c& q% {$ S( a2 A8 f
反复分析我们可以看到,在进入STOP前,用户需要停止ADC和DMA。但是在停止DMA时,用户程序直接停掉DMA的时钟。从函数名称上看,是从其他软件直接搬过来,并且误以为是DMA的默认初始化动作。
  T; U6 w1 z6 R7 _% \3 K0 O3 @
微信图片_20230726160331_1.png
图3 DMA正确的停止方式
- Q7 z0 h. P9 W6 b9 g: V* L
查询参考手册,停止循环模式的DMA应该从外设停止开始,而不是简单粗暴的停止DMA时钟。而且,在程序顺序上客户是先停止了DMA的时钟然后才去停止ADC的DMA请求。显然,当DMA开始工作时,突然停止时钟会使DMA和总线处于一个不确定阶段状态,因此才有极低概率发生唤醒故障。

6 g& s, f5 {0 K* Y. v  J- Y4 G( |
到此已经找到了发生的原因,按说应该找到了前因后果。但奇怪的是无意中发现振荡器的波形比较奇怪,并不符合低功耗模式。

$ g" C: C" D! q2 W8 X
微信图片_20230726160331.png
图 4 外部振荡器HSE 波形
3 Z+ V9 c: ^2 A+ Q0 m9 m$ x: Y
在发生故障状态时发现外部震荡器还在持续震荡,因此判定此时并非进入低功耗模式。利用IAR编译器以HOT PLUG的方式连接调试与观测。

$ y5 Q0 M# c5 f0 R! k: J& X
通过调试界面可以看到,代码会不停的进入DMA中断。
& Q& H$ D" d2 ^5 m  G$ B5 y# i, \
微信图片_20230726160332_1.png
图5 故障模式下的调试

0 L5 g" ?8 {2 C4 r
微信图片_20230726160332.png
图6 代码进入循环过程
- s2 w; J8 A' K1 H+ ]2 s
奇怪的是每次并没有看到DMA的寄存器内容,原因是已经关闭了DMA外设的时钟。所以无法看到任何状态标志。退出中断时在C语言下就无法单步调试了。切换到汇编界面下,可以看到代码可以继续运行到系统时钟配置函数,但是在配置函数中的除法部分进入了循环,然后又发生了DMA中断,并且循环没有出来。
& _; J3 \! K8 r# Q+ N5 S' ~! p
显然,正常的调试手段已显示出逻辑的不正常。

8 P" i# g9 T8 u5 q" F
4.小结
. e, `8 ~5 m: `* H  ?! x
至此,情况已经明了。由于软件在进入低功耗前试图关闭ADC加DMA工作,没有按照手册的规范,通过外设停止的方式关闭,而是简单粗暴的关闭DMA时钟,导致总线和运行逻辑出错,无法继续执行。

! L5 q: |5 \5 ^4 J+ |3 n
外部看起来像是进入低功耗模式后,外部中断触发没有执行,芯片没有唤醒,实际上是DMA进入了不正常的循环中断方式导致了系统卡在循环代码下。

% d9 Z/ f5 `; U5 @! q
芯片的外设功能强大,每种外设运行的方式也不相同,因此停止外设时需根据外设特点以及参考手册的建议来实施,切不可按自己想象的方式执行,这样引起隐蔽的偶发故障就很难去定位解决了。
$ l- v" d8 o0 W* p; |) T
此外ST已经建立好完整强大的生态系统,按照cube 软件库的规范编写调用驱动函数可以避免少走类似的弯路。
. @, F* e3 ?; g4 P1 P- s0 U% l/ B
转载自: STM32单片机
如有侵权请联系删除
  l- S5 b7 C( ?) r: S% J# ?
1 l0 Y& H8 X: r
赞 收藏 评论1 发布时间:2023-7-26 16:10

举报

1个回答
bitterheart 回答时间:2023-8-1 17:11:22

好牛啊

学会了

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版