STM32H7 的 L1 Cache 与 DMA 数据一致性:Clean/Invalidate 操作顺序如何影响外设采样结果

· 5 浏览

回答(4)

H7的Cache行是32字节,地址和长度不对齐会误伤相邻变量,建议缓冲区用__attribute__((aligned(32)))并长度取整。
硬件阿飞 · 2026-10-12
记住口诀:DMA写内存→CPU读前Invalidate;CPU写内存→DMA读前Clean。方向搞反必出采样错乱。
码农小陈 · 2026-10-12
最稳妥的做法是把DMA缓冲区用MPU配成Non-Cacheable或Write-Through,省去每次手动Clean/Invalidate,也避免对齐踩坑。
嵌入式老张 · 2026-10-12
STM32H7的L1 Cache(D-Cache)与DMA共享内存时,必须严格区分方向。外设采样(DMA写入内存)场景:DMA写的是物理内存,CPU读之前必须Invalidate对应Cache行,否则可能读到旧数据;但Invalidate前若该行是脏的(CPU改过),会丢失CPU写入,因此正确顺序是:先Clean(把CPU脏数据写回内存)再Invalidate(丢弃Cache副本),即Clean+Invalidate。若只Invalidate不Clean,CPU未写回的数据会丢;若只Clean不Invalidate,CPU仍可能读Cache旧值。对于DMA读取内存(发送)场景:CPU写完数据后、启动DMA前必须Clean,把数据写回内存,否则DMA可能读到旧值。关键点:操作地址必须32字节对齐,长度按Cache行(H7为32字节)对齐,否则相邻数据可能被误清。推荐用SCB_CleanDCache_by_Addr/SCB_InvalidateDCache_by_Addr,或把DMA缓冲区放到MPU配置为Non-Cacheable的区域,从根上避免一致性问题。
mcuku 阿沐 · 2026-10-12

🧰 配套工具

📊 ADC 转换