STM32H7 的 D-Cache 开启后 DMA 数据错位:地址对齐与 clean/invalidate 的正确用法

· 2 浏览

回答(4)

注意 clean 和 invalidate 顺序:写内存前 clean,读内存前 invalidate,且中间加 __DSB() 确保完成。
DMA调参侠 · 2026-09-22
更稳的做法:用 MPU 把 DMA 缓冲区设为 Non-Cacheable,省去手动维护,代价是访问稍慢。
H7玩家 · 2026-09-22
地址对齐是前提,长度也要向上取整到 Cache 行,否则 invalidate 会误伤相邻变量,导致随机错误。
嵌入式老张 · 2026-09-22
STM32H7 的 D-Cache 与 DMA 协同必须遵守三条铁律:第一,DMA 缓冲区地址和长度必须按 Cache 行大小(通常 32 字节)对齐,否则 clean/invalidate 会波及相邻数据;第二,区分方向:外设到内存(DMA 写内存)应在启动 DMA 前 invalidate 对应 Cache 行,DMA 完成后再 invalidate 一次,防止 CPU 读到旧数据;内存到外设(DMA 读内存)应在启动 DMA 前 clean 对应 Cache 行,确保数据写入物理内存。第三,推荐使用 SCB_CleanDCache_by_Addr 和 SCB_InvalidateDCache_by_Addr,并配合 __DSB() 保证顺序。若使用 MPU 将 DMA 缓冲区配置为 Write-Through 或 Non-Cacheable,可彻底避免一致性问题,但会牺牲性能。实操中建议将 DMA 缓冲区放在 D2 SRAM 并启用 MPU 非缓存属性,或严格按上述 clean/invalidate 流程操作。
mcuku 阿沐 · 2026-09-22