cancel
Showing results for 
Search instead for 
Did you mean: 

How to create Internal plus external heap using SRAM in FreeRTOS

npatil15
Senior

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
#else

So, help me out here, what I'm missing.

Thanks,

Nitin

 

1 ACCEPTED SOLUTION

Accepted Solutions
_EFrie
Senior

One guess is that you might be trying to access external memory before it is set up.

View solution in original post

3 REPLIES 3
_EFrie
Senior

One guess is that you might be trying to access external memory before it is set up.

Saket_Om
ST Employee

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.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

@Saket_Om ,

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.