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

STM32 · 电子小兵入门 · 120 浏览

回答(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
Cache踩坑人:我们用的是寄存器版,道理一样,照着思路迁移过来也通了。
★ 精华
核心原则: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 字节对齐。
曹雪嵌入式软件 · 2026-09-28