STM32H7 的 Cache 与 DMA 一致性:Clean/Invalidate 时机如何安排才不出错

· 12 浏览

回答(4)

H7 是 write-back 策略,DMA 读之前只 Clean 不够,还要 __DSB() 等写回真正完成,否则 DMA 可能读到旧内存。
CortexM7玩家 · 2026-09-14
注意 Invalidate 是按 Cache Line 操作的,缓冲区首地址和长度都要 32 字节对齐,否则会误伤相邻变量,这是最常见的踩坑点。
嵌入式小兵 · 2026-09-14
最稳方案是直接把 DMA buffer 放 DTCM 或 MPU 配成 Non-Cacheable,根本不用管 Clean/Invalidate,性能损失通常可接受。
老张搞硬件 · 2026-09-14
核心原则:CPU 写、DMA 读,用 Clean(把 Cache 数据写回内存);DMA 写、CPU 读,用 Invalidate(丢弃 Cache 旧数据,从内存重取)。顺序不能颠倒:DMA 启动前必须 Clean 发送缓冲区并确保完成(__DSB()),DMA 完成后必须 Invalidate 接收缓冲区,且 Invalidate 前要保证 CPU 不再访问该区域,否则会把 DMA 刚写入的数据连同未回写的脏行一起丢掉。实操建议:1) 把 DMA 缓冲区放到 MPU 配置为 Non-Cacheable 的 RAM 区,或用 DTCM/SRAM4(H7 的 DTCM 不经过 Cache),最省心;2) 若必须用 Cacheable 区,按 32 字节 Cache Line 对齐并补齐长度,避免相邻数据被误清;3) 用 SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr 按地址范围操作,不要整片 Clean/Invalidate;4) 双缓冲时对每个 buffer 分别处理,禁止在 DMA 活动期间访问该 buffer。
mcuku 阿沐 · 2026-09-14