打印
[学习笔记]

是谁偷走了DMA的数据

[复制链接]
11214|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#技术问题分析#
前些天,一个小伙伴告诉我,他用DMA搬运ADC的数据,刚开始的时候,数据是好好的,每个通道的数据都在DMA缓存上好好地排着对,在什么都没有动的情况下,缓存中的数据队列乱了,像是多了某个通道的数据或少了某个通道的数据。
正常情况下的缓存队列:

错误情况下缓存队列:

对比数据,发现错误时,DMA缓存中的队列乱了,虽然错误的位置是随机的,而且还没有错误的数值。
后来小伙伴还告诉我,他没有再复现出缓存中队列发生错位的现象。这与当时给我展示的,几分钟内就出现缓存错位的现象严重不符。

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


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

心细的小伙伴就会发现,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 | 只看该作者
这个很正常,把自己给坑了。

使用特权

评论回复
地板
redone| | 2021-11-8 17:21 | 只看该作者
这个~~~我是被标题吸引的,其实

使用特权

评论回复
5
huquanz711| | 2021-11-8 20:33 | 只看该作者
嗯嗯,这个以前也遇到过一次。

使用特权

评论回复
6
guijial511| | 2021-11-9 07:57 | 只看该作者
谢谢分享知识

使用特权

评论回复
7
TechHolder| | 2021-11-11 09:33 | 只看该作者
redone 发表于 2021-11-8 17:21
这个~~~我是被标题吸引的,其实

说明标题很重要,不过这种标题就是不太好找

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

92

帖子

2

粉丝