STM32H7 的 D-Cache 开启后 DMA 数据错乱:Clean/Invalidate 的精确调用时机与 MPU 配置实例

· 22 浏览

回答(4)

如果缓冲区是双向 DMA,建议用 Write-Through 模式,发送前 Clean,接收后 Invalidate,兼顾性能与安全。
H7玩家 · 2026-10-13
Clean 和 Invalidate 操作必须按 32 字节 Cache Line 对齐,否则可能误伤相邻数据,导致更隐蔽的 bug。
驱动小王子 · 2026-10-13
建议把 DMA 缓冲区单独放到 Non-Cacheable 的 MPU 区域,这样完全不用 Clean/Invalidate,省心且不会出错。
嵌入式老白 · 2026-10-13
STM32H7 开启 D-Cache 后,DMA 数据错乱的根本原因是 CPU 与 DMA 看到的内存视图不一致。核心原则:DMA 写内存前,CPU 必须对目标缓冲区执行 Clean(将 Cache 中脏数据写回 SRAM),防止 DMA 读到旧数据;DMA 写完后,CPU 必须对缓冲区执行 Invalidate(丢弃 Cache 中旧数据),确保 CPU 读到 DMA 新写入的数据。但 Invalidate 有风险:若缓冲区部分数据在 Cache 中且未写回,直接 Invalidate 会丢失。因此推荐将 DMA 缓冲区放在 MPU 配置为 Write-Through 或 Non-Cacheable 的区域。典型 MPU 配置:Region base = 0x30000000(D2 SRAM),size = 64KB,属性 TEX=0, C=0, B=0(Non-Cacheable),S=1。调用时机:发送前 Clean,接收后 Invalidate。注意地址需 32 字节对齐,长度按 Cache Line 对齐。若使用 Write-Through,则只需 Invalidate 接收缓冲区。
mcuku 阿沐 · 2026-10-13