STM32H7 的 D-Cache 与 DMA 一致性:地址对齐、Clean/Invalidate 顺序和常见踩坑

· 15 浏览

回答(4)

DMA 描述符和缓冲区都要 32 字节对齐,推荐用 __attribute__((aligned(32))) 定义,长度向上取整到 32 的倍数,避免误伤相邻变量。
码农小张 · 2026-09-17
注意 SCB_InvalidateDCache_by_Addr 会丢弃未写回的数据,若缓冲区有 CPU 刚写入但未 Clean 的内容,先 Clean 再 Invalidate,否则数据丢失。
H7调试员 · 2026-09-17
最省心的做法:用 MPU 把 DMA 缓冲区所在 SRAM 区域设为 Normal Non-Cacheable,从此不用手动 Clean/Invalidate,但会牺牲一点 CPU 访问性能。
嵌入式老鸟 · 2026-09-17
STM32H7 的 D-Cache 与 DMA 一致性核心在于:DMA 访问的是物理内存,CPU 可能读到 Cache 中的旧数据。正确顺序:发送(内存→外设)前,先 Clean(写回)对应 Cache 行,再启动 DMA;接收(外设→内存)前,先 Invalidate(无效化)对应 Cache 行,再启动 DMA,且必须在 DMA 完成后再访问数据。地址对齐要求:DMA 缓冲区必须按 Cache 行大小(H7 为 32 字节)对齐,长度也建议为 32 字节整数倍,否则 Clean/Invalidate 会误伤相邻数据。常见踩坑:1) 未对齐导致相邻变量被意外写回或丢弃;2) 在 DMA 传输过程中访问缓冲区,Cache 行被重新填充;3) 使用 DTCM 内存(0x20000000)做 DMA,但 DTCM 不支持 DMA,应改用 AXI SRAM 或 SRAM1-3;4) 忘记 MPU 配置将 DMA 缓冲区设为 Non-Cacheable 或 Write-Through。实操建议:优先用 MPU 将 DMA 缓冲区配置为 Non-Cacheable,可省去手动维护;若必须用 Cacheable,则严格按 Clean/Invalidate 顺序,并用 SCB_CleanDCache_by_Addr 等函数。
mcuku 阿沐 · 2026-09-17