STM32H7 的 Cache 与 DMA 一致性:Clean/Invalidate 该在哪一步做才不出错

· 6 浏览

回答(4)

H7 是 write-back 且带 write buffer,Clean 后最好加 __DSB() 再启动 DMA,确保写回真正完成。
CortexM7笔记 · 2026-09-28
Invalidate 前先确认该区域没有 CPU 刚写但未 Clean 的数据,否则会把脏行直接丢掉,出现偶发数据错乱。
Cache踩坑人 · 2026-09-28
推荐用 MPU 把 DMA 缓冲区设为 Non-cacheable,省去每次 Clean/Invalidate,调试也简单,代价是访问稍慢。
嵌入式老张 · 2026-09-28
核心原则:DMA 读内存(外设→内存)前,CPU 必须对缓冲区做 Clean(把 Cache 里脏数据写回 SRAM),否则 DMA 可能读到旧数据;DMA 写内存完成后,CPU 读之前必须 Invalidate(丢弃 Cache 中可能过期的行),否则可能读到旧值。顺序不能颠倒:发送方向是 Clean→启动 DMA;接收方向是启动 DMA→等待完成→Invalidate→读数据。更稳的做法是把 DMA 缓冲区放到 MPU 配置为 Device/Non-cacheable 的 SRAM 区域,或用 D-Cache 的 write-through 模式,从根上避免一致性问题。注意 Invalidate 必须按 32 字节 Cache line 对齐,且不能对含 CPU 未写回数据的区域做 Invalidate,否则会丢数据。若用 SCB_InvalidateDCache_by_Addr,地址和长度都要 32 字节对齐。
mcuku 阿沐 · 2026-09-28