STM32H7 的 Cache 与 DMA 数据一致性:Clean/Invalidate 的典型误用与排查方法

· 3 浏览

回答(4)

排查时先确认缓冲区地址和长度是否 32 字节对齐,再检查 DMA 是否访问了 DTCM。DTCM 不经过 Cache,放那里最安全,但注意总线带宽限制。
寄存器搬运工 · 2026-09-13
建议用 MPU 把 DMA 缓冲区设为 Non-Cacheable,虽然损失一点性能,但能彻底避免 Clean/Invalidate 时序问题,调试期尤其省心。
H7调参侠 · 2026-09-13
最容易被忽略的是接收缓冲区若被 CPU 写过,Invalidate 前必须先 Clean,否则 Cache 里的脏数据被直接丢弃,DMA 写入的内容反而被覆盖。
嵌入式老白 · 2026-09-13
STM32H7 的 D-Cache 与 DMA 协同工作,核心原则是:CPU 写、DMA 读(发送)前必须 Clean;DMA 写、CPU 读(接收)前必须 Invalidate。典型误用有三类:一是接收时只 Invalidate 不 Clean,若该缓冲区之前被 CPU 写过,Invalidate 会丢弃未写回的数据;二是 Invalidate 粒度不对,按字节或非 32 字节对齐操作,导致相邻变量被误清;三是 DMA 描述符或缓冲区跨越 Cache Line(H7 为 32 字节),造成数据踩踏。排查方法:先用 SCB_InvalidateDCache_by_Addr 前确保地址 32 字节对齐、长度按 32 字节向上取整;接收流程严格按“Clean 旧数据→Invalidate→启动 DMA→等待完成→Invalidate→读数据”;若仍异常,可临时关闭 D-Cache 验证,或用 MPU 将 DMA 缓冲区配置为 Write-Through/Non-Cacheable。注意 H7 的 AXI SRAM 与 DTCM 行为不同,DTCM 不经过 Cache,可直接 DMA 访问。
mcuku 阿沐 · 2026-09-13