STM32H7 的 D-Cache 开启后 DMA 收发数据错位:Cache 一致性维护的三种正确姿势与性能代价对比

· 3 浏览

回答(4)

推荐用 MPU 把 DMA 缓冲区分成两块:发送区 Non-Cacheable,接收区 Write-Through,兼顾性能与安全。
硬件攻城狮 · 2026-09-28
实测 H7 上 Non-Cacheable 区域做 1KB 内存拷贝比 Cacheable 慢约 2.5 倍,但省去维护开销,适合小包高频场景。
STM32调参侠 · 2026-09-28
补充一点:Invalidate 操作会丢弃未写回的数据,接收前若 CPU 写过该缓冲区,必须先 Clean 再 Invalidate,否则丢数据。
嵌入式老鸟 · 2026-09-28
STM32H7 的 D-Cache 与 DMA 冲突是经典问题:CPU 写数据后可能还在 Cache 中未写回,DMA 直接读内存导致读到旧数据;DMA 写入内存后 CPU 读时可能命中旧 Cache 行。三种正确姿势:1)MPU 配置 DMA 缓冲区为 Write-Through 或 Non-Cacheable,一劳永逸,但会降低 CPU 访问该区域的性能;2)发送前调用 SCB_CleanDCache_by_Addr() 写回,接收后调用 SCB_InvalidateDCache_by_Addr() 无效化,注意地址和长度必须 32 字节对齐,且接收无效化前要确保 CPU 未访问该缓冲区;3)使用带 Cache 维护的 DMA 驱动(如 ST 的 BSP 或 HAL 的 SCB 接口),在 DMA 完成中断中统一处理。性能代价:Non-Cacheable 区域 CPU 访问延迟约 2-3 倍;Clean/Invalidate 每次操作有几十到几百周期开销,频繁小数据 DMA 时显著。建议:大数据块用 Cache 维护,小数据或高频用 Non-Cacheable 区域,并严格对齐。
mcuku 阿沐 · 2026-09-28