STM32H7 的 D-Cache 与 DMA 一致性坑:如何用 MPU 配置回写策略避免数据错乱

· 17 浏览

回答(4)

注意 SCB_InvalidateDCache_by_Addr 的地址必须 32 字节对齐,长度也要是 32 的倍数,否则会误伤相邻数据,这是最常见的坑。
硬件工程师李工 · 2026-09-14
实际项目里我直接把 DMA 缓冲区设为 Non-Cacheable,性能损失可接受,省去手动维护 Cache 的麻烦,尤其适合高速 ADC 连续采样。
码农小张 · 2026-09-14
补充:如果缓冲区在 DTCM,它默认不经过 Cache,无需 MPU 配置,但 DMA 无法访问 DTCM,所以 DMA 缓冲区必须放在 AXI SRAM 或 SDRAM。
嵌入式老鸟 · 2026-09-14
STM32H7 的 D-Cache 与 DMA 一致性问题的核心在于:DMA 直接访问物理内存,而 CPU 可能读到 Cache 中的旧数据,或 DMA 读到尚未回写到内存的脏数据。用 MPU 配置回写策略的正确做法是:将 DMA 缓冲区所在的内存区域(如 SRAM1/2/3 或 SDRAM)配置为 Write-Through(写透)或 Write-Back, Write-Allocate 但配合手动维护。推荐方案:1)如果 DMA 只读(外设到内存),将缓冲区 MPU 属性设为 Non-Cacheable 或 Write-Through,避免 CPU 读到旧数据;2)如果 DMA 只写(内存到外设),设为 Write-Through 并确保 CPU 写操作立即到达内存;3)如果双向,最稳妥是设为 Non-Cacheable,或使用 Write-Back 但每次 DMA 传输前后调用 SCB_CleanDCache_by_Addr 和 SCB_InvalidateDCache_by_Addr。注意:Invalidate 前必须确保 CPU 没有未回写的脏数据,否则会丢失。实操建议:用 MPU 配置 32 字节对齐的缓冲区,大小按实际需求,并启用 MemManage Fault 检测非法访问。
mcuku 阿沐 · 2026-09-14