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

开启Cache后UART无法发送新数据

[复制链接]
STMCU小助手 发布时间:2022-11-24 22:00
有人使用STM32H743做产品开发,  DMA 传输待发送的数据到 UART 发送寄存器做后续UART通信。在开启D-Cache的情况下,发现UART没法发送更新过的数据。
具体应用场景是这样的,源数据放在STM32H743片内D1域的AXI-SRAM区,数据会不定期地被CPU修改,然后让DMA将数据传输到USART3的发送寄存器进行后续UART通信。结合手册可以查得USART3位于D2域。
  K/ e) K/ |% ?7 t2 k5 t
微信图片_20221123221811.png
目前开启了D-Cache/I-Cache。我基于现有场景写了一段简单的如下测试代码【编译环境使用STM32CubeIDE】:
__attribute__((section(".Source"))) uint8_t Source[5];
uint32_t  TimeOut;
uint8_t  Variable=0;
, X8 r# W8 l# o( H' a* O
微信图片_20221123221941.png

! C& a( q4 n5 u* z. T7 `
微信图片_20221123221938.png

5 O& p$ S: x) O! V& t$ V! @* l
基于上面测试代码,也重现了相同现象。即尽管CPU在不停修改源端数据,可目的端UART3的TDR寄存器的数据总保持0不变。【注:我这里的DMA使用的Memory to Memory方式,并非要一定这样操作。你完全可以基于UART事件使用Memory to Peripheral的方式。】

  c9 T+ n0 [- l6 O3 C' ?3 v
微信图片_20221123221933.png
, I+ J* T9 w) t1 ~' E& O
这里排除了其它方面的原因,该现象是因为开启了D-Cache并使用write back策略而导致的不同主设备访问同一内存而产生的数据不一致的问题。
现在CPU不时修改AXI-SRAM1指定区域的数据,DMA到同一位置读取数据送到UART发送寄存器。画个图示意下:
" C% Y* {1 k/ W, Z& l& w
微信图片_20221123221925.png

# M/ I) r: P3 J' m. W

& i5 u& l! C5 M6 l/ F7 d
对于STM32H743片内AXI-SRAM1区域,其默认的存储属性为write back及write allocate。【下图来自STM32H7参考手册】
: w& Q8 D; m+ r$ D
微信图片_20221123221919.png

4 C# @+ }" Z$ N  `1 h
此时CPU对该区域进行写操作发生Cache分配,数据会先写到Cache里。要等到Cache重分配或手动刷新Cache时才会将Cache里的新数据写到RAM内存。
这里有三种方案可选用来解决这个问题:
第一种方案就是,CPU做数据更新操作后,对相应存储区执行Cache清除操作,让Cache的新数据及时写到RAM内存,即添加下面打红勾的代码。
* V+ s0 J2 T1 S: U/ i4 v
微信图片_20221123222139.png

0 ?8 R' J7 u8 O6 N1 Z' l
第二种方案就是针对CPU修改的数据存储区进行MPU设置,配置为write through或关闭该区域Cacheable特性。下面将其配置为Write through属性。【下面截图来自ARM相关技术手册。C:Cacheable,B:Bufferable,S:Shareable】
$ K) L. D$ h7 C: d
微信图片_20221123221913.png
* r$ l1 M! I' r" T; g
使用STM32图形化配置工具CubeMx进行MPU相关配置【参见下图】:

' H8 _6 e# s3 T3 @" ^& m4 r+ O  s- O
微信图片_20221123221910.png
2 c% O" y: D" d, B" R0 U
第三种方案,简单粗暴且有效,那就是关闭芯片D-Cache的使用。如果对开启D-Cache不在乎或者只是前期功能调试先关掉无妨,后面再去调整也可以。
上面简单介绍了在开启D-Cache情况下,CPU不定期修改Cacheable内存数据,DMA读取相应内存而发生的数据不一致问题的解决方案,以供参考。
7 e: g( H: ]! m5 U
微信图片_20221123221907.png
& V: s  p3 l' X- _9 g! v) c
最后提醒下,当我们使用SCB_CleanDCache_by_Addr()函数清除Cache时,需注意给定地址要遵循32字节对齐的原则。【注:上面截图来自STM32H7Cube库。】
  i) e0 u0 L9 l
转载自:Miler

5 _9 c' Q6 |  A6 `
收藏 评论0 发布时间:2022-11-24 22:00

举报

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