Heap calculation

taugustinus wrote on Monday, September 04, 2006:

I have read the pages regarding memory allocation, but the real heap use on the target is quite a bit higher than expected - I hope You can help me understand why.

Port: ARM on LPC2000

When I do not start any tasks - just start the scheduler - and then stop the target, the xNextFreeByte is 580. If I start one task with minimal task size of 128, I get 1160 (ie. 580 bytes extra). Starting two tasks results in 1740 (ie. 2x580bytes).

Here are my settings:

#define configUSE_PREEMPTION  1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ  ( ( unsigned portLONG ) 49152000 ) /* 12.288MHz*4 */
#define configTICK_RATE_HZ  ( ( portTickType ) 100 )
#define configMAX_PRIORITIES  ( ( unsigned portBASE_TYPE ) 4 )
#define configMINIMAL_STACK_SIZE  ( ( unsigned portSHORT ) 128 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) 4024 )
          //Allocate 83 for scheduler
          //Allocate 16 per priority
          //Allocate 26+stacksize per task
          //Allocate 45+queuesize per queue
#define configMAX_TASK_NAME_LEN ( 8 )
#define configUSE_TRACE_FACILITY  0
#define configUSE_16_BIT_TICKS  0
#define configIDLE_SHOULD_YIELD 1

// - Co-routine definitions -
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

I hope You can help me understand


Thomas Augustinus

nobody wrote on Monday, September 04, 2006:

Starting the scheduler will automatically create the idle task which is way some heap space is taken.

A stack size of 128 on ARM will result in 128 * 4 bytes being used, as each stack item is byte byts (32bits).  The little extra allocated is due to the allocation of the TCB for the task.

nobody wrote on Monday, September 04, 2006:

stack depth is defined in 32bit words, so you have 128 * 4 + memory for task list element. Minimal stack of thread is 18 (16 32bit-registers R0-R15, SPSR and nesting word) I think.

P.S. Please about confirmation…

taugustinus wrote on Monday, September 04, 2006:

Thanks for Your replies!

You are ofcause right - it all adds up…

I have now looked at the code and found that the following is the case on ARM - so others may avoid tearing their hair out :slight_smile:

The stack is allocated as a tskTCB struct - 68 bytes + TaskStackSize*portLONG which is defined as long that again is a signed 32-bit on ARM.

So each task takes up 68+stack*4 bytes.

Thanks for the hint.

Best Regards
Thomas Augustinus

taugustinus wrote on Monday, September 04, 2006:

Regarding the minimum stack size -
And the minimum stack use appears to be 79bytes on the ARM - ie. 20 32-bit words.

It is purely experimental (the pxCurrentTCB turned out to be a valuable tool) tested with an empty task ( void task(void*){while(1){}} ).

So, You were right Janusz :slight_smile: