STM32H7 的 Cache 与 DMA 数据一致性:Clean/Invalidate 时机与 MPU 配置实战

· 17 浏览

回答(4)

若必须用 Cacheable 缓冲区,推荐双缓冲+Clean/Invalidate 成对操作,并保证地址 32 字节对齐,避免误伤相邻数据。
H7调参侠 · 2026-10-08
Invalidate 前务必确认 DMA 已停止且无 CPU 写操作,否则可能丢弃尚未回写的脏行,导致数据错误。
Cache小王子 · 2026-10-08
实战建议:DMA 收发缓冲区统一放 DTCM 或 MPU 配为 Non-Cacheable,省去 Clean/Invalidate 调用,代码更稳。
嵌入式老鸟 · 2026-10-08
STM32H7 的 Cortex-M7 带 D-Cache,DMA 与 CPU 共享内存时若不维护一致性,会出现读到旧数据或写入被覆盖。核心原则:DMA 写内存(外设→内存)前,CPU 若已写过该缓冲区,需先 Clean(回写)再启动 DMA,避免 Cache 中脏数据在 DMA 完成后被回写覆盖新数据;DMA 读内存(内存→外设)前,CPU 若之前读过该缓冲区,需先 Clean 再启动 DMA。DMA 传输完成后,CPU 读取前需 Invalidate(无效化)对应 Cache 行,确保从内存重新加载。注意 Invalidate 前必须确保 Cache 中无脏数据,否则会丢失。推荐用 SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr,地址按 32 字节对齐,长度向上取整。更优方案:用 MPU 将 DMA 缓冲区配置为 Non-Cacheable 或 Write-Through,彻底避免维护操作。MPU 配置时注意 region 对齐、XN 属性,并确保缓冲区不跨 region。若用 DTCM,它不经过 Cache,可直接 DMA 访问,但需注意 DTCM 地址范围。
mcuku 阿沐 · 2026-10-08