From 653295df6fc920119ff68bc751fcbec958066a65 Mon Sep 17 00:00:00 2001 From: SG Date: Sun, 25 Jul 2021 22:37:43 +1000 Subject: [PATCH] [FL-1609] Redirected malloc, calloc, realloc and free functions from newlib to freertos heap. (#604) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Core: newlib-nano heap management functions replaced with freertos functions * Core: replace newlib heap management functions for firmware only, not for bootloader * Core, Linker: automatically determine available heap size at linking. Co-authored-by: あく --- core/furi/memmgr.c | 19 +++++++++++++++++++ core/furi/memmgr_heap.c | 14 +++++--------- firmware/Makefile | 1 + firmware/targets/f6/Inc/FreeRTOSConfig.h | 3 ++- .../targets/f6/stm32wb55xx_flash_cm4_boot.ld | 6 +++--- .../f6/stm32wb55xx_flash_cm4_no_boot.ld | 6 +++--- make/freertos-heap.mk | 1 + make/toolchain.mk | 2 +- 8 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 make/freertos-heap.mk diff --git a/core/furi/memmgr.c b/core/furi/memmgr.c index b15f2ded..a79cc502 100644 --- a/core/furi/memmgr.c +++ b/core/furi/memmgr.c @@ -67,3 +67,22 @@ size_t memmgr_get_free_heap(void) { size_t memmgr_get_minimum_free_heap(void) { return xPortGetMinimumEverFreeHeapSize(); } + +void* __wrap__malloc_r(struct _reent* r, size_t size) { + void* pointer = malloc(size); + return pointer; +} + +void __wrap__free_r(struct _reent* r, void* ptr) { + free(ptr); +} + +void* __wrap__calloc_r(struct _reent* r, size_t count, size_t size) { + void* pointer = calloc(count, size); + return pointer; +} + +void* __wrap__realloc_r(struct _reent* r, void* ptr, size_t size) { + void* pointer = realloc(ptr, size); + return pointer; +} \ No newline at end of file diff --git a/core/furi/memmgr_heap.c b/core/furi/memmgr_heap.c index 2ddc7a26..16116f1e 100644 --- a/core/furi/memmgr_heap.c +++ b/core/furi/memmgr_heap.c @@ -59,14 +59,10 @@ task.h is included from an application file. */ /* Assumes 8bit bytes! */ #define heapBITS_PER_BYTE ((size_t)8) -/* Allocate the memory for the heap. */ -#if(configAPPLICATION_ALLOCATED_HEAP == 1) -/* The application writer has already defined the array used for the RTOS - heap - probably so it can be placed in a special segment or address. */ -extern uint8_t ucHeap[configTOTAL_HEAP_SIZE]; -#else -static uint8_t ucHeap[configTOTAL_HEAP_SIZE]; -#endif /* configAPPLICATION_ALLOCATED_HEAP */ +/* Heap start end symbols provided by linker */ +extern const void __heap_start__; +extern const void __heap_end__; +uint8_t* ucHeap = (uint8_t*)&__heap_start__; /* Define the linked list structure. This is used to link free blocks in order of their memory address. */ @@ -421,7 +417,7 @@ static void prvHeapInit(void) { BlockLink_t* pxFirstFreeBlock; uint8_t* pucAlignedHeap; size_t uxAddress; - size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; + size_t xTotalHeapSize = (size_t)&__heap_end__ - (size_t)&__heap_start__; /* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = (size_t)ucHeap; diff --git a/firmware/Makefile b/firmware/Makefile index 4c0ee1db..ccceb450 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -2,6 +2,7 @@ PROJECT_ROOT = $(abspath $(dir $(abspath $(firstword $(MAKEFILE_LIST))))..) PROJECT = firmware include $(PROJECT_ROOT)/make/base.mk +include $(PROJECT_ROOT)/make/freertos-heap.mk include $(PROJECT_ROOT)/assets/assets.mk include $(PROJECT_ROOT)/core/core.mk include $(PROJECT_ROOT)/applications/applications.mk diff --git a/firmware/targets/f6/Inc/FreeRTOSConfig.h b/firmware/targets/f6/Inc/FreeRTOSConfig.h index 3d1a8c45..748fc7f6 100644 --- a/firmware/targets/f6/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f6/Inc/FreeRTOSConfig.h @@ -69,7 +69,8 @@ #define configTICK_RATE_HZ ((TickType_t)1024) #define configMAX_PRIORITIES ( 56 ) #define configMINIMAL_STACK_SIZE ((uint16_t)128) -#define configTOTAL_HEAP_SIZE ((size_t)131072) +/* Heap size determined automatically by linker */ +// #define configTOTAL_HEAP_SIZE ((size_t)0) #define configMAX_TASK_NAME_LEN ( 16 ) #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 diff --git a/firmware/targets/f6/stm32wb55xx_flash_cm4_boot.ld b/firmware/targets/f6/stm32wb55xx_flash_cm4_boot.ld index 6c5e92ef..faa4301b 100644 --- a/firmware/targets/f6/stm32wb55xx_flash_cm4_boot.ld +++ b/firmware/targets/f6/stm32wb55xx_flash_cm4_boot.ld @@ -161,9 +161,9 @@ SECTIONS ._user_heap_stack : { . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; + __heap_start__ = .; + . = ORIGIN(RAM1) + LENGTH(RAM1) - _Min_Stack_Size; + __heap_end__ = .; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM1 diff --git a/firmware/targets/f6/stm32wb55xx_flash_cm4_no_boot.ld b/firmware/targets/f6/stm32wb55xx_flash_cm4_no_boot.ld index 4cd7e899..095f368b 100644 --- a/firmware/targets/f6/stm32wb55xx_flash_cm4_no_boot.ld +++ b/firmware/targets/f6/stm32wb55xx_flash_cm4_no_boot.ld @@ -161,9 +161,9 @@ SECTIONS ._user_heap_stack : { . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; + __heap_start__ = .; + . = ORIGIN(RAM1) + LENGTH(RAM1) - _Min_Stack_Size; + __heap_end__ = .; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM1 diff --git a/make/freertos-heap.mk b/make/freertos-heap.mk new file mode 100644 index 00000000..e839e61c --- /dev/null +++ b/make/freertos-heap.mk @@ -0,0 +1 @@ +LDFLAGS += -Wl,--wrap,_malloc_r -Wl,--wrap,_free_r -Wl,--wrap,_calloc_r -Wl,--wrap,_realloc_r \ No newline at end of file diff --git a/make/toolchain.mk b/make/toolchain.mk index 49eada98..ab6da9bd 100644 --- a/make/toolchain.mk +++ b/make/toolchain.mk @@ -27,4 +27,4 @@ endif CFLAGS += -fdata-sections -ffunction-sections -fno-math-errno -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" CPPFLAGS += -fno-threadsafe-statics -fno-use-cxa-atexit -fno-exceptions -fno-rtti -LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -u _printf_float +LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -u _printf_float \ No newline at end of file