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

坑爹的D-Cache

[复制链接]
bssz1 发布时间:2017-2-24 21:32
串口+DMA接收,总是收不到数据,查了好几天,今天终于找到问题了,居然是D-Cache搞的鬼!!% ^( \. e9 N7 ]( |: N
1 收藏 2 评论12 发布时间:2017-2-24 21:32

举报

12个回答
1375854021@qq.c 回答时间:2023-7-22 13:03:50

1375854021@qq.c 发表于 2023-7-22 13:01
我也是遇到了这样的问题,我是在做STM32H750VBT6的DMA-ADC采样USB发送的时候遇到的。我是用的按键触发 ...

[md]不过没想到这个帖子已经是6年前的帖子了,还是比较感慨,吃我一记洛阳铲!!!!

破晓-2024005 回答时间:2018-7-14 22:58:30
还有一种情况,就是如果你这部分的数据是从flash里读到catch里的,这个时候你如果操作了flash里的这部分数据,这个时候catch同样也是不会更新的。
bssz1 回答时间:2017-2-26 23:04:28
转帖,原帖见http://www.51hei.com/bbs/dpj-51303-1.html7 n5 V, i: u3 J5 K

& v, c6 ~: v: s
7 W- W  ]- d& g6 nSTM32F7系列芯片集成了L1高速缓存,即L1 CACHE,包括D-CACHE和I-CACHE。它能够提升CPU访问数据或指令的速度,改善MCU的性能。关于STM32F7 L1 CACHE的应用,有个数据一致性问题需要注意,不然编程时可能会遇到些奇怪的现象。
/ H3 t1 i$ w- @0 F7 [0 V    在聊这个话题之前,先说几个基本概念或术语。. L, e- C- S8 o! H/ {8 [
1、芯片复位后,I-CACHE,D-CACHE默认是关闭的。可以分别打开或关闭以及配置各自大小。
2 u' h) ^( N, f% r( Z' W( d0 c% n2、对于STM32F7来说,只有经过AXI总线接口访问时才用到L1 CACHE。换句话,通过其它总线【TCM/AHBP/AHBS】做数据或指令访问时是不涉及到L1 CACHE的。
8 p9 \; N5 D7 O* `" U3、回写【WRITE BACK】:在写数据时,只是把数据写进D-CACHE而未写入二级存储器,并将缓存行里的数据标识为DIRTY,直到执行CACHE的清除操作才将D-CACHE里的内容写进二级存储器。
, X& n: F& }7 C& W; k: Z3、透写【WRITE THROUGH】:在写数据操作时同时将数据写入D-CACHE和二级存储器。这对于保持数据的一致性有好处,代码编写也相对简单。不过它需要消耗更多的写数据时间。当然,下次访问相同内容时还是可以直接从缓存里读取。跟回写相比,算是一种折衷处理办法。# v7 J* p/ z! A" B5 t* W
4、STM32F7片内外各个存储单元的存储属性是通过MPU来配置的。在芯片复位之后,MPU是默认关闭的,此时各存储单元的存储属性遵照如下的默认配置。# j: [4 C. ^2 i/ b/ k( B2 N

  y8 `9 i) r9 [: p( e    好,那什么时候会发生数据一致性问题?: Y* ?6 y5 A8 d& Z4 }$ K5 A
    当有CPU和其它主设备【如DMA】共同访问某可缓存的二级存储器比方SRAM1,同时该存储器又具有回写属性,此时就可能发生数据一致性问题。因为该存储器的回写属性,导致通过CPU欲写入存储器的数据只是缓冲在CACHE里,而没有及时写入存储器。如果此时DMA访问该二级存储器的话,读到的数据可能跟预期不一致。9 g' {3 P. C+ \( z( p7 M
    为了避免数据不一致的问题,我们需要做D-CACHE维护操作。一般有如下四种方法:/ I$ M" N# u! Z$ @! r% f) V* H
1、当对一个可缓存的二级存储器做了写数据操作之后,通过软件对D-CACHE进行清除操作,即运行SCB_CleanDCache()。这样将CACHE里的缓存内容写回到二级存储器,比如把那些DIRTY CACHE行的数据写进SRAM1。
; E0 o. @& f- _) J4 T! L2、通过MPU调整可缓存存储器的存储属性,将其CACHE使用方式改为透写模式。这样保证每次写入CACHE里的内容也同时写入二级存储器,比如写进SRAM1。+ s8 @/ p* |; h  \* s+ B9 O. G. @
3、通过MPU调整可缓存存储器的存储属性,将其共享属性改为可共享的【SHAREABLE】。此后该二级存储器将变为不可缓存。
/ O, Q& W2 L0 C( ?* }4、通过配置CACR寄存器中的D-CACHE位,强制将所有写操作配置为透写属性。1 Q9 Z' X' ?3 M, T8 \: U

  S& t6 D! v9 x0 N    当然,跟上面描述相对应的还有一种情形。那就是DMA更新了可缓存存储器比如SRAM1的数据后,CPU再去读SRAM1,此时也会发生数据不一致的问题。因为CPU此时读的数据还是之前CACHE里的旧数据。为了避免这个问题,保证数据的一致,就得在CPU读SRAM1之前通过软件执行CACHE失效操作,这样保证CPU直接从二级存储器比方SRAM1读取数据。
  k7 h0 D8 P; M5 P6 N' l2 U 3 `) C& E. o# ]+ F$ }
    下面有个关于数据一致性的实例供大家思考。
* K" p: [' T5 ~% L/ A首先CPU从片上FLASH存储块aSRC_Const_Buffer的128字节常量数据拷贝到SRAM1里的一个名为pBuffer的缓存区。
5 @4 a9 E+ `/ f# M然后CPU配置并使能DMA执行从内存到内存的传输,将SRAM1里pBuffer缓存区的数据传输到DTCM  RAM的另一个aDST_Buffer缓存区。
, m3 k' w. F9 \( y  {最后,CPU将aDST_Buffer缓存区的数据与flash存储块aSRC_Const_Buffer的常量数据进行比较是否一致。2 ?2 d/ G: x, ]4 K. P4 z
# O6 Z$ U. @  x# R9 r: ]$ @' x) ?
最后小结下,对于STM32F7系列MCU来说,可能发生数据一致性问题需要的几个因素:
9 O1 S5 H* Z6 k- f1、有CPU和DMA参与数据访问;
6 K, [( f/ y0 n- D9 N) z4 d2、有被CPU和DMA共同访问的可缓存的带回写属性的物理存储块;$ s% p, B' X! @4 x; @7 r$ O
3、开启了D-CACHE;

评分

参与人数 1ST金币 +5 收起 理由
zero99 + 5 赞一个!

查看全部评分

wenyangzeng 回答时间:2017-2-24 21:46:37
好像FSMC驱动TFT也是如此。
酱哒哒 回答时间:2017-2-25 10:19:26
楼主能说说,D-cache具体怎么影响的吗?没遇到过,可以提前留个心
五哥1 回答时间:2017-2-25 13:14:11
这个不懂能详解吗?
zhangxu56726 回答时间:2017-2-25 13:45:57
说明下啊,什么原因?就说解决了
zoomdy 回答时间:2017-2-25 16:23:15
哈哈,用上高档货了,可得好好研究Cache
mark0668 回答时间:2017-2-25 18:42:48
这个也没搞懂,确实有影响
1375854021@qq.c 回答时间:2023-7-22 13:01:35

我也是遇到了这样的问题,我是在做STM32H750VBT6的DMA-ADC采样USB发送的时候遇到的。我是用的按键触发定时器,然后定时外部触发ADC采样,采样结果经过DMA传输进一个Buffer,然后USB发送这个Buffer。我遇到的问题主要是两个,当然是开启D-Cache的时候遇到的。

1,猜到的ADC数据用DMA传输,但是这个Buffer总是传不满。举个例子,在Buffer容量足够的情况下,我ADC和DMA共传输16个数据,结果只有Buffer前两位有数据;传输17个数据,那么Buffer前17位都有数据;传输32个数据,只有Buffer前18个位有数据;传输33个数据,那么Buffer前33个位都有数据。我当时没有想到是D-Cache的问题,只是以为是我DMA配置的问题。然后我在调试的是否发现,我的Buffer基地址是0x240001DC,填数据的时候总是停止到后一个位为0的时候就停止了,然后我突然意识到了难道是这就是原因?我之前也有STM32F103做过,但是就没有这个问题,我有一点点怀疑,但还是尝试直接把Buffer的基地址设置在了0x24000200上。改完之后无论传输多少数据,数据都会正常传输到Buffer之中。

2,虽然我解决了数据传输的问题,但是当我把Buffer的数据利用USB发送到PC上时还是出问题了。我按下按钮,定时器触发ADC采样,然后DMA把数据传到Buffer,然后USB发送,第一次数据发送正常。然而当我第二次按下按钮,Buffer数据不更新,DMA正常传输完成中断,当然USB发送的数据也没有更新。既然DMA正常的传输完成中断,而ADC数据也正常更新,那么按道理Buffer数据也应当正常更新,然后不管我怎么调试,怎么重启DMA,Buffer就是不更新。这是就很蹊跷了,我在网上偶然看到一个帖子,就是说DMA经常有数据不一致的问题,主要是由DCache导致的,我不懂Cache,然后就直接把DCache关掉了,然后一切数据正常。后来我想,问题1也很蹊跷,然后我取消手动指定Buffer的地址,让编译器自动分配在0x240001DC上,数据传输也没问题了,可恶的D-Cache!

本来半天就可以搞定的事情最后花费了两天,看来自己还是对STM32H750不太熟悉,不过也确实学到了很多。

OoO_God 回答时间:2024-8-6 10:51:59
OoO_God 回答时间:2024-8-6 10:52:33

bssz1 发表于 2017-2-26 23:04
转帖,原帖见http://www.51hei.com/bbs/dpj-51303-1.html</p>
<p>

我也服了,你们知道这对于小白来说,多恐怖吗?在做UART+DMA功能,主控板和子板进行交互,网口lwip进行上位机下发数据给主控板,主控板通过串口和dma转发数据给子板.功能代码两周就搞完了,这一个D-cache卡我两周,我给注释掉后就好了,还以为是逻辑代码或者外设初始化有问题,这个东西导致一个月才搞完

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版