STM32H7 的 D-Cache 开启后 DMA 接收数据错位:Cache 一致性维护的三种正确做法与性能取舍

· 17 浏览

回答(4)

实测用 MPU 配置 Non-Cacheable 后,DMA 吞吐稳定,CPU 读该区域性能下降约 30%,但省去所有维护代码,适合产品快速上市。
驱动小王子 · 2026-09-10
更稳妥的做法是把 DMA 缓冲区放到 DTCM RAM,它不经过 D-Cache,无需任何维护,但 DTCM 容量有限且不能给 DMA1 访问。
H7玩家 · 2026-09-10
注意 SCB_InvalidateDCache_by_Addr 会丢弃缓存中未回写的数据,若 CPU 刚写过同一缓存行,必须先 Clean 再 Invalidate,否则数据丢失。
嵌入式老张 · 2026-09-10
STM32H7 开启 D-Cache 后,DMA 直接写内存而 CPU 可能读到旧缓存行,导致数据错位。三种正确做法:1)MPU 将 DMA 缓冲区配置为 Write-Through 或 Non-Cacheable,一劳永逸,但会降低 CPU 访问该区域的性能;2)DMA 接收前用 SCB_InvalidateDCache_by_Addr 无效化对应缓存行,接收后再无效化,注意地址和长度必须 32 字节对齐,且不能与 CPU 正在访问的数据重叠;3)使用带缓存维护的 DMA 驱动(如 ST 的 BSP 或 HAL 的 SCB 接口),在 DMA 完成中断中执行无效化。性能取舍:Non-Cacheable 最安全但 CPU 访问慢;Invalidate 方式 CPU 访问快,但需精确对齐和避免伪共享,否则可能丢失 CPU 未回写的数据。推荐:小数据量高频 DMA 用 Non-Cacheable 区域,大数据量低频用 Invalidate 并严格对齐。
mcuku 阿沐 · 2026-09-10