2026-02-10 12:14 AM - last edited on 2026-02-10 6:04 AM by TDK
Hello,
I was trying to create two heap regions, sing internal RAM and external SRAM. So I tried below, but the code at some point crash and generate hardfault error. Just want to know does the procedure is correct or am I missing something?
//in .ld file
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 512K
EXT_SRAM (xrw) : ORIGIN = 0x60000000, LENGTH = 512K
EXT_PSRAM(xrw) : ORIGIN = 0x6C000000, LENGTH = 8M
}
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */
_Min_Heap_Size = 0x0;
_Min_Stack_Size = 0x400;
._user_heap_stack (NOLOAD) :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
.heap_internal (NOLOAD):
{
. = ALIGN(8);
_heap_internal_start = .;
. = . + 0x2000; /* 8 KB internal heap */
_heap_internal_end = .;
. = ALIGN(8);
} >RAM
.heap_ext (NOLOAD) :
{
. = ALIGN(8);
_heap_start = .;
. = . + 0x40000; /* 256 KB for heap */
_heap_end = .;
. = ALIGN(8);
} >EXT_SRAM
/* ========== Stack in External SRAM ========= */
.stack_ext (NOLOAD) :
{
. = ALIGN(8);
_ext_stack_start = .;
. = . + 0x40000; /* 256 KB for stack */
_ext_stack_end = .;
. = ALIGN(8);
} >EXT_SRAM
The I create external_heap.c file to manage the heap regions
#define EXTERNAL_HEAP_SIZE (400 * 1024) // 400 KB
#define INTERNAL_HEAP_SIZE (8 * 1024) // 8 KB
extern uint8_t _heap_internal_start;
extern uint8_t _heap_internal_end;
extern uint8_t _heap_start;
extern uint8_t _heap_end;
HeapRegion_t xHeapRegions[] =
{
{ &_heap_internal_start, (size_t)(INTERNAL_HEAP_SIZE) },
{ &_heap_start, (size_t)(EXTERNAL_HEAP_SIZE) },
{ NULL, 0 }
};
To allow to use this xHeapRegions[] array I have set some macros as below for heap_5.c, as per my understanding this will allow me to define custom heap regions.
#define USE_FREERTOS_HEAP_5
#define configHEAP_5_REGIONS
#if defined(USE_FREERTOS_HEAP_5)
#if (configAPPLICATION_ALLOCATED_HEAP == 0)
/*
FreeRTOS heap is not defined by the application.
Single region of size configTOTAL_HEAP_SIZE (defined in FreeRTOSConfig.h)
is provided by default. Define configHEAP_5_REGIONS to provide custom
HeapRegion_t array.
*/
#define HEAP_5_REGION_SETUP 1
#ifndef configHEAP_5_REGIONS
#define configHEAP_5_REGIONS xHeapRegions
static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
static HeapRegion_t xHeapRegions[] = {
{ ucHeap, configTOTAL_HEAP_SIZE },
{ NULL, 0 }
};
#else
/* Global definition is provided to override default heap array */
// extern HeapRegion_t configHEAP_5_REGIONS[];
#endif
#elseSo, help me out here, what I'm missing.
Thanks,
Nitin
Solved! Go to Solution.
2026-02-12 4:51 PM
One guess is that you might be trying to access external memory before it is set up.
2026-02-12 4:51 PM
One guess is that you might be trying to access external memory before it is set up.
2026-04-03 1:55 AM
Hello @npatil15
In the linker script, the external heap region was reserved as 0x40000 bytes (256 KB), but in the C code the external heap size was defined as 400 * 1024 bytes (400 KB). This mismatch means that FreeRTOS may allocate memory beyond the 256 KB actually reserved in the linker, overwriting whatever follows that region in external SRAM and eventually causing a HardFault.
To avoid this, the heap size defined in C must match exactly the size reserved in the linker script (either change the linker to 400 KB or adjust the C constant to 256 KB) so that all heap allocations stay within valid memory.
2026-04-05 9:08 PM
Thanks for observations, this change is also a culprit among those changes. And also, as @_EFrie suggested, I was accessing external memory without using Loader programme, which used to load program to external memory and only that way I can run the code from external memory and so continue to use Heap as well.