Use all free RAM for FreeRTOS heap

* Use all free RAM for FreeRTOS heap
* Wrap newlib malloc and related functions
* Implement calloc
This commit is contained in:
Felipe Martínez 2024-12-09 01:10:09 +01:00 committed by GitHub
parent 2105a7b63d
commit b8c51abe69
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 103 additions and 21 deletions

View File

@ -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)

View File

@ -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;

View File

@ -180,6 +180,7 @@ __STATIC_INLINE uint32_t ulPortRaiseBASEPRI( void )
/*-----------------------------------------------------------*/
size_t xPortGetHeapSize(void);
#ifdef __cplusplus
}

View File

@ -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

View File

@ -195,7 +195,7 @@ std::unique_ptr<Screen> 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<Screen> SystemInfo::CreateScreen3() {
spiFlashId.type,
spiFlashId.density,
xPortGetFreeHeapSize(),
xPortGetHeapSize(),
xPortGetMinimumEverFreeHeapSize(),
mallocFailedCount,
stackOverflowCount);

49
src/libs/lfs_config.h Normal file
View File

@ -0,0 +1,49 @@
#pragma once
#include <libraries/log/nrf_log.h>
#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 <littlefs/lfs_util.h>

View File

@ -1,4 +1,5 @@
#include <stdlib.h>
#include <string.h>
#include <FreeRTOS.h>
// 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* calloc(size_t num, size_t size) {
(void)(num);
(void)(size);
// Not supported
return NULL;
void __wrap_free(void* ptr) {
free(ptr);
}
void *pvPortRealloc(void *ptr, size_t xWantedSize);
void* realloc( void *ptr, size_t newSize) {
void* calloc(size_t num, size_t size) {
void *ptr = malloc(num * size);
if (ptr) {
memset(ptr, 0, num * size);
}
return ptr;
}
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);
}