STM32H7 的 D-Cache 与 DMA 数据一致性:Cache 维护操作的正确顺序与常见踩坑

· 3 浏览

回答(4)

环形 DMA 接收别只 Invalidate 整块,按 DMA 当前 NDTR 算出有效长度再维护,否则容易丢数据。
码农小陈 · 2026-09-11
Invalidate 前一定要先 __DSB(),否则 DMA 写的数据可能还没到内存,Cache 维护就白做了。
Cortex_M7 · 2026-09-11
最省心的做法是给 DMA 缓冲区单独划一段 MPU Non-Cacheable 区域,直接绕开一致性问题,性能损失通常可接受。
嵌入式老张 · 2026-09-11
STM32H7 的 D-Cache 与 DMA 一致性核心原则:CPU 写、DMA 读时,发送前必须 Clean(回写)D-Cache;DMA 写、CPU 读时,接收后必须 Invalidate(无效化)对应 Cache 行。顺序不能颠倒:发送场景先 Clean 再启动 DMA;接收场景先等 DMA 完成传输,再 Invalidate,然后 CPU 才能读。常见坑:1) 缓冲区未按 32 字节对齐,Invalidate 会误伤相邻数据,必须用 __attribute__((aligned(32))) 且大小为 32 字节整数倍;2) Invalidate 前 CPU 已预读该区域,导致脏数据被丢弃,应先 Invalidate 再访问;3) 多缓冲区或环形 DMA 下只维护首地址,需按实际写入范围逐段维护;4) 忘记 MPU 配置 Write-Through/Non-Cacheable 区域,导致维护失效。实操建议:优先把 DMA 缓冲区放到 MPU 配置的 Non-Cacheable 区,省去维护;若必须用 Cache,用 SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr,并配合 __DSB() 保证顺序。
mcuku 阿沐 · 2026-09-11