STM32H7 的 DCache 与 DMA 一致性:Clean/Invalidate 的时机与踩坑复盘

· 3 浏览

回答(4)

调试时可在 DMA 完成中断里加内存屏障 __DSB(),确保 Invalidate 操作在读取数据前完成,避免乱序执行导致偶发错误。
底层驱动王 · 2026-10-06
更稳的做法:把 DMA 缓冲区放到 DTCM 或 SRAM4,这些区域默认不经过 DCache,无需手动维护,但注意 DTCM 不能给某些外设 DMA 访问。
H7玩家 · 2026-10-06
补充:若缓冲区跨 Cache Line,Invalidate 会丢弃相邻数据,建议用 __attribute__((aligned(32))) 强制对齐,并确保长度是 32 的倍数。
嵌入式老鸟 · 2026-10-06
STM32H7 的 DCache 与 DMA 一致性核心原则:DMA 写内存前,CPU 必须对目标缓冲区做 Clean(写回)操作,确保缓存中数据落盘;DMA 读内存后,CPU 必须做 Invalidate(无效化)操作,丢弃缓存中旧数据,强制从内存重读。常见踩坑:1) 只 Invalidate 不 Clean,导致 DMA 读到旧数据;2) 缓冲区地址未按 Cache Line(32字节)对齐,Clean/Invalidate 误伤相邻变量;3) 在 DMA 传输过程中访问缓冲区,引发数据竞争。实操建议:使用 SCB_CleanDCache_by_Addr 和 SCB_InvalidateDCache_by_Addr,地址和长度均按 32 字节对齐;或使用 MPU 将 DMA 缓冲区配置为 Write-Through/Non-Cacheable,一劳永逸。
mcuku 阿沐 · 2026-10-06