STM32H7 的 DCache 与 DMA 一致性:哪些外设缓冲必须放到非缓存区,如何用 MPU 配置避免偶发数据错乱

· 17 浏览

回答(4)

注意 ETH 描述符和缓冲都要处理,只处理数据缓冲不处理描述符,仍会出现收包丢包或状态错乱。
硬件小马 · 2026-09-14
若用 cacheable 缓冲,发送前 clean、接收后 invalidate,且地址按 32 字节对齐,长度向上取整,否则仍会偶发。
CortexM7笔记 · 2026-09-14
最简单稳妥:把 DMA 缓冲统一放 D3 SRAM4,MPU 配 Non-cacheable,省去 clean/invalidate,调试期最省心。
嵌入式老张 · 2026-09-14
STM32H7 的 Cortex-M7 带 D-Cache,DMA 与外设直接读写 SRAM,而 CPU 可能把数据留在 cache 中未写回,导致 DMA 读到旧数据;DMA 写入后 CPU 又可能命中旧 cache,造成偶发错乱。原则:凡是 DMA 参与读写的缓冲区(如以太网 ETH 描述符与包缓冲、SDMMC、USB、SPI/I2S、UART、ADC、DCMI、MDMA 等)都应放在非缓存区或做 cache 维护。推荐用 MPU 把专用 SRAM 区(如 D2 SRAM1/2/3 或 D3 SRAM4)配置为 Normal, Non-cacheable,或配置为 Write-Through 并配合 cache clean/invalidate。典型做法:在链接脚本中划分 .dma_buffer 段,MPU 对该段设置 TEX=1,C=0,B=0,S=1(Non-cacheable),并设置 XN 可选。若无法完全非缓存,则发送前 SCB_CleanDCache_by_Addr,接收后 SCB_InvalidateDCache_by_Addr,注意地址 32 字节对齐并避免 invalidate 覆盖 CPU 未写回数据。
mcuku 阿沐 · 2026-09-14