diff --git a/TODO.md b/TODO.md index 8b2d008..cbfa1b4 100644 --- a/TODO.md +++ b/TODO.md @@ -12,6 +12,7 @@ Explicit is better than implicit. - consider moving to C++17 (GNU)? or any newer than C++11 - wrap all memory management functions (malloc, calloc, free, memset, etc.) and their vendor SDK counterparts to use FreeRTOS instead + - pretty much done for ambz and ambz2, Beken is yet left to do (`os_malloc()` etc.) - remove all network protocol client/server implementations from SDKs (mDNS, HTTP, DNS, etc.) ### New families diff --git a/builder/family/beken-72xx.py b/builder/family/beken-72xx.py index fba38f7..5c4c500 100644 --- a/builder/family/beken-72xx.py +++ b/builder/family/beken-72xx.py @@ -95,19 +95,6 @@ queue.AppendPublic( "-g", "--specs=nano.specs", "-Wl,--gc-sections", - "-Wl,-wrap,_free_r", - "-Wl,-wrap,_malloc_r", - "-Wl,-wrap,calloc", - "-Wl,-wrap,free", - "-Wl,-wrap,malloc", - "-Wl,-wrap,realloc", - "-Wl,-wrap,zalloc", - "-Wl,-wrap,_realloc_r", - "-Wl,-wrap,printf", - "-Wl,-wrap,puts", - "-Wl,-wrap,snprintf", - "-Wl,-wrap,sprintf", - "-Wl,-wrap,vsnprintf", "-Wl,-wrap,bk_flash_get_info", "-Wl,-wrap,bk_flash_erase", "-Wl,-wrap,bk_flash_write", diff --git a/builder/family/realtek-ambz.py b/builder/family/realtek-ambz.py index 2fbcc04..d320863 100644 --- a/builder/family/realtek-ambz.py +++ b/builder/family/realtek-ambz.py @@ -63,9 +63,6 @@ queue.AppendPublic( "-Wl,--undefined=gImage2EntryFun0", "-Wl,--no-enum-size-warning", "-Wl,--no-wchar-size-warning", - "-Wl,-wrap,malloc", - "-Wl,-wrap,free", - "-Wl,-wrap,realloc", "-Wl,-wrap,rom_psk_CalcGTK", "-Wl,-wrap,rom_psk_CalcPTK", "-Wl,-wrap,CalcMIC", diff --git a/builder/family/realtek-ambz2.py b/builder/family/realtek-ambz2.py index 73abb27..5e9b3ed 100644 --- a/builder/family/realtek-ambz2.py +++ b/builder/family/realtek-ambz2.py @@ -111,14 +111,6 @@ queue.AppendPublic( "-Wl,-wrap,atoi", "-Wl,-wrap,atol", "-Wl,-wrap,atof", - "-Wl,-wrap,malloc", - "-Wl,-wrap,calloc", - "-Wl,-wrap,realloc", - "-Wl,-wrap,free", - "-Wl,-wrap,_malloc_r", - "-Wl,-wrap,_calloc_r", - "-Wl,-wrap,_realloc_r", - "-Wl,-wrap,_free_r", "-Wl,-wrap,memcmp", "-Wl,-wrap,memcpy", "-Wl,-wrap,memmove", diff --git a/builder/frameworks/base.py b/builder/frameworks/base.py index c8c2928..01903c7 100644 --- a/builder/frameworks/base.py +++ b/builder/frameworks/base.py @@ -81,6 +81,17 @@ queue.AppendPublic( "$BOARD_DIR", ], LINKFLAGS=[ + # malloc.c wrappers + "-Wl,-wrap,malloc", + "-Wl,-wrap,calloc", + "-Wl,-wrap,zalloc", + "-Wl,-wrap,realloc", + "-Wl,-wrap,free", + "-Wl,-wrap,_malloc_r", + "-Wl,-wrap,_calloc_r", + "-Wl,-wrap,_realloc_r", + "-Wl,-wrap,_free_r", + # linker map path '"-Wl,-Map=' + join("$BUILD_DIR", "${PROGNAME}.map") + '"', ], LIBS=[ diff --git a/cores/beken-72xx/base/lt_defs.h b/cores/beken-72xx/base/lt_defs.h index 552faaf..fbeae66 100644 --- a/cores/beken-72xx/base/lt_defs.h +++ b/cores/beken-72xx/base/lt_defs.h @@ -8,4 +8,5 @@ #define LT_HAS_FREERTOS 1 #define LT_HAS_MBEDTLS 1 -#define LT_HEAP_FUNC xPortGetFreeHeapSize +#define LT_HEAP_FUNC xPortGetFreeHeapSize +#define LT_REALLOC_FUNC pvPortRealloc diff --git a/cores/common/base/fixups/malloc.c b/cores/common/base/fixups/malloc.c new file mode 100644 index 0000000..95c78b4 --- /dev/null +++ b/cores/common/base/fixups/malloc.c @@ -0,0 +1,68 @@ +/* Copyright (c) Kuba SzczodrzyƄski 2023-03-03. */ + +// Generic implementation of malloc() family wrappers for FreeRTOS + +#if LT_HAS_FREERTOS + +#include +#include +#include + +#include + +// no such thing in FreeRTOS, but present on most vendor SDKs +extern void *LT_REALLOC_FUNC(void *pv, size_t xWantedSize); + +void *__wrap_malloc(size_t size) { + return pvPortMalloc(size); +} + +void *__wrap_calloc(size_t num, size_t size) { + void *ptr; + if (num == 0 || size == 0) + num = size = 1; + ptr = pvPortMalloc(num * size); + if (ptr) + memset(ptr, 0, num * size); + return ptr; +} + +void *__wrap_realloc(void *ptr, size_t new_size) { + return LT_REALLOC_FUNC(ptr, new_size); +} + +void __wrap_free(void *ptr) { + vPortFree(ptr); +} + +void *__wrap__malloc_r(void *reent, size_t size) { + return pvPortMalloc(size); +} + +void *__wrap__calloc_r(void *reent, size_t num, size_t size) { + void *ptr; + if (num == 0 || size == 0) + num = size = 1; + ptr = pvPortMalloc(num * size); + if (ptr) + memset(ptr, 0, num * size); + return ptr; +} + +void *__wrap__realloc_r(void *reent, void *ptr, size_t new_size) { + return LT_REALLOC_FUNC(ptr, new_size); +} + +void __wrap__free_r(void *reent, void *ptr) { + vPortFree(ptr); +} + +#endif + +// Additionally, define zalloc() as a shorthand to calloc() - some implementation use it + +void *__wrap_zalloc(size_t size) { + return __wrap_calloc(1, size); +} + +__attribute__((alias("__wrap_zalloc"), weak)) void *zalloc(size_t size); diff --git a/cores/realtek-amb/base/lt_defs.h b/cores/realtek-amb/base/lt_defs.h index 1e33567..e6250ff 100644 --- a/cores/realtek-amb/base/lt_defs.h +++ b/cores/realtek-amb/base/lt_defs.h @@ -4,4 +4,5 @@ #define LT_HAS_PRINTF 1 -#define LT_HEAP_FUNC xPortGetFreeHeapSize +#define LT_HEAP_FUNC xPortGetFreeHeapSize +#define LT_REALLOC_FUNC pvPortReAlloc diff --git a/docs/dev/stdlib.md b/docs/dev/stdlib.md index 54184da..cbe3082 100644 --- a/docs/dev/stdlib.md +++ b/docs/dev/stdlib.md @@ -4,7 +4,7 @@ Usually, functions available in C standard library should not be defined by the The following functions must not be defined by the SDK. Their presence makes conflicts due to incompatibility with C library, so they should be removed or disabled, and replaced with wrappers. -Memory management functions should be wrapped and redirected to FreeRTOS (if possible). +Memory management functions should be wrapped and redirected to FreeRTOS (if possible). The necessary linker flags are added for all families (in `base.py`), and a FreeRTOS implementation of the wrappers are provided in `malloc.c` in the common core. Additionally, if the `printf` library is used in the chip family code, all other vendor-defined printf-like functions should be replaced with it.