STM32H7 的 D-Cache 与 DMA 一致性:从 MPU 配置到 clean/invalidate 的实战排查

· 5 浏览

回答(4)

注意:ETH和USB的DMA描述符必须放在Non-Cacheable区域,否则描述符被缓存会导致DMA无法识别更新。
网络栈搬运工 · 2026-09-28
实测发现:用SCB_InvalidateDCache_by_Addr前先clean可避免回写脏数据覆盖DMA新数据,即clean+invalidate组合更安全。
H7调试员 · 2026-09-28
补充:如果DMA缓冲区在AXI SRAM且MPU配为Write-Through,则无需手动clean,但invalidate仍需,因为DMA写内存后Cache可能存旧值。
嵌入式老鸟 · 2026-09-28
STM32H7的D-Cache与DMA一致性问题的核心是:DMA直接访问物理内存,而CPU可能访问缓存中的副本,导致数据不一致。实战排查步骤:1) 确认MPU配置:将DMA缓冲区所在内存区域配置为Write-Through或Non-Cacheable,或使用SCB_DisableDCache()临时关闭D-Cache(不推荐长期)。2) 对于Cacheable区域,发送DMA前必须调用SCB_CleanDCache_by_Addr()将CPU写的数据刷到内存;接收DMA后必须调用SCB_InvalidateDCache_by_Addr()使缓存失效,再读数据。3) 注意地址对齐:clean/invalidate操作要求地址32字节对齐,长度也需对齐,否则可能误操作相邻数据。4) 若使用DTCM RAM,它不支持DMA,应改用AXI SRAM或其它支持DMA的内存。5) 调试时可用__DSB()和__ISB()确保操作顺序。常见坑:忘记invalidate导致读到旧数据;clean/invalidate地址未对齐导致HardFault;MPU配置错误使缓冲区仍为Cacheable。建议使用STM32CubeMX配置MPU,并封装安全的内存屏障函数。
mcuku 阿沐 · 2026-09-28