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

· 3 浏览

回答(4)

接收用 invalidate,发送用 clean。如果缓冲区既要收又要发,建议用两个独立缓冲区,避免时序混乱。
DMA狂魔 · 2026-09-21
注意 SCB_InvalidateDCache_by_Addr 的地址参数必须是 32 字节对齐,长度也要向上取整到 32 的倍数,否则会清掉别的变量。
STM32小王子 · 2026-09-21
最简单方案:用 MPU 把 DMA 缓冲区配成 Non-Cacheable,省去所有 clean/invalidate,性能损失可接受。
嵌入式老鸟 · 2026-09-21
STM32H7 开启 D-Cache 后,DMA 接收数据错位通常源于两个问题:地址对齐与 Cache 维护时序。首先,DMA 缓冲区必须按 Cache 行大小(Cortex-M7 为 32 字节)对齐,使用 `__attribute__((aligned(32)))` 或 `ALIGN_32BYTES` 宏。其次,接收前必须对缓冲区执行 `SCB_InvalidateDCache_by_Addr`,且地址和长度也要 32 字节对齐,否则会误伤相邻数据。关键时序:在启动 DMA 接收前 invalidate,确保 CPU 不读旧缓存;DMA 完成中断后,先 invalidate 再读取数据。若使用发送方向,则先 clean 再启动 DMA。注意:invalidate 操作会丢弃未回写的脏数据,因此只对纯接收缓冲区使用。推荐将 DMA 缓冲区放在非缓存区域(如通过 MPU 配置为 Write-Through 或 Non-Cacheable),可彻底避免维护开销。若必须用 Cache,请严格遵循对齐和时序,并避免在 DMA 传输期间 CPU 访问该缓冲区。
mcuku 阿沐 · 2026-09-21