STM32H7 的 D-Cache 开启后 DMA 收发数据错乱:地址对齐与 clean/invalidate 时序怎么排

· 1 浏览

回答(4)

H7 的 AXI SRAM 默认 Cacheable,DMA 访问它容易出问题;用 D2 SRAM 或加 MPU 区域,比反复调 Cache 维护函数可靠得多。
STM32调参侠 · 2026-10-14
关键点:invalidate 只应在 DMA 接收完成后做,且必须按 32 字节对齐;发送前 clean 别漏,否则 DMA 读到旧数据。
CortexM7玩家 · 2026-10-14
我一般直接把 DMA 缓冲放到 D2 SRAM 并配 MPU 为 Non-Cacheable,省去 clean/invalidate,实测最稳,性能损失可接受。
嵌入式老张 · 2026-10-14
STM32H7 的 D-Cache 与 DMA 共存必须遵守两条铁律:缓冲区地址按 Cache Line(Cortex-M7 为 32 字节)对齐,且长度补齐到 32 字节整数倍;否则 clean/invalidate 会误伤相邻数据。时序上要区分方向:DMA 发送(内存→外设)前,先对缓冲区做 SCB_CleanDCache_by_Addr,把 CPU 写的数据刷到 SRAM,再启动 DMA;DMA 接收(外设→内存)时,启动 DMA 前先 SCB_InvalidateDCache_by_Addr 使缓存行失效,DMA 完成后再次 invalidate,然后 CPU 才能读。注意不要在 DMA 传输中途 invalidate,否则可能丢弃 DMA 已写入但尚未回写的数据。推荐把 DMA 缓冲区放到 MPU 配置为 Non-Cacheable 的 SRAM 区域(如 D2 SRAM 或通过 MPU 设置),从根上避免维护开销;若必须用 Cacheable 内存,务必用 __attribute__((aligned(32))) 并封装 clean/invalidate 函数,同时保证 DMA 描述符和缓冲区不跨 Cache Line。
mcuku 阿沐 · 2026-10-14