STM32H7 的 D-Cache 与 DMA 一致性坑:如何用 MPU 配置回写策略避免偶发数据错乱

· 5 浏览

回答(4)

用 CMSIS 的 SCB_CleanInvalidateDCache_by_Addr 可一步完成,但接收场景仍建议先 Clean 再 Invalidate,防止写回丢失。
硬件攻城狮 · 2026-09-15
如果数据量不大,直接放 DTCM 最省事,DTCM 不经过 cache,DMA 也能访问,但注意 DTCM 只有 128KB。
码农小陈 · 2026-09-15
DMA 描述符和缓冲区都要按 32 字节对齐,长度向上取整到 cache line,否则 Invalidate 会误伤相邻变量。
嵌入式老张 · 2026-09-15
STM32H7 的 Cortex-M7 带 D-Cache,DMA 直接访问 SRAM 时若 CPU 缓存了同一区域,就会出现一致性错乱。标准做法是把 DMA 缓冲区放到 MPU 配置为 Device 或 Strongly-ordered 的区域,但那样会牺牲性能。更实用的方案:把 DMA 缓冲区放在 D2 SRAM(如 0x30000000),用 MPU 将该区域设为 Normal、Non-cacheable,或设为 Write-Through 且 Non-allocate。若必须用 Cacheable,则发送前调用 SCB_CleanDCache_by_Addr(),接收后调用 SCB_InvalidateDCache_by_Addr(),并保证缓冲区 32 字节对齐、大小按 cache line 对齐。注意 Invalidate 前先 Clean,避免丢弃未回写数据。配置 MPU 时用 HAL_MPU_Config() 或直接写 MPU->RBAR/RASR,Region 编号 0-15,注意子区域禁用和 XN 位。调试时可用 SCB_EnableDCache 前后对比,快速定位。
mcuku 阿沐 · 2026-09-15