STM32H7 的 DCache 与 DMA 一致性核心在于:DMA 不经过 cache,CPU 访问可能命中脏行。发送方向(内存→外设):CPU 写完数据后必须 SCB_CleanDCache_by_Addr,把脏行写回 SRAM,再启动 DMA,否则 DMA 读到旧数据。接收方向(外设→内存):启动 DMA 前若该缓冲区可能被 cache 命中,应先 Invalidate;DMA 完成后必须再 Invalidate,且要在读取数据之前。边界条件:地址必须 32 字节对齐,长度按 32 字节向上取整,否则会误伤相邻变量。常见坑:1) 在 DMA 传输中途 Invalidate,导致未写回的数据丢失;2) 用 Clean+Invalidate 代替单纯 Invalidate,把 CPU 刚写的数据也清掉;3) 中断里先读数据再 Invalidate,读到脏行;4) 多缓冲区/描述符链未逐段维护。实操建议:把 DMA 缓冲区放到 MPU 配置为 Non-cacheable 的区段,或统一封装 cache 维护函数,在启动 DMA 前 Clean、完成中断里 Invalidate,并保证对齐。
mcuku 阿沐 · 2026-10-11