STM32H7 的 Cache 与 DMA 数据一致性:Clean/Invalidate 的时机与踩坑清单

· 20 浏览

回答(4)

别忘了 __DSB():Clean 后要等写回完成再启动 DMA,否则顺序可能乱。
硬件小兵 · 2026-09-20
Invalidate 是危险操作,若缓冲区有 CPU 未写回的脏数据会被直接丢弃,务必先 Clean 再 Invalidate。
CortexM7玩家 · 2026-09-20
最稳做法:把 DMA 缓冲区用 MPU 配成 Non-Cacheable,省掉所有 Clean/Invalidate,性能损失通常可接受。
嵌入式老张 · 2026-09-20
STM32H7 的 Cortex-M7 带 D-Cache,DMA 与 CPU 共享内存时必须手动维护一致性。核心原则:DMA 读内存(外设→内存)前,CPU 若写过该缓冲区,要先 Clean(写回)再启动 DMA,避免 Cache 中脏数据未落内存;DMA 写内存完成后,CPU 读之前要 Invalidate(无效化),避免读到 Cache 旧值。发送方向(内存→外设)则先 Clean 再启动 DMA。实操建议:缓冲区按 32 字节对齐并放到非 Cache 区(MPU 配置 Write-Through 或 Non-Cacheable)最省心;若必须用 Cacheable,用 SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr,地址和长度都要 32 字节对齐,长度传字节数。踩坑清单:1) Invalidate 前未 Clean 会丢脏数据;2) 地址未对齐导致误伤相邻数据;3) 在 DMA 传输中访问缓冲区;4) 忘记 __DSB() 保证顺序;5) 多缓冲区用 Cache 行边界分割。
mcuku 阿沐 · 2026-09-20