...
Heap, Stack, and static/ dynamic memory allocation.
Heap/ Stack
The program’s machine instructions (e.g., executable code) are stored in the text area. Global and static data are stored in initialized/ uninitialized data. The “malloc” operator allocates memory on the heap and can be released with the “free” operator. Therefore, memory allocated on the heap is always where space is left. Memory holes are the consequence. The stack contains all the automatic, non-static variables and is implemented as “least in first out” structure. The operator “push” allocates memory on the stack, “pop” releases the last allocated element from the stack.
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 convinience 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
...
static vs dynmic memory allocation
...
reentrant/ tread-safe calls. this is an inconvinience 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.