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

STM32F3系列SDADC外部触发 DMA运输的bug

[复制链接]
rui41104 提问时间:2026-7-15 16:11 / 未解决

最近公司说现场有机器卡死的情况 让复现出卡死的bug 逻辑是这样

ADC触发是外部上升沿触发 1ms触发一次 触发一次ADC采集一组 一组三个数据 一共采集15组 采集到之后 给DMA发请求 DMA把数据从ADC外设搬到内存 DMA传输完45个了 触发DMA的中断 DMA中断内先关掉ADC 再关掉PWM 然后改了一下标志位为1 主循环内一开始标志位为0 为1的时候进行数据处理 处理完了把标志位改为0 进行下一轮 现在是想复现出ADC卡死的情况 目前推测是和JDMAEN的置位时刻有关 感觉可能是时序问题 翻到数据手册发现有这么一句刚好是描述我这个的情况

In order to stop a circular transfer, the software needs to stopthe peripheral from generating DMA requests (such as quit the ADC scan mode), before disablingg the DMA channel The software must explicitly program the DMA_CNDTRX value before starting/enabling atransfer, and after having stopped a circular trans。

这个让关掉ADC前先关触发源 我想知道如果先关触发源会导致什么bug

求助求助 要复现卡死这个bug 求助

收藏 评论12 发布时间:2026-7-15 16:11

举报

12个回答
butterflyspring 回答时间:5 天前
现场卡住的话,保持不掉电,可以连接上调试器去看看各种寄存器状态。

也许不是最最新的状态,但是会有一些信息可以提示方向。

如果是进入循环状态,那就更容易推断出可能性了。
butterflyspring 回答时间:6 天前
rui41104 发表于 2026-7-15 17:18
[md]你好 非常感谢你的回答
目前这个丢数据我已经发现 JOVRF会置位为1 代表数据溢出 也会存在一部分数据 ...

不是很了解为什么不触发DMA中断ADC会卡住。

我看到的小伙伴停止DMA时直接关闭DMA时钟。然后进入STOP。
有的时候会观测到,DMA中断标志起来了,然后又不停进入中断,导致看起来外部唤醒信号失效。
因为没有了DMA的时钟,所以这个标志会清除不掉。

所以按照手册推荐的顺序是合理的。
butterflyspring 回答时间:7 天前
这段话是说要停止循环传输,软件需要在禁用 DMA 通道之前,先阻止外设生成DMA 请求(例如退出 ADC 扫描模式)。  所以如果不这样做理论上会遇到下面的问题:
1.剩余DMA 传输不保证正确完成,可能出现丢数、少搬一部分、buffer尾部数据异常
2.不会产生正常的DMA 传输完成中断,导致软件流程可能卡在等待完成事件上
3不能指望后续直接恢复这个DMA 通道;不重新配置(特别是 DMA_CNDTRx)就恢复运行,是硬件不支持
4.某些场景下还可能出现重新使能后传输意外延续、状态不一致的问题,因此才要求必须先停外设请求,再关DMA
5.另外我还遇到过去进STOP 后没有唤醒的故障。


所以你可以提高这段软件运行频率看看发生故障的现象是否也高频发生。

rui41104 回答时间:7 天前

