diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0a97a0158b..e2b69b8b02 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -788,6 +788,10 @@ add_definitions(-DFREERTOS) add_definitions(-D__STACK_SIZE=1024) add_definitions(-D__HEAP_SIZE=0) add_definitions(-DMYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME=1500) +add_definitions(-DLFS_CONFIG=libs/lfs_config.h) + +# _sbrk is purposefully not implemented so that builds fail when it is used +add_link_options(-Wl,-wrap=malloc -Wl,-wrap=free -Wl,-wrap=calloc -Wl,-wrap=realloc -Wl,-wrap=_malloc_r -Wl,-wrap=_sbrk) # Note: Only use this for debugging # Derive the low frequency clock from the main clock (SYNT) diff --git a/src/FreeRTOS/heap_4_infinitime.c b/src/FreeRTOS/heap_4_infinitime.c index 1470847114..bf6492545a 100644 --- a/src/FreeRTOS/heap_4_infinitime.c +++ b/src/FreeRTOS/heap_4_infinitime.c @@ -60,15 +60,6 @@ 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 */ - /* Define the linked list structure. This is used to link free blocks in order of their memory address. */ typedef struct A_BLOCK_LINK @@ -113,6 +104,8 @@ application. When the bit is free the block is still part of the free heap space. */ static size_t xBlockAllocatedBit = 0; +static size_t xHeapSize = 0; + /*-----------------------------------------------------------*/ void *pvPortMalloc( size_t xWantedSize ) @@ -332,27 +325,38 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) } /*-----------------------------------------------------------*/ +size_t xPortGetHeapSize( void ) +{ + return xHeapSize; +} +/*-----------------------------------------------------------*/ + void vPortInitialiseBlocks( void ) { /* This just exists to keep the linker quiet. */ } /*-----------------------------------------------------------*/ +extern uint8_t *__HeapLimit; // Defined by nrf_common.ld + static void prvHeapInit( void ) { BlockLink_t *pxFirstFreeBlock; uint8_t *pucAlignedHeap; size_t uxAddress; - size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; + size_t xTotalHeapSize = ( size_t ) &__StackLimit - ( size_t ) &__HeapLimit; + uint8_t *pucHeap = ( uint8_t * ) &__HeapLimit; + + xHeapSize = xTotalHeapSize; /* Ensure the heap starts on a correctly aligned boundary. */ - uxAddress = ( size_t ) ucHeap; + uxAddress = ( size_t ) pucHeap; if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( portBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); - xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; + xTotalHeapSize -= uxAddress - ( size_t ) pucHeap; } pucAlignedHeap = ( uint8_t * ) uxAddress; diff --git a/src/FreeRTOS/portmacro_cmsis.h b/src/FreeRTOS/portmacro_cmsis.h index e6e09158a7..d165d17135 100644 --- a/src/FreeRTOS/portmacro_cmsis.h +++ b/src/FreeRTOS/portmacro_cmsis.h @@ -180,6 +180,7 @@ __STATIC_INLINE uint32_t ulPortRaiseBASEPRI( void ) /*-----------------------------------------------------------*/ +size_t xPortGetHeapSize(void); #ifdef __cplusplus } diff --git a/src/FreeRTOSConfig.h b/src/FreeRTOSConfig.h index 67c33a34cc..d877705a70 100644 --- a/src/FreeRTOSConfig.h +++ b/src/FreeRTOSConfig.h @@ -62,7 +62,6 @@ #define configTICK_RATE_HZ 1024 #define configMAX_PRIORITIES (3) #define configMINIMAL_STACK_SIZE (120) -#define configTOTAL_HEAP_SIZE (1024 * 40) #define configMAX_TASK_NAME_LEN (4) #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index d265fddd5b..886dacb6c6 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -195,7 +195,7 @@ std::unique_ptr SystemInfo::CreateScreen3() { "#808080 SPI Flash# %02x-%02x-%02x\n" "\n" "#808080 Memory heap#\n" - " #808080 Free# %d\n" + " #808080 Free# %d/%d\n" " #808080 Min free# %d\n" " #808080 Alloc err# %d\n" " #808080 Ovrfl err# %d\n", @@ -209,6 +209,7 @@ std::unique_ptr SystemInfo::CreateScreen3() { spiFlashId.type, spiFlashId.density, xPortGetFreeHeapSize(), + xPortGetHeapSize(), xPortGetMinimumEverFreeHeapSize(), mallocFailedCount, stackOverflowCount); diff --git a/src/libs/lfs_config.h b/src/libs/lfs_config.h new file mode 100644 index 0000000000..eaeede0e63 --- /dev/null +++ b/src/libs/lfs_config.h @@ -0,0 +1,49 @@ +#pragma once + +#include + +#ifndef LFS_TRACE +#ifdef LFS_YES_TRACE +#define LFS_TRACE_(fmt, ...) \ + NRF_LOG_DEBUG("[LFS] %s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "") +#else +#define LFS_TRACE(...) +#endif +#endif + +#ifndef LFS_DEBUG +#ifndef LFS_NO_DEBUG +#define LFS_DEBUG_(fmt, ...) \ + NRF_LOG_DEBUG("[LFS] %s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS_DEBUG(...) LFS_DEBUG_(__VA_ARGS__, "") +#else +#define LFS_DEBUG(...) +#endif +#endif + +#ifndef LFS_WARN +#ifndef LFS_NO_WARN +#define LFS_WARN_(fmt, ...) \ + NRF_LOG_WARNING("[LFS] %s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS_WARN(...) LFS_WARN_(__VA_ARGS__, "") +#else +#define LFS_WARN(...) +#endif +#endif + +#ifndef LFS_ERROR +#ifndef LFS_NO_ERROR +#define LFS_ERROR_(fmt, ...) \ + NRF_LOG_ERROR("[LFS] %s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS_ERROR(...) LFS_ERROR_(__VA_ARGS__, "") +#else +#define LFS_ERROR(...) +#endif +#endif + +// This is required in order for the CRC implementation in littlefs/lfs_util.c to be compiled +#undef LFS_CONFIG + +#undef LFS_UTIL_H +#include diff --git a/src/stdlib.c b/src/stdlib.c index 3ad66b3781..21b506a843 100644 --- a/src/stdlib.c +++ b/src/stdlib.c @@ -1,4 +1,5 @@ #include +#include #include // Override malloc() and free() to use the memory manager from FreeRTOS. @@ -10,18 +11,41 @@ void* malloc(size_t size) { return pvPortMalloc(size); } +void* __wrap_malloc(size_t size) { + return malloc(size); +} + +void* __wrap__malloc_r(struct _reent* reent, size_t size) { + (void) reent; + return malloc(size); +} + void free(void* ptr) { vPortFree(ptr); } +void __wrap_free(void* ptr) { + free(ptr); +} + void* calloc(size_t num, size_t size) { - (void)(num); - (void)(size); - // Not supported - return NULL; + void *ptr = malloc(num * size); + if (ptr) { + memset(ptr, 0, num * size); + } + return ptr; } -void *pvPortRealloc(void *ptr, size_t xWantedSize); -void* realloc( void *ptr, size_t newSize) { +void* __wrap_calloc(size_t num, size_t size) { + return calloc(num, size); +} + +void* pvPortRealloc(void* ptr, size_t xWantedSize); + +void* realloc(void* ptr, size_t newSize) { return pvPortRealloc(ptr, newSize); } + +void* __wrap_realloc(void* ptr, size_t newSize) { + return realloc(ptr, newSize); +}