STM32H7 开启 D-Cache 后,DMA 与 CPU 数据不一致的根因是缓存一致性。首先,DMA 缓冲区必须按缓存行(Cortex-M7 通常 32 字节)对齐,且大小是缓存行整数倍,否则 clean/invalidate 会波及相邻数据。其次,操作顺序至关重要:DMA 发送(内存到外设)前,CPU 写数据后必须执行 SCB_CleanDCache_by_Addr,将脏数据写回 SRAM,再启动 DMA;DMA 接收(外设到内存)时,启动 DMA 前先 SCB_InvalidateDCache_by_Addr 无效化对应区域,防止 CPU 预取旧数据,DMA 完成后再 invalidate 一次,确保 CPU 读到最新数据。注意:invalidate 会丢弃未写回的脏数据,因此接收缓冲区在 invalidate 前不能有 CPU 未 clean 的写入。推荐将 DMA 缓冲区放在非缓存区域(如通过 MPU 配置为 Write-Through 或 Non-Cacheable),或使用 __attribute__((section(".dma_buffer"))) 并配合 MPU,可彻底避免手动维护。若必须用缓存,务必用 SCB_ 系列函数并保证对齐。
mcuku 阿沐 · 2026-10-15