STM32H7 的 D-Cache 与 DMA 数据一致性:从 Cache 行对齐到 Clean/Invalidate 的实战排查

· 5 浏览

回答(4)

建议:DMA 缓冲区单独放一个段,链接脚本对齐 32 字节,MPU 设为 Non-Cacheable,省去 Clean/Invalidate 烦恼。
RTOS搬砖工 · 2026-09-19
实测发现:用 HAL_DMA_Start 前先 SCB_CleanDCache_by_Addr,回调里再 SCB_InvalidateDCache_by_Addr,可解决 90% 数据错乱。
STM32小王子 · 2026-09-19
补充:若缓冲区在 AXI SRAM 且 MPU 配为 Write-Through,Clean 可省略,但 Invalidate 仍需在 DMA 接收后执行,且注意 32 字节对齐。
嵌入式老鸟 · 2026-09-19
STM32H7 的 D-Cache 与 DMA 一致性核心是:DMA 操作的内存区域必须保证 Cache 行对齐,且根据数据流向正确执行 Clean/Invalidate。发送(内存→外设)前对源缓冲区执行 Clean(写回),接收(外设→内存)前对目标缓冲区执行 Invalidate(无效化),接收后若 CPU 要读,需再次 Invalidate 或使用非缓存内存。常见坑:1) 缓冲区未按 32 字节对齐,导致相邻变量被误无效化;2) 在 DMA 传输中执行 Invalidate 会丢失未写回数据;3) 使用 DTCM 内存(0x20000000)可绕过 Cache,但 DMA 无法访问,需改用 AXI SRAM 并配置 MPU 为 Write-Through 或 Non-Cacheable。实战排查:先检查 SCB_InvalidateDCache_by_Addr 的地址和长度是否 32 字节对齐,再确认 MPU 配置是否将 DMA 缓冲区设为 Non-Cacheable,最后用 __DSB() 确保操作顺序。推荐对 DMA 缓冲区统一使用 MPU 配置为 Non-Cacheable,可彻底避免一致性问题。
mcuku 阿沐 · 2026-09-19