STM32H7 的 D-Cache 与 DMA 冲突导致数据错乱:如何用 MPU 配置 Non-Cacheable 区域并验证一致性

· 3 浏览

回答(4)

如果缓冲区小于 32 字节,Invalidate 会误伤相邻数据,最好按 cache line 对齐并整行操作,或直接放 Non-Cacheable 区。
硬件阿伟 · 2026-09-22
验证时建议用双缓冲加内存屏障 __DSB(),并在 DMA 完成中断里只做标志位,避免中断中访问未同步的 Cache 数据。
码农小何 · 2026-09-22
补充一点:H7 的 AXI SRAM 默认是 Cacheable,若 DMA 访问同一块内存,必须 MPU 配置或手动维护 Cache,二者不能混用。
嵌入式老张 · 2026-09-22
STM32H7 的 D-Cache 与 DMA 冲突本质是 Cache 与内存视图不一致:CPU 写数据可能停留在 Cache 未回写,DMA 读到旧数据;DMA 写入后 CPU 又可能命中旧 Cache 行。最稳妥方案是用 MPU 将 DMA 缓冲区配置为 Non-Cacheable。步骤:1) 在链接脚本或源码中把 DMA buffer 放到独立段,如 .dma_buffer,地址按 32 字节对齐;2) 在 MPU 中选一个 region,BaseAddress 指向该段,Size 覆盖缓冲区,AP 设为 Full Access,TEX=1、C=0、B=0,S=0,即 Normal Non-Cacheable;3) 使能 MPU 和 D-Cache,注意 region 编号与优先级,避免与其他 region 重叠;4) 若必须用 Cacheable 内存,则 DMA 发送前调用 SCB_CleanDCache_by_Addr,接收后调用 SCB_InvalidateDCache_by_Addr,且地址 32 字节对齐、长度按 cache line 对齐。验证方法:写固定模式数据后触发 DMA,比较内存与预期;用调试器查看 MPU 寄存器、Cache 命中情况;也可临时关闭 D-Cache 对比结果。注意 DMA 描述符和缓冲区都要处理,避免只处理数据区而漏掉描述符。
mcuku 阿沐 · 2026-09-22