搜索

[学习笔记] 是谁偷走了DMA的数据

[复制链接]
4342|3
手机看帖
扫描二维码
随时随地手机跟帖
GrootBrain|  楼主 | 2021-7-9 14:06 | 显示全部楼层 |阅读模式
#技术问题分析#
前些天,一个小伙伴告诉我,他用DMA搬运ADC的数据,刚开始的时候,数据是好好的,每个通道的数据都在DMA缓存上好好地排着对,在什么都没有动的情况下,缓存中的数据队列乱了,像是多了某个通道的数据或少了某个通道的数据。
正常情况下的缓存队列:
1625807692(1).png
错误情况下缓存队列:
1625808187(1).png 1625808103(1).png
对比数据,发现错误时,DMA缓存中的队列乱了,虽然错误的位置是随机的,而且还没有错误的数值。
后来小伙伴还告诉我,他没有再复现出缓存中队列发生错位的现象。这与当时给我展示的,几分钟内就出现缓存错位的现象严重不符。

我们来看一下DMA搬运的过程,DMA的搬运是需要触发的,如果没有触发,那就在ADC转化的过程中,就会搬运数据,那将得到一堆错乱无效的数据。既然是需要得到正确的采样结果,那只有是在转换完成后才能触发DMA搬运数据,而且,DMA搬运完成后,触发信号需要清除。说到这,或许已经有人知道我说的是哪个标记位了,是的,没错,就是转换完成标记位。
1625809294(1).png

会不会是谁动了这个标记位,导致了DMA没有触发信号,然后DMA少读了数据,造成了队列错误的情况呢?
答案是有的!!!
我们看下这个标记位,是在写 0 或读取ADC_RDR 以清除该位,首先可以代码中排除了认为给EOC赋值或操作ADC 状态寄存器的可能,就剩下读取ADC_RDR的可能了。
但是在代码中,没有人为地读取ADC_RDR寄存器,那到底是谁读了寄存器呢。这让我想到了debug下的ADC寄存器窗口。
1625809823(1).png
心细的小伙伴就会发现,debug下,该窗口下的值是会跳动的,也就是DMK在不断的读取ADC模块的寄存器的值。

想到这,我立马寻找小半伙,问他前些天出现DMA错位的现象,是不是出现问题的时候,是有查看ADC寄存器,后来没有复现到问题的时候,是没有查看ADC寄存器状态的。小伙伴给我的答案是肯定的。
于是我打开前几天跑了一晚上没复现DMA缓存错位的工程,默默的将ADC寄存器窗口打开,发现一下子就能把问题给浮现了。
DMA缓存中数据错误,就是由于MDK开了ADC寄存器窗口,读取了ADC_RDR,造成了EOC标记被清,DMA没有得到触发而少搬运数据造成的。

发散:由此看来,调试其他模块DMA搬运时,打开了DMA搬运的外设寄存器,都会造成MDK读取对应的data寄存器,会把对应标记位清楚,DMA得不到触发,没有搬运数据,造成DMA缓存中的数据错位。

如何避免?
1. 不要打开DMA搬运的外设;
2. 不要在watch窗口输入DMA搬运的寄存器或地址;
3. 不要在memory窗口读取外设的地址。


使用特权

评论回复

评论

Sy1vester 2021-7-9 14:23 回复TA
是他,就是他,是他,就是他,我们的朋友 小那托 
hc1223| | 2021-7-9 14:31 | 显示全部楼层
问题已解决,只有调试时在
1. 不要打开DMA搬运的外设;
2. 不要在watch窗口输入DMA搬运的寄存器或地址;
3. 不要在memory窗口读取外设的地址。
中会出现。
烧录后脱机正常跑没问题!

使用特权

评论回复
zhengshuai888| | 2021-7-9 18:09 | 显示全部楼层
这个很正常,把自己给坑了。

使用特权

评论回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

本版热帖

本版活跃用户

优质原创写原创,赢大奖

编辑推荐

  • 1 kk的回忆 得到打赏 ¥561.01
  • 2 火星国务卿 得到打赏 ¥518.00
  • 3 呐咯密密 得到打赏 ¥295.00
  • 4 小叶三千 得到打赏 ¥210.00
  • 5 jinglixixi 得到打赏 ¥190.00
  • 6 Gavin3389 得到打赏 ¥180.00
  • 7 神圣雅诗人 得到打赏 ¥170.00
  • 8 xyz549040622 得到打赏 ¥150.00
  • 9 linghz 得到打赏 ¥120.00
  • 10 137017878 得到打赏 ¥115.00
在线客服 快速回复 返回顶部 返回列表