软件测试面试全攻略:从基础到高阶知识体系
2026/8/21 11:49:28
STM32H743开启D-cache以后,如果使用DMA会导致数据错乱。
DMA访问的是RAM, 实际的数据可能还在D-cache中,没有与RAM同步。
SCB_CleanDCache_by_Addr()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);通过MPU关闭一块SRAM的Cache功能
0x30000000为首地址的128K(SRAM1)0x24000000(AXI SRAM)这一块?因为这块ram的速度快,关闭Cache太浪费。DMA使用到的内存需要定义到关闭Cache的内存范围内
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);};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)}}#define__DMA_RAM\__attribute__((section(".dma_buffer")))\__attribute__((aligned(32)))//注意,这里buf需要是全局变量或static变量__DMA_RAMuint8_tbuf[512]={0};//buf在0x30000000 sram段//备注,这里赋初值可能没作用。例如下面两行代码,赋的初值不起效果__DMA_RAMuint8_tbuf[512]={1,2,3};static__DMA_RAMuint8_tbuf[512]={1,2,3};/** * @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 透写,如不开启透写,实际使用中可能遇到各种问题 */}