STM32H7 的 D-Cache 与 DMA 同存时如何避免数据一致性踩坑:MPU 配置与 clean/invalidate 的实战顺序

· 4 浏览

回答(4)

推荐用 SCB_InvalidateDCache_by_Addr 和 SCB_CleanDCache_by_Addr,不要用全量 clean/invalidate,否则中断延迟和性能都很差。
Cortex-M7玩家 · 2026-10-10
如果 DMA 缓冲区在 DTCM,它本身不经过 D-Cache,无需 clean/invalidate,但注意 DTCM 不能被某些 DMA 控制器访问。
STM32搬砖工 · 2026-10-10
补充:H7 的 Cache 行是 32 字节,invalidate 时长度要向上取整到行边界,否则可能清掉相邻变量导致玄学 bug。
嵌入式老鸟 · 2026-10-10
STM32H7 的 D-Cache 与 DMA 共存时,核心原则:DMA 访问的内存区域必须保证 Cache 与内存一致。推荐做法:1) 用 MPU 将 DMA 缓冲区配置为 Write-Through 或 Non-Cacheable(如 TEX=0,C=0,B=0 或 TEX=0,C=1,B=0),避免手动维护;2) 若必须用 Cacheable 区域,则严格按方向操作:CPU 写、DMA 读(发送)前,先 clean(回写)该缓冲区,确保内存数据最新;DMA 写、CPU 读(接收)前,先 invalidate(无效化)该缓冲区,防止 CPU 读到旧 Cache 行;3) 顺序不能颠倒:发送是 clean 后启动 DMA;接收是 DMA 完成中断里先 invalidate 再读数据。4) 注意 invalidate 会丢弃未回写数据,所以接收缓冲区在 DMA 期间 CPU 不应写。5) 缓冲区地址和长度需按 Cache 行(32 字节)对齐,避免误伤相邻数据。实战中优先用 MPU 配置 Non-Cacheable 区域最省心,性能敏感再考虑 clean/invalidate 方案。
mcuku 阿沐 · 2026-10-10