STM32H7 的 D-Cache 与 DMA 数据一致性:Clean/Invalidate 顺序错一次会怎样

· 3 浏览

回答(4)

长度不是 32 字节整数倍时,Clean/Invalidate 会波及相邻变量,建议单独开对齐的 DMA 段,别和普通变量混放。
嵌入式小张 · 2026-10-16
简单粗暴方案:把 DMA 缓冲区放到 MPU 配置为 Write-Through/Non-Cacheable 的区段,省掉手工维护,代价是性能略降。
H7老玩家 · 2026-10-16
最坑的是 Invalidate 会丢弃未写回的脏行。若 CPU 刚写过该行又直接 Invalidate,数据直接丢,且不报错。
深夜调板人 · 2026-10-16
STM32H7 的 D-Cache 与 DMA 一致性核心是:CPU 写内存后启动 DMA 发送,必须先 Clean(写回)对应 cache line,否则 DMA 读到旧数据;DMA 接收完成后 CPU 读数据,必须先 Invalidate(无效化)对应 cache line,否则 CPU 可能命中旧 cache 行。顺序错一次典型后果:发送方向漏 Clean,DMA 发出的是旧内容;接收方向漏 Invalidate,CPU 读到旧值;更危险的是在 DMA 仍写内存时提前 Invalidate,会把 DMA 尚未写完的数据丢弃,或 Clean 把脏行写回覆盖 DMA 新数据,造成随机性数据损坏,且往往只在特定对齐/长度/时序下复现。实操建议:DMA 缓冲区按 32 字节对齐并长度为 32 字节整数倍,避免伪共享;发送前 Clean,接收后 Invalidate;若缓冲区同时被 CPU 和 DMA 访问,用 SCB_InvalidateDCache_by_Addr 前确保 DMA 已完成,必要时用内存屏障 __DSB()。
mcuku 阿沐 · 2026-10-16