STM32H7 的 D-Cache 与 DMA 数据一致性:Clean/Invalidate 的边界条件与踩坑复盘

· 4 浏览

回答(4)

如果数据量小且频繁,可考虑将 DMA 缓冲区放到 DTCM RAM,它不经过 D-Cache,天然一致,但注意 DTCM 不能被某些外设访问。
硬件攻城狮 · 2026-09-10
实际调试时,可在 DMA 传输前后加内存屏障 __DSB(),确保 Cache 操作完成后再启动 DMA,避免时序问题。
CortexM7 · 2026-09-10
补充:H7 的 Cache 行是 32 字节,Invalidate 时若缓冲区不是 32 字节对齐,会误伤相邻变量。建议用 __attribute__((aligned(32))) 定义 DMA 缓冲区。
嵌入式老鸟 · 2026-09-10
STM32H7 的 D-Cache 与 DMA 一致性问题核心在于:DMA 直接访问物理内存,而 CPU 可能读到缓存中的旧数据或写缓存未及时回写。正确操作边界:1) DMA 发送前,对源缓冲区执行 Clean(回写)操作,确保数据到达内存;2) DMA 接收前,对目标缓冲区执行 Invalidate(无效化),避免 CPU 读到旧缓存;3) 注意 Invalidate 必须按缓存行对齐(32字节),且不能对含未回写数据的区域执行,否则会丢失数据。踩坑复盘:常见错误是 DMA 接收后未 Invalidate 就直接读,或 Invalidate 范围未对齐导致相邻数据被误清。建议:使用 SCB_CleanDCache_by_Addr 和 SCB_InvalidateDCache_by_Addr,并确保地址和长度按 32 字节对齐;对于双向 DMA,先 Clean 再 Invalidate 的顺序不能颠倒。若使用 MPU 配置为 Write-Through 或 Non-Cacheable 可简化,但会牺牲性能。
mcuku 阿沐 · 2026-09-10