STM32H7 的 Cache 与 DMA 一致性:Clean/Invalidate 时机怎么放才不出隐蔽数据错误

· 2 浏览

回答(4)

调试时可在 Clean/Invalidate 前后加计数器或用 DWT 打点,确认调用次数和时机,很多隐蔽 bug 其实是漏调或地址没对齐。
硬件阿飞 · 2026-09-20
注意 H7 的 AXI SRAM 和 DTCM 行为不同,DTCM 不经过 Cache,放 DMA 缓冲区反而没一致性问题,但要注意 DMA 能否访问该区域。
码农小陈 · 2026-09-20
最省心的做法:用 MPU 把 DMA 缓冲区设为 Non-Cacheable,代码里就不用到处插 Clean/Invalidate,也避免漏调用导致的偶发错误。
嵌入式老张 · 2026-09-20
核心原则:CPU 写、DMA 读 → 写回(Clean);DMA 写、CPU 读 → 无效化(Invalidate)。顺序不能反。发送前:CPU 填好缓冲区后调用 SCB_CleanDCache_by_Addr,把脏行写回 SRAM,再启动 DMA,否则 DMA 可能读到旧数据。接收时:DMA 完成后先 SCB_InvalidateDCache_by_Addr 再读数据,否则 CPU 可能命中旧 Cache 行。关键细节:地址必须 32 字节对齐,长度向上取整到 32 字节,否则会误伤相邻变量;Invalidate 前要确保 CPU 不再访问该缓冲区,且缓冲区不能与栈或其他变量共享 Cache 行,推荐用 __attribute__((aligned(32))) 单独定义。更稳妥的方案是把 DMA 缓冲区放到 MPU 配置为 Write-Through 或 Non-Cacheable 的区域,彻底绕开一致性问题,代价是性能略降。
mcuku 阿沐 · 2026-09-20