How to configure the Total Heap Size

jeanalban wrote on Thursday, March 12, 2015:

Hello everybody,

I want to dimension the total heap size of freeRTOS with configTOTAL_HEAP_SIZE.

I use a STMF32F4 microcontroller, featuring:

  • 192KB of SRAM
  • 64KB of CCM RAM (core coupled memory) (I use this memory in my code to init my static variables)

For the moment, I configure configTOTAL_HEAP_SIZE to 102400 bytes

I want to increase the total heap size of freeRTOS because I want more memory space. Are my static variables included in the heap size? Can I set the TOTAL_HEAP_SIZE to 192000KB for example?

Thanks a lot,
Have a good day,
Jean

heinbali01 wrote on Thursday, March 12, 2015:

Hi Jean,

Which heap_x.c are you using?

You will find this declaration in versions 1, 2 and 4:

static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];

That is the heap space.

You can make this configTOTAL_HEAP_SIZE as big as you want, the linker will issue an error when you’re running out of RAM.

Another possibility is to use heap_5.c. Right after starting-up, and before the first call to pvPortMalloc(), you will have to call:

void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions );

to add the heap regions. Depending on the compiler used, you can calculate the amount of RAM memory dynamically.

Note that, depending on the compiler you’re using, some standard functions may still call the the malloc/free couple.

Often I declare these functions, making sure that they have a C-linking (and not a C++ linking):

extern void non_existent_function( void );

void *malloc( size_t size )
{
    ( void ) size;
    non_existent_function();
    return NULL;
}

void free( void *pvMemory )
{
    ( void ) pvMemory;
    non_existent_function();
}

Now if I call e.g. gmtime(), there will be a linking error because non_existent_function could not be found.

Regards.

jeanalban wrote on Friday, March 13, 2015:

Hi Hein,

Thanks a lot! I defined configTOTAL_HEAP_SIZE to (180*1024) Bytes, this is the maximum value my linker accepts.

This value is very close the RAM space (192KB) of my microcontroller.

I have another question: which use the rest of memory space? The rest of the memory should be 192000-(180*1024) = 7280 bytes. Is it freeRTOS?

rtel wrote on Friday, March 13, 2015:

FreeRTOS itself uses very approximately 200 to 300 bytes. Task stacks
come from the heap.

You would have to ask your compiler where the rest of the RAM is going.
The easiest way of doing that it to look at the map file - it will
tell you how much RAM each section is taking (.bss, .data, etc.) and
what in those sections is using RAM. That is a C question though, not a
FreeRTOS question - the things that take up RAM in a non-RTOS
application (static variables, statically allocated DMA or network
buffers, etc.) will be the same things taking up RAM when you add
FreeRTOS into the build.

Regards.

heinbali01 wrote on Friday, March 13, 2015:

Hello Jean,

I have another question: which use the rest of memory space?
The rest of the memory should be 192000-(180*1024) = 7280 bytes.
Is it freeRTOS?

Yes partly. FreeRTOS has some static declarations.

The RAM is normally divided among these:

  • Static and global variables
  • Any code located in RAM
  • A heap to be accessed by the standard malloc()/free()
  • A stack which is used until the scheduler will start

In your project you will probably find a file describing the layout for the linker, e.g. “stm32F40.ld”.
It describes all memories and it tells were to put the stack and heap (if any).

The linker file defines symbols like e.g. ‘_ebss’ which you can declare in your code:

extern char _ebss;

The address of ‘_ebss’ can be used within your code to dynamically determine how much free RAM is actually left. That would be useful if you use “heap_5.c”.

But the following is much simpler and it is also safe:

#define configTOTAL_HEAP_SIZE  ( 180 * 1024 )

because the linker will fail when it doesn’t fit any more.

Regards, Hein

1 Like

jeanalban wrote on Tuesday, March 17, 2015:

Hello RTE, Hello Hein,

Thanks a lot for your precious answers! I understand that I have a lot of static and global variables in my RAM, that reduces the heap space. I moved these variables to the CCM memory to expand the heap space: it works!

I have a trouble with my debugger: when I set the maximum heap size (180 * 1024), I can’t watch my variables anymore in the debug mode. My variables are all equal to ‘0’. But when I reduce the heap size (120 * 1024) I can watch my variables again.

I guess that it’s because the debug mode use a lot of space in the RAM memory, although I have configured the linker to “debug in flash”.

Do you ever experienced this kind of trouble? For your information I use Coocox + GNU Tools ARM Embedded + ST Link + STM32F427.

Have a good day!

rtel wrote on Tuesday, March 17, 2015:

Sorry - I have no experience with the Coocox tools.

Regards.