FreeRTOS needs a way to manage memory for tasks and resources. Different heap implementations help control how memory is allocated and freed.
FreeRTOS heap implementations (heap_1 to heap_5)
/* Example: heap_4.c partial structure and functions */ /* Define the heap size */ #define configTOTAL_HEAP_SIZE ((size_t)(10 * 1024)) /* Static array to hold the heap memory */ static uint8_t ucHeap[configTOTAL_HEAP_SIZE]; /* Function to allocate memory */ void *pvPortMalloc(size_t xSize); /* Function to free memory */ void vPortFree(void *pv); /* Function to initialize the heap */ void vPortInitialiseBlocks(void);
Each heap_x.c file implements these functions differently.
You include only one heap_x.c file in your project to select the heap method.
/* heap_1.c: Simple allocator, no free */ void *pvPortMalloc(size_t xSize) { static size_t xNextFreeByte = 0; if ((xNextFreeByte + xSize) <= configTOTAL_HEAP_SIZE) { void *pvReturn = &ucHeap[xNextFreeByte]; xNextFreeByte += xSize; return pvReturn; } else { return NULL; } } void vPortFree(void *pv) { /* Does nothing */ }
/* heap_2.c: Allocator with free but no coalescing */ /* Uses linked list to track free blocks but does not merge adjacent free blocks */
/* heap_4.c: Allocator with free and coalescing */ /* Uses linked list and merges adjacent free blocks to reduce fragmentation */
/* heap_5.c: Multiple heap regions */ /* Allows defining several separate memory regions to allocate from */
This program shows how heap_1 allocates memory until full, then fails. Free does nothing.
/* Sample FreeRTOS heap_1 usage example */ #include <stdio.h> #include <stdint.h> #include <stddef.h> #define configTOTAL_HEAP_SIZE ((size_t)(1024)) static uint8_t ucHeap[configTOTAL_HEAP_SIZE]; static size_t xNextFreeByte = 0; void *pvPortMalloc(size_t xSize) { if ((xNextFreeByte + xSize) <= configTOTAL_HEAP_SIZE) { void *pvReturn = &ucHeap[xNextFreeByte]; xNextFreeByte += xSize; return pvReturn; } else { return NULL; } } void vPortFree(void *pv) { /* heap_1 does not free memory */ } int main() { printf("Heap size: %zu bytes\n", configTOTAL_HEAP_SIZE); void *ptr1 = pvPortMalloc(100); printf("Allocated 100 bytes at %p\n", ptr1); void *ptr2 = pvPortMalloc(500); printf("Allocated 500 bytes at %p\n", ptr2); void *ptr3 = pvPortMalloc(500); if (ptr3 == NULL) { printf("Allocation of 500 bytes failed (not enough memory)\n"); } else { printf("Allocated 500 bytes at %p\n", ptr3); } vPortFree(ptr1); // Does nothing return 0; }
heap_1 is very simple but cannot free memory, so it is only good for static or simple use cases.
heap_4 is the most flexible and recommended for most applications because it supports freeing and reduces fragmentation.
heap_5 allows multiple memory regions, useful for complex memory layouts.
Time complexity for malloc in heap_4 is generally O(n) where n is number of free blocks.
Common mistake: Including more than one heap_x.c file causes linker errors.
Use heap_1 if you never free memory, heap_4 if you need full malloc/free support.
FreeRTOS provides five heap implementations named heap_1 to heap_5.
Each heap implementation offers different features for memory allocation and freeing.
Choose the heap implementation based on your application's memory management needs.
Practice
NOT support freeing allocated memory?Solution
Step 1: Understand heap_1 behavior
heap_1 only allows allocation but does not provide a function to free memory once allocated.Step 2: Compare with other heaps
heap_2, heap_3, and heap_4 all support freeing memory, with heap_3 using standard malloc/free.Final Answer:
heap_1 -> Option AQuick Check:
heap_1 no free support = heap_1 [OK]
- Confusing heap_1 with heap_2 which supports free
- Assuming all heaps support freeing memory
- Mixing heap_3's malloc/free with heap_1's behavior
Solution
Step 1: Check FreeRTOS heap file naming
Heap implementations are included by adding the corresponding .c file, e.g., "heap_3.c".Step 2: Verify correct syntax
Using #include "heap_3.c" is the standard way to include heap_3 in the build.Final Answer:
#include "heap_3.c" -> Option BQuick Check:
Include heap_3.c with quotes = D [OK]
- Using angle brackets instead of quotes
- Incorrect file name spelling or casing
- Trying to include a header instead of the .c file
void *ptr = pvPortMalloc(1000);
if(ptr == NULL) {
printf("Allocation failed\n");
} else {
printf("Allocation succeeded\n");
}Solution
Step 1: Understand heap_4 allocation behavior
heap_4 supports allocation and freeing with coalescing. If memory is insufficient, pvPortMalloc returns NULL.Step 2: Analyze the if condition
If ptr is NULL, the code prints "Allocation failed"; otherwise, it prints "Allocation succeeded".Final Answer:
Allocation failed -> Option CQuick Check:
pvPortMalloc NULL means failure = A [OK]
- Assuming allocation always succeeds
- Confusing NULL with zero pointer
- Ignoring the if condition logic
Solution
Step 1: Recall heap_2 features
heap_2 supports freeing memory via vPortFree(), but does not coalesce free blocks.Step 2: Identify common mistake
If memory is not freed, the most common cause is forgetting to call vPortFree() after allocation.Final Answer:
You forgot to call vPortFree() after allocation -> Option DQuick Check:
Missing vPortFree causes leaks = B [OK]
- Assuming heap_2 lacks free support
- Confusing heap_2 with heap_1 or heap_3
- Thinking heap_2 uses malloc/free internally
Solution
Step 1: Review heap features
heap_1 does not support freeing; heap_2 supports free but no coalescing; heap_4 supports free and coalesces adjacent free blocks; heap_5 extends heap_4 with multiple memory regions.Step 2: Match requirements
For minimizing fragmentation and real-time suitability, heap_4 is ideal as it coalesces free blocks and is deterministic.Final Answer:
heap_4 -> Option AQuick Check:
heap_4 coalesces free blocks = A [OK]
- Choosing heap_5 without needing multiple regions
- Assuming heap_2 coalesces free blocks
- Picking heap_1 which lacks free support
Ready to prove it?
Pass the test and this pattern moves unknown
