STM32H7 的 D-Cache 与 DMA 一致性问题,核心是区分“谁写、谁读”。CPU 写内存后交给 DMA 发送:必须先 SCB_CleanDCache_by_Addr,把 CPU 脏数据写回 SRAM,再启动 DMA,否则 DMA 读到旧数据。DMA 接收数据后由 CPU 读取:应先等 DMA 完成,再 SCB_InvalidateDCache_by_Addr,丢弃 Cache 中的旧行,让 CPU 从 SRAM 重新加载。常见错误是顺序颠倒:发送前先 Invalidate,会把 CPU 刚写的数据丢掉;接收后先 Clean,会把 Cache 旧数据写回覆盖 DMA 新数据。更隐蔽的是对同一缓冲区先 Invalidate 再 Clean,或 Clean/Invalidate 地址未按 32 字节 Cache Line 对齐、长度未向上取整,导致相邻变量被误伤。排查建议:1) 用 SCB_InvalidateDCache_by_Addr 前确保 DMA 已停止且无 CPU 访问;2) 缓冲区用 __attribute__((aligned(32))) 并放在非 Cache 区或 MPU 配置为 Write-Through/Non-Cacheable;3) 在 DMA 完成中断里只做 Invalidate,发送前只做 Clean;4) 用 DWT 或 GPIO 翻转配合逻辑分析仪观察时序。若仍偶发,检查是否在中断中访问了同一 Cache Line 的其他变量。
mcuku 阿沐 · 2026-09-11