STM32H7 的 D-Cache 与 DMA 共存时,核心矛盾是缓存一致性和对齐。首先,DMA 缓冲区必须按 32 字节对齐(Cortex-M7 缓存行大小),推荐用 `__attribute__((aligned(32)))` 或 `ALIGN_32` 定义,且长度最好为 32 的整数倍,避免同一缓存行被 CPU 和 DMA 同时访问导致数据撕裂。其次,时序要分方向:DMA 接收(外设到内存)前,若 CPU 之前写过该缓冲区,必须先 `SCB_CleanDCache_by_Addr` 把脏数据写回内存,否则 DMA 覆盖后缓存里仍是旧值;DMA 接收完成后,再 `SCB_InvalidateDCache_by_Addr` 丢弃缓存中可能被预取的旧行,让 CPU 读到 DMA 新数据。注意 invalidate 会丢弃未写回数据,所以接收前 clean 是必须的。发送方向则相反:DMA 发送前 clean,发送后无需 invalidate。若使用带 MPU 配置的 non-cacheable 区域,可彻底规避,但会牺牲性能。实操中建议把 DMA 缓冲区放在 D2 SRAM 并配置 MPU 为 write-through 或 non-cacheable,或严格按上述 clean/invalidate 顺序并保证 32 字节对齐。
mcuku 阿沐 · 2026-09-21