STM32H7 的 D-Cache 开启后 DMA 收发数据错位,如何用 MPU 配置回写策略而不整体关 Cache

· 3 浏览

回答(4)

如果用了 Ethernet 或 SDMMC 的 IDMA,注意它们有自己的 cache 维护要求,MPU 配好后仍要在回调里手动 clean/invalidate。
H7搬砖工 · 2026-10-13
别忘了 DMA 描述符和缓冲区都要对齐 32 字节,否则 SCB_CleanDCache_by_Addr 会误伤相邻数据,这是最常见的错位元凶。
Cortex小王子 · 2026-10-13
Write-Through 会降低 CPU 写性能,若缓冲区只用于 DMA 收发、CPU 很少写,直接配 Non-Cacheable 更省心,避免 clean/invalidate 时序坑。
嵌入式老张 · 2026-10-13
STM32H7 的 D-Cache 与 DMA 一致性问题的核心是:DMA 直接访问物理内存,而 CPU 可能读到 Cache 中的旧数据或写数据只停留在 Cache 未回写到内存。正确做法是用 MPU 把 DMA 缓冲区所在内存区域配置为 Write-Through(透写)或 Non-Cacheable,而不是全局关 Cache。 推荐配置:在 MPU 中为该 SRAM 区域建立 region,设置 TEX=0、C=1、B=0(Write-Through, no write allocate),或直接 C=0、B=0(Non-Cacheable)。同时设置 XN=0、AP=Full Access、S=1。 若坚持用 Write-Back,则必须在 DMA 发送前调用 SCB_CleanDCache_by_Addr() 回写,接收后调用 SCB_InvalidateDCache_by_Addr() 无效化,且地址必须 32 字节对齐。 实操建议:DMA 缓冲区单独放在 D2 SRAM 并做 32 字节对齐,MPU region 大小按 2 的幂次覆盖,配置后调用 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT)。注意 MPU 配置必须在使能 Cache 前完成,否则需先关中断再重配。
mcuku 阿沐 · 2026-10-13