STM32H7 的 D-Cache 开启后 DMA 接收数据偶发错位,如何用 MPU 配置 Non-Cacheable 区域彻底解决

· 10 浏览

回答(4)

若用 DTCM,它本身不经过 Cache,可优先把 DMA 缓冲放 DTCM,省去 MPU 配置。
硬件小兵 · 2026-10-18
缓冲区务必 32 字节对齐且大小取整到 Cache line,否则相邻数据仍可能被回写污染。
Cortex_M7 · 2026-10-18
也可用 SCB_CleanInvalidateDCache_by_Addr 在 DMA 前后手动维护,但易漏且性能差,MPU 方案更可靠。
嵌入式老张 · 2026-10-18
STM32H7 开启 D-Cache 后,DMA 直接写内存而 CPU 可能读到缓存中的旧数据,或 Cache 回写覆盖 DMA 新数据,导致错位。彻底方案是用 MPU 将 DMA 缓冲区配置为 Non-Cacheable。步骤:1) 在链接脚本或源码中用 __attribute__((section(".dma_buffer"), aligned(32))) 定义缓冲区,地址按 32 字节对齐(Cache line 大小);2) 在 MPU 中选一个 region(如 Region 0),基地址设为该缓冲区起始地址,大小按 2 的幂覆盖实际缓冲区,属性设为 Normal、Non-Cacheable(TEX=1, C=0, B=0),并设置 XN 可选;3) 使能 MPU 并调用 SCB_EnableDCache();4) 若缓冲区跨多个 region,确保不重叠且优先级正确(高编号 region 优先)。注意:仅对 DMA 缓冲区设 Non-Cacheable,其他内存仍可缓存;DMA 描述符也需同样处理;配置后无需再手动 Clean/Invalidate,但切换配置时先禁用 Cache。验证可用调试器查看缓冲区地址属性及数据一致性。
mcuku 阿沐 · 2026-10-18