0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

茶话MCU 来源:茶话MCU 作者:茶话MCU 2022-11-23 09:02 次阅读

有人使用STM32H743做产品开发, DMA 传输待发送的数据到 UART 发送寄存器做后续UART通信。在开启D-Cache的情况下,发现UART没法发送更新过的数据。

具体应用场景是这样的,源数据放在STM32H743片内D1域的AXI-SRAM区,数据会不定期地被CPU修改,然后让DMA将数据传输到USART3的发送寄存器进行后续UART通信。结合手册可以查得USART3位于D2域。[下面截图来自STM32H7芯片参考手册]

6957715a-6ac4-11ed-8abf-dac502259ad0.png

目前开启了D-Cache/I-Cache。我基于现有场景写了一段简单的如下测试代码【编译环境使用STM32CubeIDE】:

__attribute__((section(".Source"))) uint8_t Source[5];

uint32_t TimeOut;

uint8_t Variable=0;

696d97c8-6ac4-11ed-8abf-dac502259ad0.png

6987d1e2-6ac4-11ed-8abf-dac502259ad0.png

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

699cf540-6ac4-11ed-8abf-dac502259ad0.png

这里排除了其它方面的原因,该现象是因为开启了D-Cache并使用write back策略而导致的不同主设备访问同一内存而产生的数据不一致的问题。

现在CPU不时修改AXI-SRAM1指定区域的数据,DMA到同一位置读取数据送到UART发送寄存器。画个图示意下:

69bd7888-6ac4-11ed-8abf-dac502259ad0.png

对于STM32H743片内AXI-SRAM1区域,其默认的存储属性为write back及writeallocate。【下图来自STM32H7参考手册】

69d5228a-6ac4-11ed-8abf-dac502259ad0.png

此时CPU对该区域进行写操作发生Cache分配,数据会先写到Cache里。要等到Cache重分配或手动刷新Cache时才会将Cache里的新数据写到RAM内存。

这里有三种方案可选用来解决这个问题:

第一种方案就是,CPU做数据更新操作后,对相应存储区执行Cache清除操作,让Cache的新数据及时写到RAM内存,即添加下面打红勾的代码。

69faf514-6ac4-11ed-8abf-dac502259ad0.png

第二种方案就是针对CPU修改的数据存储区进行MPU设置,配置为write through或关闭该区域Cacheable特性。下面将其配置为Writethrough属性。【下面截图来自ARM相关技术手册。C:Cacheable,B:Bufferable,S:Shareable】

6a1bc596-6ac4-11ed-8abf-dac502259ad0.png

使用STM32图形化配置工具CubeMx进行MPU相关配置【参见下图】:

6a36452e-6ac4-11ed-8abf-dac502259ad0.png

第三种方案,简单粗暴且有效,那就是关闭芯片D-Cache的使用。如果对开启D-Cache不在乎或者只是前期功能调试先关掉无妨,后面再去调整也可以。

上面简单介绍了在开启D-Cache情况下,CPU不定期修改Cacheable内存数据,DMA读取相应内存而发生的数据不一致问题的解决方案,以供参考。

6a5e537a-6ac4-11ed-8abf-dac502259ad0.png

最后提醒下,当我们使用SCB_CleanDCache_by_Addr()函数清除Cache时,需注意给定地址要遵循32字节对齐的原则。【注:上面截图来自STM32H7Cube库。】

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Cache
    +关注

    关注

    0

    文章

    127

    浏览量

    27978
  • uart
    +关注

    关注

    22

    文章

    1159

    浏览量

    99954
  • dma
    dma
    +关注

    关注

    3

    文章

    535

    浏览量

    99018
  • STM32H743
    +关注

    关注

    0

    文章

    24

    浏览量

    1349

原文标题:开启Cache后UART无法发送新数据

文章出处:【微信号:stmcu832,微信公众号:茶话MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32h7开启Cache,串口发送DMA会导致中断触发如何解决?

    STM32h7 开启Cache,串口使用发送DMA发送数据会导致中断触发(只
    发表于 03-12 07:37

    cc2530为什么在休眠唤醒无法发送数据

    cc2530为什么在休眠唤醒无法发送数据?contiki系统cc2530上循环间断发送数据,每
    发表于 03-30 15:10

    程序是将ADC采集的数据和串口接收的数据通过ble蓝牙发送出去,请问为什么打开uart找不到搜索蓝牙?如何解决?

    我写的程序是将ADC采集的数据和串口接收的数据通过ble蓝牙发送出去,不知道为什么,打开uart,手机
    发表于 06-29 16:27

    UART3不会发送数据

    我正在使用UART3进行RS-485通信(我在PC和电路板之间连接了B& B RS-232到RS-485转换器)。麻烦的是UART3不会“发送数据,除非我在通过
    发表于 04-30 14:55

    怎么用UART发送和接收数据

    你好。我这里有几个RN4871。我对它们很感兴趣,因为我可以完全替换MCU,直接使用RN4871,运行脚本。改变名称和波特率没问题。现在我需要能够用UART发送和接收数据。用户点击电话应用程序中
    发表于 04-20 10:07

    am335x裸机开启mmu和cache,ucos2任务不能调度如何排查?

    beaglebone 开启mmu和cache,ucos2卡在 OSStartHighRdy,无法调度任务,请问如何排查?
    发表于 01-12 06:41

    CH552 UART0无法发送是为什么?如何处理?

    CH552 UART0无法发送,按照ADC范例改了下,依然不行;代码如下:求解惑#include "..\Public\CH554.H"#include "
    发表于 06-02 07:22

    CH573 TMOS开启sleep串口异常怎么解决?

    使用例程包BLE-UART工程修改未开启sleep前UART0_SendString(PS, 12),串口0发送数据正常不丢
    发表于 09-07 07:19

    CH579M开启数据发送中断,进入不了怎么解决?

    串口发送中断,串口接收到数据开启发送中断,第一次可以进入中断发送数据;再接收数据
    发表于 09-19 09:33

    UART 发送数据丢失最后一个字节

    STM32 UART 发送数据丢失最后一个字节
    发表于 12-04 15:10 0次下载

    UART需要使用DMA发送吗 ?

    UART需要使用DMA发送吗?
    的头像 发表于 03-07 16:57 6599次阅读

    如何根据UART传输协议将数据发送出去呢?

    和接收部分相反,UART发送数据部分是CPU将需要发送数据写到发送
    的头像 发表于 06-05 15:59 1822次阅读
    如何根据<b class='flag-5'>UART</b>传输协议将<b class='flag-5'>数据</b><b class='flag-5'>发送</b>出去呢?

    UART发送数据丢失最后一个字节

    电子发烧友网站提供《UART发送数据丢失最后一个字节.pdf》资料免费下载
    发表于 08-01 17:57 1次下载
    <b class='flag-5'>UART</b><b class='flag-5'>发送</b><b class='flag-5'>数据</b>丢失最后一个字节

    UART数据帧与发送

    时,它保持在高电压电平。为了开始数据传输,发送 UART数据线从高电平拉到低电平(从 1 到 0)。接收 UART
    的头像 发表于 11-09 17:42 349次阅读

    GD32F103C8T6 Uart3无法发送数据

    以用来实现与其他外设或者外部设备的数据交互。 然而,在一些情况下,用户可能会遇到UART3无法发送数据的问题。在接下来的文章中,我们将深入探
    的头像 发表于 01-09 10:57 490次阅读