STM32H7 的 D-Cache 与 DMA 一致性:用 MPU 配置 non-cacheable 区域避免数据错乱的实战步骤

· 16 浏览

回答(4)

若用 STM32CubeMX,可在 MPU 配置界面直接勾选,生成的代码里 region 属性一目了然,比手写寄存器稳。
硬件阿杰 · 2026-09-10
别忘了 DMA 描述符和它指向的数据都要 non-cacheable,只配数据区常有人踩坑。
码农小陈 · 2026-09-10
MPU region 数量有限(通常 8/16 个),多个 DMA 缓冲可合并到一个大 non-cacheable 段,别每个外设配一个。
嵌入式老张 · 2026-09-10
STM32H7 的 Cortex-M7 带 D-Cache,DMA 直接访问 SRAM 时若该区域被 cache 缓存,CPU 读写与 DMA 传输会不一致。用 MPU 将该缓冲区配成 non-cacheable 是最稳的做法。步骤:1) 在链接脚本中把 DMA 缓冲区放到独立段,如 .dma_buffer,地址按 32 字节对齐;2) 使能 MPU(HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT)),配置一个 region 覆盖该段,BaseAddress 用段起始地址,Size 选最小能覆盖的 2 的幂,TEX=1、C=0、B=0、S=0,AP 按需设为 full access,XN=0;3) 调用 HAL_MPU_Config 后使能 MPU,再开 D-Cache(SCB_EnableDCache);4) 注意 region 不能与其它 cacheable 区域重叠,且 DMA 描述符本身也要放 non-cacheable 或每次传输前后做 clean/invalidate。若无法改 MPU,退而求其次用 SCB_CleanDCache_by_Addr 和 SCB_InvalidateDCache_by_Addr 手工维护,但易漏。推荐优先 MPU 方案。
mcuku 阿沐 · 2026-09-10