STM32H7中SPI+DMA适配d-cache的局部优化方案问询
STM32H7 SPI DMA 与D-Cache 处理问题
我在STM32H7 SoC中使用带DMA的SPI设备,由于DMA无法访问D-Cache,目前靠全局禁用D-Cache解决问题,但希望仅针对受影响的小内存区域处理,避免全局禁用。
我学习了ARM缓存中clean和invalidate操作的含义,我的理解是:
- Clean缓存区域:强制将缓存内容写入实际内存
- Invalidate缓存区域:强制缓存从实际内存更新
此理解是否正确?
我计划按以下步骤实现SPI(带DMA)传输:
- 向DMA读取的缓冲区写入待传输值;
- Clean该区域的D-Cache,强制内容写入实际内存,确保DMA可见;
- 启动操作:DMA从上述区域读取值并写入SPI的Tx缓冲区;
- SPI读写同步进行,Rx缓冲区会存入数据,DMA将其读取后写入用户提供的recv缓冲区。由于该缓冲区的观察者可能访问D-Cache,而缓存可能未更新新接收的值,因此Invalidaterecv缓冲区区域,强制D-Cache更新。
上述流程是否合理?
补充参考信息
- ST GitHub相关问题示例
- ST论坛关于D-Cache问题的解答
内存与DMA互连关系

如图所示,DMA1可访问SRAM1、2、3,我使用的是SRAM2。
SRAM2缓存属性

可见其为write back、write allocate模式,非write through。我从资料了解了这些术语定义,但不确定ARM的I-Cache和D-Cache是否适用这些物理缓存的术语,暂假设定义通用。
问题解答
1. 缓存操作理解正确性
你的理解完全正确:
- Clean(清理):将D-Cache中被修改过的脏数据写回物理内存,确保物理内存的数据与缓存一致,常用于CPU写入数据后需要让DMA等外设读取的场景。
- Invalidate(失效):标记缓存中的数据为无效,后续CPU访问该区域时会直接从物理内存重新加载数据,常用于外设(如DMA)写入物理内存后,需要让CPU获取最新数据的场景。
2. SPI DMA传输流程合理性
你的流程完全合理,完美匹配Write-Back模式下的缓存处理逻辑:
- Tx阶段:由于SRAM2是Write-Back模式,CPU写入缓冲区的数据可能仅存在于D-Cache中,物理内存未同步更新,此时必须执行Clean操作,将缓存数据刷入物理内存,保证DMA能读取到正确的传输数据。
- Rx阶段:DMA直接将数据写入物理内存,而D-Cache中可能保留该区域旧的缓存数据,此时执行Invalidate操作,让CPU后续访问该缓冲区时直接读取物理内存中的新数据,避免读到旧值。
额外注意点:
- 执行缓存操作时,要确保操作的内存区域是缓存行对齐的,或者直接调用STM32 HAL库中提供的缓存操作函数(如
SCB_CleanDCache_by_Addr()、SCB_InvalidateDCache_by_Addr()),这些函数会自动处理对齐问题。 - 如果使用CubeMX配置内存属性,要确认SRAM2的缓存配置确实是Write-Back,避免因配置错误导致的缓存问题。
内容的提问来源于stack exchange,提问作者Martel
相关产品推荐
相关产品推荐

