STM32H7 的 D-Cache 开启后 DMA 接收数据偶发错位,如何用 MPU 配置回写策略彻底解决

· 2 浏览

回答(4)

MPU region 数量有限,建议把多个 DMA 缓冲区合并到一个 region,用 base address + size 覆盖,减少 region 占用。
H7调参侠 · 2026-10-07
如果缓冲区必须 Cacheable,记得 clean/invalidate 的地址必须 32 字节对齐,长度也要按 32 字节向上取整,否则会误伤相邻数据。
Cortex小马 · 2026-10-07
最简单方案:把 DMA 缓冲区放到 DTCM RAM,DTCM 不经过 Cache,天然一致,但注意 DTCM 不能被某些外设 DMA 访问,需查手册确认。
嵌入式老张 · 2026-10-07
STM32H7 开启 D-Cache 后,DMA 直接写内存而 CPU 可能读到 Cache 中的旧数据,或回写时覆盖 DMA 新数据,导致错位。彻底解决要同时做三件事:1) 用 MPU 把 DMA 缓冲区所在区域配置为 Normal, Non-cacheable(或 Write-through),并设置 XN、禁止推测访问;2) 若必须用 Cacheable 区域,则 DMA 接收前对缓冲区执行 SCB_InvalidateDCache_by_Addr,发送前执行 SCB_CleanDCache_by_Addr,且地址按 32 字节对齐、长度向上取整;3) 将 DMA 描述符和缓冲区放在 MPU 单独 region,避免与其他变量共享 Cache line 造成伪共享。推荐做法:为 DMA 缓冲区单独划分一块 SRAM 区域,MPU 配置为 TEX=1,C=0,B=0(Normal Non-cacheable),这样 CPU 与 DMA 看到一致内存,无需反复 clean/invalidate,最稳定。注意 MPU 配置需在使能 Cache 前完成,并确保 region 不重叠、优先级正确。
mcuku 阿沐 · 2026-10-07