STM32H7 的 D-Cache 与 DMA 共存时,如何用 MPU 配置实现零拷贝且避免数据一致性错误

· 行业用户 · 7 浏览

回答(5)

调试时建议用 MPU 的 MemManage fault 监控越界访问,并确认 SCB->CCR 的 DC 位状态,避免误以为 cache 已关。
STM32老兵 · 2026-10-31
如果数据量大且要 cache 加速,可用双缓冲加手动 clean/invalidate,配合 __DSB() 和 __DMB() 保证顺序,但这就不是严格零拷贝了。
Cortex_M7 · 2026-10-31
别忘了 DMA 描述符本身也要放 Non-cacheable 区,很多人只配了数据缓冲,结果描述符被 cache 住导致 DMA 读到旧值。
嵌入式小刘 · 2026-10-31
补充一点:AXI SRAM 默认是 cacheable 的,若用 D2 SRAM 做 DMA 缓冲,注意 D2 域时钟和总线矩阵访问延迟,高频 DMA 下性能可能不如 AXI SRAM 配 Non-cacheable 属性。
硬件老张 · 2026-10-31
核心原则:DMA 缓冲区必须放在 MPU 配置为 Device 或 Strongly-ordered 的内存区,或使用 Non-cacheable 属性,从而彻底绕开 D-Cache 一致性问题,实现零拷贝。具体做法:在链接脚本中划出一段专用 SRAM(如 D2 SRAM 或 AXI SRAM 的固定区域),MPU 对该区域配置 TEX=1、C=0、B=0(Normal Non-cacheable),或 TEX=0、C=0、B=1(Shareable Device)。DMA 描述符和缓冲区都放在此区,CPU 与 DMA 直接读写同一地址,无需 cache clean/invalidate,也无需 memcpy。注意:1) 区域大小按 32 字节对齐,避免与相邻 cacheable 区共享 cache line;2) 若必须用 cacheable 区,则需在 DMA 前 clean、DMA 后 invalidate,且缓冲区按 cache line(32B)对齐并留 padding;3) 配置 MPU 后需调用 SCB_EnableDCache 前完成,运行中改属性要先 disable cache。推荐优先用 Non-cacheable 专用区方案,最稳且真正零拷贝。
mcuku 阿沐 · 2026-10-31