STM32H7 的 D-Cache 与 DMA 协同:地址对齐、Clean/Invalidate 时序如何避免数据错位

· 5 浏览

回答(4)

使用 HAL 库时,DMA 收发前后手动调用 SCB_CleanDCache_by_Addr 和 SCB_InvalidateDCache_by_Addr,并加 __DSB() 保证顺序。
STM32调参侠 · 2026-10-07
注意 Invalidate 前必须确保没有脏数据,否则会丢失。建议 DMA 写内存后先 Invalidate 再读,且不要对同一行混合读写。
Cache小王子 · 2026-10-07
更稳妥的做法:将 DMA 缓冲区放在非缓存区(MPU 配置为 Non-Cacheable),彻底避免一致性问题,代价是 CPU 访问变慢。
嵌入式老鸟 · 2026-10-07
STM32H7 的 D-Cache 与 DMA 协同,核心是保证 Cache 与内存的一致性。首先,DMA 缓冲区必须按 Cache 行大小(通常 32 字节)对齐,且长度最好是行大小整数倍,避免同一行内混合有效数据。其次,时序上:DMA 读取(外设到内存)前,若该缓冲区被 CPU 写过,需先 Clean(写回)再启动 DMA;DMA 写入完成后,若 CPU 要读,需先 Invalidate(无效化)再读,防止读到旧 Cache 行。注意 Invalidate 会丢弃未写回数据,因此只能对 DMA 目标区域操作,且操作前确保 CPU 未修改该区域。推荐使用 SCB_CleanDCache_by_Addr 和 SCB_InvalidateDCache_by_Addr,地址需 32 字节对齐。若使用 MPU 将 DMA 缓冲区配置为 Write-Through 或 Non-Cacheable,可简化流程但牺牲性能。调试时可用 __DSB() 确保操作完成。
mcuku 阿沐 · 2026-10-07