有人使用stm32h743做产品开发, dma 传输待发送的数据到 uart 发送寄存器做后续uart通信。在开启d-cache的情况下,发现uart没法发送更新过的数据。
具体应用场景是这样的,源数据放在stm32h743片内d1域的axi-sram区,数据会不定期地被cpu修改,然后让dma将数据传输到usart3的发送寄存器进行后续uart通信。结合手册可以查得usart3位于d2域。[下面截图来自stm32h7芯片参考手册]
目前开启了d-cache/i-cache。我基于现有场景写了一段简单的如下测试代码【编译环境使用stm32cubeide】:
__attribute__((section(.source))) uint8_t source[5];
uint32_t timeout;
uint8_t variable=0;
基于上面测试代码,也重现了相同现象。即尽管cpu在不停修改源端数据,可目的端uart3的tdr寄存器的数据总保持0不变。【注:我这里的dma使用的memory to memory方式,并非要一定这样操作。你完全可以基于uart事件使用memory to peripheral的方式。】
这里排除了其它方面的原因,该现象是因为开启了d-cache并使用write back策略而导致的不同主设备访问同一内存而产生的数据不一致的问题。
现在cpu不时修改axi-sram1指定区域的数据,dma到同一位置读取数据送到uart发送寄存器。画个图示意下:
对于stm32h743片内axi-sram1区域,其默认的存储属性为write back及writeallocate。【下图来自stm32h7参考手册】
此时cpu对该区域进行写操作发生cache分配,数据会先写到cache里。要等到cache重分配或手动刷新cache时才会将cache里的新数据写到ram内存。
这里有三种方案可选用来解决这个问题:
第一种方案就是,cpu做数据更新操作后,对相应存储区执行cache清除操作,让cache的新数据及时写到ram内存,即添加下面打红勾的代码。
第二种方案就是针对cpu修改的数据存储区进行mpu设置,配置为write through或关闭该区域cacheable特性。下面将其配置为writethrough属性。【下面截图来自arm相关技术手册。c:cacheable,b:bufferable,s:shareable】
使用stm32图形化配置工具cubemx进行mpu相关配置【参见下图】:
第三种方案,简单粗暴且有效,那就是关闭芯片d-cache的使用。如果对开启d-cache不在乎或者只是前期功能调试先关掉无妨,后面再去调整也可以。
上面简单介绍了在开启d-cache情况下,cpu不定期修改cacheable内存数据,dma读取相应内存而发生的数据不一致问题的解决方案,以供参考。
最后提醒下,当我们使用scb_cleandcache_by_addr()函数清除cache时,需注意给定地址要遵循32字节对齐的原则。【注:上面截图来自stm32h7cube库。】
内存超频有什么用 实测超频对游戏的影响
优博终端基于RK3568工控开发板通过OpenHarmony兼容性测评
如何提高示波器测量准确度,有哪些实现方法
太阳能板的工作原理是什么
STM32L152和S14432的无线网络系统设计
开启Cache后UART无法发送新数据
直流源表的四象限是如何工作的?典型应用是哪些?
ColorOS7预告片公布 或在本月正式亮相
田间小气候监测站的简单说明
SIMATIC S7-1500 PLC计算指令(CALCULATE)简述
闪存阵列如何处理“写断崖”和“垃圾回收”
适用于多平台应用的Kotlin编程语言
RK3288主板的CPU主频最大是多少
华为P10售价曝光:华为P10相比上一代P9只涨价11元,值不值这个价?
如何正确使用二极管的导通压降
LED显示屏的防雷措施有哪些?
模拟IC设计之OP带宽的计算方法
带刹车减速电机刹车打不开怎么办?
从手动到全自动:锡膏印刷机的进化史
专访波士顿动力 CEO:要做机器人界的 Android,对赚钱也感兴趣