butterflyspring 发表于 2026-7-15 17:01
这段话是说要停止循环传输,软件需要在禁用 DMA 通道之前,先阻止外设生成DMA 请求(例如退出 ADC 扫描模式 ...

你好 非常感谢你的回答 目前这个丢数据我已经发现 JOVRF会置位为1 代表数据溢出 也会存在一部分数据丢失的情况 这会导致HAL_SDADC_InjectedStart_DMA的返回值是ERROE 同时JDMAEN位无法被置为1 但是这并不会导致ADC卡死的情况 我观察到如果JDMAEN位被错误置为0的话会出现ADC采样 DMA停止搬运 导致中断无法触发 造成ADC卡死的情况 但遗憾的是我目前并不知道什么情况下JDMAEN会被置为0 对于你提到的进入STOP之后无法唤醒的情况 我很感兴趣 这可能与我复现bug有关 我想知道进入stop之后无法唤醒的故障是怎么触发的 十分感谢你的回答

rui41104 回答时间:5 天前

butterflyspring 发表于 2026-7-16 11:10
不是很了解为什么不触发DMA中断ADC会卡住。</p>
<p>我看到的小伙伴停止DMA时直接关闭DMA时钟。然后进入STOP。

十分感谢您的回答

昨天继续排查时 仍然毫无进展 目前推测的死锁路径时ADC采样数据 DMA传输数据 传输一定数据量后DMA触发中断 如果在DMA传输过程中 ADC的JDMAEN使能位被关掉 就会造成ADC在采样 DMA无法传输 数据量永远不会传输过去 DMA的CNT也不会减少 从而无法触发中断 构成死锁

但是似乎这样的路径不太可能 生产环境中不知道发生了什么

手册中那样写 可能是因为如果未关闭触发源 那么在关闭ADC的过程中 由于外部持续的触发源 会导致JCIP持续置为1 HAL源码会在这里等待200ms直至JCIP清0 如果等待超出时间 会使得stastus变为超时 也会导致ADC卡死无法恢复的错误

遗憾的是源代码里作为超时基准的systick优先级较低 并不会造成超时的情况 唉

rui41104 回答时间:5 天前

butterflyspring 发表于 2026-7-17 10:16
现场卡住的话,保持不掉电,可以连接上调试器去看看各种寄存器状态。</p>
<p>也许不是最最新的状态,但是会有一些 ...

谢谢你的回答 遗憾的是并没有现场日志以及当时的寄存器状况 只有现象描述 目前推测是ADC部分出的问题 但还未找到原因 后续会将排查思路整理出来

虽然并未找到原因 但排除了各个可能会出现问题的时序情况 同时对hal库内代码的寄存器操作以及对芯片的理解加深了 只不过不知道怎么给领导交差 😢

xmshao 回答时间:前天 10:05

如果是状态机方面的原因应该是比较好跟踪的,往往会停止在固定的位置;

再一个就是代码有无可能发生非法访问的问题,尤其是地址跨界访问,这时卡在哪里就不好说,

通常往往会触发异常中断;

至于收满45个数据后的重启,应该是首先停 触发ADC的外设【比方TIMER,并令其回到初始状态】、然后就是停止ADC和DMA,待到下次传输时,再重新启动基于ADC的DMA传输,最后启动触发源,比方TIMER。

rui41104 回答时间:前天 16:26

xmshao 发表于 2026-7-20 10:05
如果是状态机方面的原因应该是比较好跟踪的,往往会停止在固定的位置;</p>
<p>再一个就是代码有无可能发生非 ...

[md]谢谢你的回答

目前还是没有找出来状态机的问题 仍然未复现出bug

这边触发异常中断这个可能性 在考虑过后 如果触发了异常中断 比如DMA传输错误 确实会导致ADC卡死的情况 但是什么会导致DMA传输错误还没有找到

rui41104 回答时间:前天 19:37

再这样下去只能考虑是硬件问题了 没办法了

xmshao 回答时间:昨天 11:13

rui41104 发表于 2026-7-20 19:37
再这样下去只能考虑是硬件问题了 没办法了

硬件方面也不排除,比方电源、外在干扰,导致ADC\DMA工作异常,最终导致DMA没法正常完成又

没法重启。代码里可以考虑加上超时管理,或者启用看门狗。

rui41104 回答时间:昨天 11:47

修正一下 即使溢出 JDMAEN也可以正常置位 之前结论有误

rui41104 回答时间:昨天 19:44

今天看了下 有个函数的内容是写flash 写的过程中会关中断 测试无果

发现ST官方曾发表过一篇与我的情况类似 都是关DMA顺序不对导致的偶发性bug

文章编号为LAT1236 看似无法唤醒的一种异常现象分析

不同点可能就是它关DMA用的是把DMA时钟关掉 我使用的是HAL_DMA_Abort

遗憾的是上面并未提出导致BUG的真正原因以及复现思路

希望可以获取官方当时处理bug的笔记或者思路 求助求助

所属标签

相似问题

官网相关资源

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