STM32H7 的 Cache 与 DMA 数据一致性问题:Clean/Invalidate 的边界到底怎么划

· 7 浏览

回答(4)

别忘了 D-Cache 按行 32 字节操作,缓冲区没对齐会连带刷掉邻居变量;用 __attribute__((aligned(32))) 并让长度 32 对齐,能省很多调试时间。
裸机小陈 · 2026-09-23
记住口诀:发前 Clean,收前 Invalidate,收后再 Invalidate。顺序错一个就是偶发数据错乱,而且往往跑几小时才复现。
H7调参侠 · 2026-09-23
最稳的做法:把 DMA 缓冲区放到 MPU 配置为 Non-Cacheable 的 SRAM 区域,彻底不用 Clean/Invalidate,代价是 CPU 访问该区变慢,适合低频小数据量。
嵌入式老张 · 2026-09-23
核心原则:DMA 是总线主设备,它绕过 D-Cache 直接访问 SRAM;CPU 访问的是 Cache。因此一致性维护必须按“数据流向”划分边界。发送方向(CPU 写缓冲→DMA 读):CPU 写完数据后、启动 DMA 前,对缓冲区执行 Clean(写回),把脏行刷到 SRAM,否则 DMA 读到旧数据。接收方向(DMA 写缓冲→CPU 读):启动 DMA 前先 Invalidate 该缓冲区,丢弃可能存在的旧缓存行;DMA 完成中断后再次 Invalidate,再让 CPU 读,否则 CPU 命中旧 Cache 行。注意 Invalidate 会丢弃未写回数据,所以接收缓冲在 DMA 期间 CPU 绝不能碰。实操建议:缓冲区按 32 字节对齐并大小为 32 字节整数倍,避免相邻变量被误刷;用 SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr 按地址范围操作,不要整片 Clean/Invalidate;MPU 可把 DMA 缓冲配为 Write-Through 或 Non-Cacheable 省去维护,但会牺牲 CPU 性能。
mcuku 阿沐 · 2026-09-23