
很少见到关于heap5的使用,特地今天测试了一下,并且分享关于这方面的例子。 软件:CubeMX5.6,Keil5.27,串口助手 硬件:STM32L4R5,片外 双SRAM STEP1: 环境搭建,各项配置 并不赘述如何配置芯片,自行搭建。 STEP2:修改CubemX代码 生成的FreeRTOS的MX_FREERTOS_Init中添加部分代码,如下 const HeapRegion_t xHeapRegions[] = { { ( uint8_t * ) 0x64000000UL, 1024*32 }, { ( uint8_t * ) 0x68000000UL, 1024*32 }, { NULL, 0 } /* Terminates the array. */ }; vPortDefineHeapRegions(xHeapRegions); STEP3:测试malloc 本测试仅有一个任务, void StartDefaultTask(void const * argument) { /* USER CODE BEGIN StartDefaultTask */ uint8_t * p; uint32_t size; uint32_t count = 1; char str[64]; /* Infinite loop */ for(;;) { if( HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == GPIO_PIN_SET ) { HAL_Delay(10); if( HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == GPIO_PIN_SET ) { p = pvPortMalloc(1024*2); size = xPortGetFreeHeapSize(); sprintf(str, "malloc times %d\r\n", (uint32_t)count); HAL_UART_Transmit(&hlpuart1, (uint8_t *)str, strlen(str), 0xFF); memset(str, 0, strlen(str)); sprintf(str, "mem add %x\r\n", (uint32_t)p); HAL_UART_Transmit(&hlpuart1, (uint8_t *)str, strlen(str), 0xFF); memset(str, 0, strlen(str)); sprintf(str, "Free size Bytes %d\r\n", size); HAL_UART_Transmit(&hlpuart1, (uint8_t *)str, strlen(str), 0xFF); memset(str, 0, strlen(str)); sprintf(str, "Free size Bytes %d\r\n", size); HAL_UART_Transmit(&hlpuart1, (uint8_t *)str, strlen(str), 0xFF); memset(str, 0, strlen(str)); count++; } } osDelay(50); } /* USER CODE END StartDefaultTask */ } 测试结果: malloc times 1 mem add 64000270 Free size Bytes 62848 Free size Bytes 62848 malloc times 2 mem add 64000a78 Free size Bytes 60792 Free size Bytes 60792 malloc times 3 mem add 64001280 Free size Bytes 58736 Free size Bytes 58736 malloc times 4 mem add 64001a88 Free size Bytes 56680 Free size Bytes 56680 malloc times 5 mem add 64002290 Free size Bytes 54624 Free size Bytes 54624 malloc times 6 mem add 64002a98 Free size Bytes 52568 Free size Bytes 52568 malloc times 7 mem add 640032a0 Free size Bytes 50512 Free size Bytes 50512 malloc times 8 mem add 64003aa8 Free size Bytes 48456 Free size Bytes 48456 malloc times 9 mem add 640042b0 Free size Bytes 46400 Free size Bytes 46400 malloc times 10 mem add 64004ab8 Free size Bytes 44344 Free size Bytes 44344 malloc times 11 mem add 640052c0 Free size Bytes 42288 Free size Bytes 42288 malloc times 12 mem add 64005ac8 Free size Bytes 40232 Free size Bytes 40232 malloc times 13 mem add 640062d0 Free size Bytes 38176 Free size Bytes 38176 malloc times 14 mem add 64006ad8 Free size Bytes 36120 Free size Bytes 36120 malloc times 15 mem add 640072e0 Free size Bytes 34064 Free size Bytes 34064 malloc times 16 mem add 68000008 Free size Bytes 32008 Free size Bytes 32008 malloc times 17 mem add 68000810 Free size Bytes 29952 Free size Bytes 29952 malloc times 18 mem add 68001018 Free size Bytes 27896 Free size Bytes 27896 malloc times 19 mem add 68001820 Free size Bytes 25840 Free size Bytes 25840 malloc times 20 mem add 68002028 Free size Bytes 23784 Free size Bytes 23784 malloc times 21 mem add 68002830 Free size Bytes 21728 Free size Bytes 21728 malloc times 22 mem add 68003038 Free size Bytes 19672 Free size Bytes 19672 malloc times 23 mem add 68003840 Free size Bytes 17616 Free size Bytes 17616 malloc times 24 mem add 68004048 Free size Bytes 15560 Free size Bytes 15560 malloc times 25 mem add 68004850 Free size Bytes 13504 Free size Bytes 13504 malloc times 26 mem add 68005058 Free size Bytes 11448 Free size Bytes 11448 malloc times 27 mem add 68005860 Free size Bytes 9392 Free size Bytes 9392 malloc times 28 mem add 68006068 Free size Bytes 7336 Free size Bytes 7336 malloc times 29 mem add 68006870 Free size Bytes 5280 Free size Bytes 5280 malloc times 30 mem add 68007078 Free size Bytes 3224 Free size Bytes 3224 malloc times 31 mem add 0 Free size Bytes 3224 Free size Bytes 3224 32KB x 2 SRAM,总共64KB,实际可以使用小于64KB,并且每次malloc大小为2KB,实际1024*2+8 = 2056Byets。 最后明显大于2056Bytes却还是不能malloc的原因: 第一次malloc地址0x64000270,也就是说624Bytes跳过了, 那么3324-624=2700Bytes, 第一片SRAM的最后一次malloc 地址0x640072e0,第一片剩余3360-2056=518Bytes,总共2700-518=2182Bytes, 第二片SRAM的最后一次有效malloc 地址0x68007078,第二片最后剩余922Bytes,总共2182-922<2056Bytes, 简单来说,第一片前部分内存,后部分内存,第二片后部分内存都被切开剩余了,虽然剩余3224Bytes,很明显能malloc一次2056Bytes的空间,但是这种碎片应该可以被更小malloc大小用掉。SDRAM使用heap5应该注意这点,而且对于不连续的内存的使用会比较复杂,0x64000000到0x68000000,中间不连续,程序需要考虑,操作内存需要跳到相应地址。我觉得一个if else 就够了。 |