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

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

[复制链接]
STMCU小助手 发布时间:2023-7-26 16:10
1. 引言
STM32 G0 系列产品具有丰富的外设和强大的处理性能以及良好的低功耗特性,被广泛用于各类工业产品中,包括一些需要低功耗需求的应用。
2. 问题描述
2 h- _% Z) j6 |# \2 q/ |7 ^
用户使用STM32G0B1 作为汽车多媒体音响控制器的控制芯片,用来作为收音机频道存贮和各种检测控制。在实验室条件下模拟汽车频繁打火的情形进行测试,连续工作72 小时实验中,进入STOP 模式后,会出现无法再继续运行的情况(屏幕没有显示输出,外部中断无反应)。

$ v# B+ K( F  u2 {) t

% s+ s+ P& ]- F9 y$ h
3. 问题重现- w3 a5 z6 o6 E7 ^5 _! Y& T

+ B# k( K4 o+ p* t+ q
通常调查问题时采取调试监控的方式。但是用户产品是在检测外部掉电时,测外部电压(汽车ACC 电源,轿车12V)下降后,立刻进入低功耗模式,然后通过RTC 和外部中断(PC13 下降沿触发即汽车打火上电)唤醒MCU 继续工作。
8 x8 k" q+ Y. O$ K. n. A
那么既然是已经进入低功耗模式,并且在几十个小时内才会出现故障,通常的用ST-LINK 在线调试方式显然很困难重现问题,即使幸运的遇到了故障,也很容易错过引起故障的代码部分,看到了现象却无法定位。

$ c% Q7 Z4 s* X5 b1 [2 Z
在此种情况下,正面分析出问题的可能性极小,况且用户代码量超过200k。这时候采用排除法不失为一种可行的办法。通过增加测试样本数量,进行并行测试提高定位效率。

9 a# |. j$ o) E+ h; D
图1 是为了方便说明问题,模拟用户关键程序。主要是进入STOP 前后外设的处理,来复现故障现象。

; k! a1 W8 U1 c/ o2 t7 y
微信图片_20230726160330.png
图1 模拟ACC掉电唤醒程序
9 |1 k3 V  d( ?
在经过一段时间的实验,并从增加和减少该段代码的排除中,最后验证并定位到下面的代码引起故障发生。

- q% ]1 D4 e7 A$ J6 g9 g% L3 P
微信图片_20230726160331_2.png
图2 定位到引起的故障代码
3 d* S/ P! H  x+ _9 X7 _9 F0 u+ Q
反复分析我们可以看到,在进入STOP前,用户需要停止ADC和DMA。但是在停止DMA时,用户程序直接停掉DMA的时钟。从函数名称上看,是从其他软件直接搬过来,并且误以为是DMA的默认初始化动作。
* O: K, U& |5 A# g
微信图片_20230726160331_1.png
图3 DMA正确的停止方式

. ]9 }7 f5 ^, _9 Z! u2 o
查询参考手册,停止循环模式的DMA应该从外设停止开始,而不是简单粗暴的停止DMA时钟。而且,在程序顺序上客户是先停止了DMA的时钟然后才去停止ADC的DMA请求。显然,当DMA开始工作时,突然停止时钟会使DMA和总线处于一个不确定阶段状态,因此才有极低概率发生唤醒故障。
6 B/ k0 ^! c6 w9 b9 j  B5 v* d
到此已经找到了发生的原因,按说应该找到了前因后果。但奇怪的是无意中发现振荡器的波形比较奇怪,并不符合低功耗模式。

  P4 z$ S$ h' D8 A1 D# m
微信图片_20230726160331.png
图 4 外部振荡器HSE 波形
) S# B; j$ k' R5 }8 q3 C
在发生故障状态时发现外部震荡器还在持续震荡,因此判定此时并非进入低功耗模式。利用IAR编译器以HOT PLUG的方式连接调试与观测。
1 Q# t) x! j$ s1 u' O3 Z' R. _
通过调试界面可以看到,代码会不停的进入DMA中断。

; ], P. i6 v& H* I" }" X6 N  r
微信图片_20230726160332_1.png
图5 故障模式下的调试
! R  `* X9 s0 @2 a
微信图片_20230726160332.png
图6 代码进入循环过程

0 Z  O' f) l0 V7 v
奇怪的是每次并没有看到DMA的寄存器内容,原因是已经关闭了DMA外设的时钟。所以无法看到任何状态标志。退出中断时在C语言下就无法单步调试了。切换到汇编界面下,可以看到代码可以继续运行到系统时钟配置函数,但是在配置函数中的除法部分进入了循环,然后又发生了DMA中断,并且循环没有出来。
1 H- p3 h- W+ u, G. p' v0 d
显然,正常的调试手段已显示出逻辑的不正常。
; V7 |' f  J# O8 f, F2 `' O
4.小结
' g3 q9 w0 K' D2 w6 G: B
至此,情况已经明了。由于软件在进入低功耗前试图关闭ADC加DMA工作,没有按照手册的规范,通过外设停止的方式关闭,而是简单粗暴的关闭DMA时钟,导致总线和运行逻辑出错,无法继续执行。
* O5 J+ @. G9 }
外部看起来像是进入低功耗模式后,外部中断触发没有执行,芯片没有唤醒,实际上是DMA进入了不正常的循环中断方式导致了系统卡在循环代码下。

, r% u9 v2 M7 l
芯片的外设功能强大,每种外设运行的方式也不相同,因此停止外设时需根据外设特点以及参考手册的建议来实施,切不可按自己想象的方式执行,这样引起隐蔽的偶发故障就很难去定位解决了。
3 q% }; @6 _- E( \  F  e
此外ST已经建立好完整强大的生态系统,按照cube 软件库的规范编写调用驱动函数可以避免少走类似的弯路。

7 M  `5 V: a7 _1 \$ ~4 C" J
转载自: STM32单片机
如有侵权请联系删除
5 j5 Z+ g. Z: t) h
( i( I+ ?# K' \1 ?4 R4 R
收藏 评论1 发布时间:2023-7-26 16:10

举报

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

好牛啊

学会了

所属标签

相似分享

官网相关资源

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