Skip to content

Commit

Permalink
Use all free RAM for FreeRTOS heap
Browse files Browse the repository at this point in the history
* Use all free RAM for FreeRTOS heap
* Wrap newlib malloc and related functions
* Implement calloc
  • Loading branch information
pipe01 authored Dec 9, 2024
1 parent 2105a7b commit b8c51ab
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 20 deletions.
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
28 changes: 16 additions & 12 deletions src/FreeRTOS/heap_4_infinitime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/FreeRTOS/portmacro_cmsis.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ __STATIC_INLINE uint32_t ulPortRaiseBASEPRI( void )

/*-----------------------------------------------------------*/

size_t xPortGetHeapSize(void);

#ifdef __cplusplus
}
Expand Down
1 change: 0 additions & 1 deletion src/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/displayapp/screens/SystemInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -209,6 +209,7 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen3() {
spiFlashId.type,
spiFlashId.density,
xPortGetFreeHeapSize(),
xPortGetHeapSize(),
xPortGetMinimumEverFreeHeapSize(),
mallocFailedCount,
stackOverflowCount);
Expand Down
49 changes: 49 additions & 0 deletions src/libs/lfs_config.h
Original file line number Diff line number Diff line change
@@ -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>
36 changes: 30 additions & 6 deletions src/stdlib.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdlib.h>
#include <string.h>
#include <FreeRTOS.h>

// Override malloc() and free() to use the memory manager from FreeRTOS.
Expand All @@ -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);
}

0 comments on commit b8c51ab

Please sign in to comment.