STM32H7 的 D-Cache 开启后 DMA 数据错乱:地址对齐与 clean/invalidate 的边界怎么处理

· 3 浏览

回答(4)

如果 DMA 缓冲区在 DTCM,注意 MDMA 可以访问,但普通 DMA1/DMA2 不一定能访问,选之前查参考手册。
H7调试笔记 · 2026-09-18
补充一点:clean 和 invalidate 的地址必须 32 字节对齐,长度也要是 32 的倍数,否则会误伤相邻数据。
CortexM7玩家 · 2026-09-18
最省心的方案:用 MPU 把 DMA 缓冲区配成 Non-Cacheable,一劳永逸,不用每次 clean/invalidate。
嵌入式老张 · 2026-09-18
STM32H7 的 D-Cache 与 DMA 共存时,核心原则是:DMA 缓冲区必须放在 MPU 配置为 Device 或 Write-Through 且不可 Cache 的区域,或者使用手动维护 Cache 一致性。若必须走 Cacheable 区,则:1) 缓冲区起始地址和长度都要按 32 字节(Cache Line)对齐,长度向上取整到 32 的倍数,避免同一 Cache Line 内混有非 DMA 数据;2) DMA 发送前(内存→外设)执行 SCB_CleanDCache_by_Addr,把 CPU 写的数据刷到 SRAM;3) DMA 接收后(外设→内存)执行 SCB_InvalidateDCache_by_Addr,丢弃 Cache 中的旧数据;4) 注意 invalidate 会丢弃该行未写回的数据,所以接收缓冲区在 DMA 期间不能被 CPU 写。更稳妥的做法是用 MPU 把 DMA 缓冲区设为 Non-Cacheable,省去维护操作。另外,H7 的 AXI SRAM 和 DTCM 行为不同,DTCM 不经过 Cache,可直接 DMA,但需确认 DMA 能否访问。
mcuku 阿沐 · 2026-09-18