FreeRTOS Memory Management
Heap, Stack, and static/ dynamic memory allocation.
NetX 90 Memory Layout
Our provided memory layout for the netX 90 is displayed on the right. The different segments are typically used for:
Text Segment: contains executable instructions.
Initialized Data Segment: contains initialized (global, static) data.
Uninitialized Data Segment: also knows as block started by symbol (bss), contains uninitialized (global, static) data or data that is initialized to zero. Data in this segment is initialized by the kernel to arithmetic 0 before the program starts executing.
Stack: The stack is a least-in-first-out (LIFO) structure that stores temporary data. It can be accessed by using the “push” and “pop” operators.
Heap: The heap is a dynamic memory segment and can be accessed by using the “malloc“ and “free” operators. In generals, the stack is significantly faster for small data structures. This is the reason why the heap is mostly used for larger temporary data structures. Another downside of the heap are memory holes.
You might also see netX 90 - Stack and Heap.
Stack-overflow
If the stack is full and a push operation is executed, the stack is considered to be in an overflow state and may override data on the heap.
Why it is Important when using FreeRTOS
Each task has its own dedicated stack. How and where you place that stack, is up to you!
A typical implementation would be to place the task stack and other FreeRTOS objects (queues, semaphores, mutexes, etc.) dynamically on the memory heap (see xTaskCreate). If you don't want that, you can use the static implementation option xTaskCreateStatic (more information can be founder at static vs dynamic memory allocation).
If you still want to use the convenience of a heap, FreeRTOS offers various implementation options, you could take an independent implementation, or you can implement your own.
Official FreeRTOS Heap Implementations
FreeRTOS provides multiple heap memory allocation implementations, which do not require a standard library, and you can use out of the box. But, in many netX 90 example projects, we use the standard library newlib c, which is not yet using reentrant/ tread-safe calls. This is an inconvenience which, thankfully, others had before.
Independent FreeRTOS Heap Implementation
If you plan to use heap functionalities from newlib, you might want to implement the newlib functions reentrant/ thread-safe in the first place. The reentrant/ tread-safe implementation can then be used for FreeRTOS as well. A good read is newlib and FreeRTOS. In case you wish to use newlib, the following line needs to be added (the operating system creates then an impure pointer for each task, which is required for a reentrant useage of newlib).
#define configUSE_NEWLIB_REENTRANT 1