Hello,
Apologies if this is an elementary topic, but I am a bit confused as to the terms and the meanings used in a typical C program vs those used in a FreeRTOS context, and would like to clear them up. My setup is a Zybo Z7 board running FreeRTOS v10.0. I am using the heap_4.c file.
-
I understand that in a baremetal C program, the heap size specified in the linker script sets the upper bound of memory that can be allocated dynamically (during run time) by malloc(). The stack segment is used to hold function arguments and local variables during function calls, also during run time.
-
As per this thread (https://support.xilinx.com/s/question/0D52E00006hpUz3SAE/freertos-and-heap-and-memory-management?language=en_US), when using FreeRTOS with the heap_4.c scheme, the memory required for all tasks and kernel objects are statically allocated – ie, they live in the global segment of the memory (.bss) . Moreover, calls to pvPortMalloc() allocate memory from this already pre-allocated memory, so no memory from the heap segment is used. The max static memory allocated is controlled by the configTOTAL_HEAP_SIZE setting. The following experiment seems to confirm this being the case :
Heap size in linker.ld =0 + configTOTAL_HEAP_SIZE set to 64
text data bss dec hex filename
88796 4168 8576 101540 18ca4 test_malloc_pvPortMalloc.elf
Heap size in linker.ld =0 + configTOTAL_HEAP_SIZE set to 512
text data bss dec hex filename
88796 4168 9024 101988 18e64 test_malloc_pvPortMalloc.elf
The following line in heap_4.c also confirms that this is the case :
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
-
Following on from 2., this means we can technically allocate a heap of 0B in the linker script and then use pvPortMalloc() to allocate some memory and we should get a non-NULL pointer value to this memory.
-
From this thread (Heap clarification - FreeRTOS), the space for all task stack and kernel objects is statically allocated from the statically declared memory bound by configTOTAL_HEAP_SIZE. Does the task stack include space for local variables in function calls during calls? If so, then the actual ‘stack’ as in C parlance, doesn’t get used when running FreeRTOS. Is this a correct interpretation?
-
From (Effect of stack size and heap size value in the linker script (Xilinx Zynq SDK) - FreeRTOS), it looks like
a) The stack size in the linker script will be the stack given to the ‘main’ program (what runs pre-scheduler) and will be reused as the interrupt stack when the scheduler starts.
b) The heap size in the linker script will be the amount of heap available via the standard C malloc function (as opposed to the statically created memory for FreeRTOS tasks, objects and memory allocated via pvPortMalloc() that heap4.c provides)
Is this interpretation correct? -
Given the above, how do we interpret the distinction between ‘static’ and ‘dynamic’ allocation as discussed here (FreeRTOS Static Memory Allocation)? It looks like to me like all memory required for FreeRTOS tasks and objects are statically allocated (since I am using heap_4.c), with the scheme providing functionality of organizing the allocated memory to reduce fragmentation if tasks and/or objects get deleted.
Is this correct?
Apology for the long post. Thanks for the help!
yogesh
