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

· 4 浏览

回答(4)

收发顺序记牢:发=clean 后启动;收=启动后等完成再 invalidate。顺序反了就是随机错乱,调几天都找不到。
DMA不迷路 · 2026-10-14
H7 的 cache line 是 32 字节,缓冲区长度不是 32 倍数时,invalidate 会误伤相邻变量,建议单独开一块对齐的 DMA 内存池。
Cortex小王子 · 2026-10-14
MPU 把 DMA 缓冲区配成 Device 或 Normal Non-cacheable,最省心,不用每次 clean/invalidate,代价是 CPU 访问稍慢。
嵌入式老张 · 2026-10-14
STM32H7 的 D-Cache 与 DMA 冲突本质是缓存一致性:DMA 直接访问 SRAM,而 CPU 可能读到旧缓存或写回覆盖 DMA 新数据。正确做法:1) 缓冲区按 32 字节对齐(CACHE_LINE_SIZE),大小取 32 的整数倍,避免同一 cache line 混有其它变量;2) 发送前对缓冲区做 clean(SCB_CleanDCache_by_Addr),把 CPU 写入刷到 SRAM,再启动 DMA;3) 接收时先启动 DMA,等 DMA 完成中断后,对接收缓冲区做 invalidate(SCB_InvalidateDCache_by_Addr),再读数据;4) 若接收缓冲区在 DMA 期间可能被 CPU 访问,应先 invalidate 再启动 DMA,完成后再次 invalidate;5) 最稳妥是把 DMA 缓冲区放到 MPU 配置为 non-cacheable 的 SRAM 区域,彻底绕开 clean/invalidate 时序问题。注意 invalidate 会丢弃未写回数据,务必在 DMA 未写该区域时执行。
mcuku 阿沐 · 2026-10-14