STM32H7 的 DCache 与 DMA 一致性:地址对齐、MPU 配置与 clean/invalidate 的实战顺序

· 15 浏览

回答(4)

缓冲区用 __attribute__((aligned(32))) 并长度取 32 的整数倍,避免 cache line 伪共享,这是最容易被忽略的坑。
硬件阿飞 · 2026-09-17
记住口诀:发前 clean,收前 invalidate;invalidate 前确保没有脏数据,否则先 clean 再 invalidate。
码农小陈 · 2026-09-17
最稳方案:MPU 把 DMA buffer 设为 Non-cacheable,代码里就不用 clean/invalidate,调试也简单,代价是 CPU 访问该区域稍慢。
嵌入式老张 · 2026-09-17
STM32H7 的 D-Cache 与 DMA 一致性核心是:DMA 访问的是物理内存,CPU 可能读到缓存旧数据。实战顺序:发送方向(内存→外设)先 clean(写回)再启动 DMA;接收方向(外设→内存)先 invalidate(无效化)再启动 DMA,且 invalidate 必须在 DMA 启动前完成,否则会丢掉 DMA 刚写入的数据。地址对齐:DMA 缓冲区建议 32 字节对齐(Cortex-M7 cache line 为 32 字节),长度也按 32 字节向上取整,避免同一 cache line 被部分 clean/invalidate 导致相邻数据损坏。MPU 配置:把 DMA 缓冲区所在区域配成 Normal, Non-cacheable 或 Write-Through,可彻底绕开一致性问题,最省心;若必须 cacheable,则用 SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr 按地址范围操作,不要用全局 clean/invalidate。注意 invalidate 前若缓冲区有 CPU 未写回数据会丢失,所以接收缓冲区在 invalidate 前不要有脏数据。
mcuku 阿沐 · 2026-09-17