【嵌入式】STM32H743, D-cache, DMA注意事项
2026/8/21 11:40:58 网站建设 项目流程

1. 问题

STM32H743开启D-cache以后,如果使用DMA会导致数据错乱。

2. 原因

DMA访问的是RAM, 实际的数据可能还在D-cache中,没有与RAM同步。

3. 解决方法

3.1 使用前同步

  • DMA发送前将cache中的数据写会RAM
SCB_CleanDCache_by_Addr()
  • DMA接收数据后,cache获取RMA的数据
SCB_InvalidateDCache_by_Addr()
  • 详情
//用于将 D-Cache 数据回写到 SRAM 里面SCB_CleanDCache_by_Addr((uint32_t*)buf,len);//用于重新从 SRAM 获取数据, 丢弃 D-Cache 当前数据,SCB_InvalidateDCache_by_Addr((uint32_t*)buf,len);//写回数据到 SRAM, 并重新获取 D-Cache数据SCB_CleanInvalidateDCache_by_Addr((uint32_t*)buf,len);

3.2 MPU方式(推荐)

  • 通过MPU关闭一块SRAM的Cache功能

    • 例如:以0x30000000为首地址的128K(SRAM1)
    • 为什么不用0x24000000(AXI SRAM)这一块?因为这块ram的速度快,关闭Cache太浪费。
  • DMA使用到的内存需要定义到关闭Cache的内存范围内

步骤

1. 开启MPU并设置
voidMPU_Config(void){MPU_Region_InitTypeDef MPU_InitStruct={0};/* Disables the MPU */HAL_MPU_Disable();/** Initializes and configures the Region and the memory to be protected */MPU_InitStruct.Enable=MPU_REGION_ENABLE;MPU_InitStruct.Number=MPU_REGION_NUMBER0;MPU_InitStruct.BaseAddress=0x30000000;MPU_InitStruct.Size=MPU_REGION_SIZE_128KB;MPU_InitStruct.SubRegionDisable=0x0;MPU_InitStruct.TypeExtField=MPU_TEX_LEVEL0;MPU_InitStruct.AccessPermission=MPU_REGION_FULL_ACCESS;MPU_InitStruct.DisableExec=MPU_INSTRUCTION_ACCESS_ENABLE;MPU_InitStruct.IsShareable=MPU_ACCESS_SHAREABLE;MPU_InitStruct.IsCacheable=MPU_ACCESS_NOT_CACHEABLE;MPU_InitStruct.IsBufferable=MPU_ACCESS_NOT_BUFFERABLE;HAL_MPU_ConfigRegion(&MPU_InitStruct);/* Enables the MPU */HAL_MPU_Enable(MPU_HFNMI_PRIVDEF);}
2. Keil工程设置Linker

3 STM32H743_DMA.sct
;STM32H743IITx;Flash2MB;AXISRAM(D1)512KB;SRAM1+SRAM2+SRAM3(D2)288KB LR_IROM10x080000000x00200000{ER_IROM10x080000000x00200000{*.o(RESET,+First)*(InRoot$$Sections).ANY(+RO)};普通RW/ZI变量 RW_RAM_D10x240000000x00080000{.ANY(+RW+ZI)};DMA专用区域 RW_DMA0x300000000x00048000{*(.dma_buffer)}}
4. 使用
#define__DMA_RAM\__attribute__((section(".dma_buffer")))\__attribute__((aligned(32)))//注意,这里buf需要是全局变量或static变量__DMA_RAMuint8_tbuf[512]={0};//buf在0x30000000 sram段//备注,这里赋初值可能没作用。例如下面两行代码,赋的初值不起效果__DMA_RAMuint8_tbuf[512]={123};static__DMA_RAMuint8_tbuf[512]={1,2,3};

3.3 D-Cache 的透写模式

  • 缺点: 会损失一些性能,因为每次都要从从Cache写会数据。
/** * @brief 使能 STM32H7 的 L1-Cache, 同时开启 D cache 的强制透写 * @param 无 * @retval 无 */voidsys_cache_enable(void){SCB_EnableICache();/* 使能 I-Cache,函数在 core_cm7.h 里面定义 */SCB_EnableDCache();/* 使能 D-Cache,函数在 core_cm7.h 里面定义 */SCB->CACR|=1<<2;/* 强制 D-Cache 透写,如不开启透写,实际使用中可能遇到各种问题 */}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询