Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs Books & Kits Visualisation Ecosystem Training Contact & Support




Last site update Jan 14 2014

Memory Management
[More Advanced]

FreeRTOS offers several heap management schemes that range in complexity and features - the simplest of which can sometimes even meet the requirements of systems that do not permit dynamic memory allocation. It is also possible to provide your own heap implementation.

The RTOS kernel allocates RAM each time a task, queue, mutex, software timer, semaphore or event group is created. The standard C library malloc() and free() functions can sometimes be used for this purpose, but ...

  1. they are not always available on embedded systems,

  2. they take up valuable code space,

  3. they are not thread safe, and

  4. they are not deterministic (the amount of time taken to execute the function will differ from call to call)

... so more often than not an alternative memory allocation implementation is required.

One embedded / real time system can have very different RAM and timing requirements to another - so a single RAM allocation algorithm will only ever be appropriate for a subset of applications.

To get around this problem, FreeRTOS keeps the memory allocation API in its portable layer. The portable layer is outside of the source files that implement the core RTOS functionality, allowing an application specific implementation appropriate for the real time system being developed to be provided. When the RTOS kernel requires RAM, instead of calling malloc(), it instead calls pvPortMalloc(). When RAM is being freed, instead of calling free(), the RTOS kernel calls vPortFree().

Memory allocation implementations included in the RTOS source code download

The FreeRTOS download includes four sample memory allocation implementations, each of which are described in the following subsections. The subsections also include information on when each of the provided implementations might be the most appropriate to select.

Each provided implementation is contained in a separate source file (heap_1.c, heap_2.c, heap_3.c and heap_4.c respectively) which are located in the Source/Portable/MemMang directory of the main RTOS source code download. Other implementations can be added as needed. Exactly one of these source files should be included in a project at a time.


heap_1.c

This is the simplest implementation of all. It does not permit memory to be freed once it has been allocated. Despite this, heap_1.c is appropriate for a large number of embedded applications. This is because the majority of deeply embedded applications create all the tasks, queues, semaphores, etc. required when the system boots, and then use all of these objects for the lifetime of program (until the application is switched off again, or is rebooted). Nothing ever gets deleted.

The implementation simply subdivides a single array into smaller blocks as RAM is requested. The total size of the array (the total size of the heap) is set by configTOTAL_HEAP_SIZE - which is defined in FreeRTOSConfig.h.

The xPortGetFreeHeapSize() API function returns the total amount of heap space that remains unallocated, allowing the configTOTAL_HEAP_SIZE setting to be optimised.

The heap_1 implementation:

  • Can be used if your application never deletes a task, queue, semaphore, mutex, etc. (which actually covers the majority of applications in which FreeRTOS gets used).

  • Is always deterministic (always takes the same amount of time to execute) and cannot result in memory fragmentation.

  • Is very simple and allocated memory from a statically allocated array, meaning it is often suitable for use in applications that do not permit true dynamic memory allocation.


heap_2.c

This scheme uses a best fit algorithm and, unlike scheme 1, allows previously allocated blocks to be freed. It does not however combine adjacent free blocks into a single large block (it does not include a coalescence algorithm - see heap_4.c for an implementation that does coalescence free blocks).

The total amount of available heap space is set by configTOTAL_HEAP_SIZE - which is defined in FreeRTOSConfig.h.

The xPortGetFreeHeapSize() API function returns the total amount of heap space that remains unallocated (allowing the configTOTAL_HEAP_SIZE setting to be optimised), but does not provided information on how the unallocated memory is fragmented into smaller blocks.

This implementation:

  • Can be used even when the application repeatedly deletes tasks, queues, semaphores, mutexes, etc., with the caveat below regarding memory fragmentation.

  • Should not be used if the memory being allocated and freed is of a random size. For example:
    • If an application dynamically creates and deletes tasks, and the size of the stack allocated to the tasks being created is always the same, then heap2.c can be used in most cases. However, if the size of the stack allocated to the tasks being created was not always the same, then the available free memory might become fragmented into many small blocks, eventually resulting in allocation failures. heap_4.c would be a better choise in this case.

    • If an application dynamically creates and deletes queues, and the queue storage area is the same in each case (the queue storage area is the queue item size multiplied by the length of the queue), then heap_2.c can be used in most cases. However, if the queue storage area were not the same in each case, then the available free memory might become fragmented into many small blocks, eventually resulting in allocation failures. heap_4.c would be a better choise in this case.

    • The application called pvPortMalloc() and vPortFree() directly, rather than just indirectly through other FreeRTOS API functions.

  • Could possible result in memory fragmentation problems if your application queues, tasks, semaphores, mutexes, etc. in an unpredictable order. This would be unlikely for nearly all applications but should be kept in mind.

  • Is not deterministic - but is much more efficient that most standard C library malloc implementations.

heap_2.c is suitable for most small real time systems that have to dynamically create tasks.


heap_3.c

This implements a simple wrapper for the standard C library malloc() and free() functions that will, in most cases, be supplied with your chosen compiler. The wrapper simply makes the malloc() and free() functions thread safe.

This implementation:

  • Requires the linker to setup a heap, and the compiler library to provide malloc() and free() implementations.

  • Is not deterministic.

  • Will probably considerably increase the RTOS kernel code size.

Note that the configTOTAL_HEAP_SIZE setting in FreeRTOSConfig.h has no effect when heap_3 is used.


heap_4.c

This scheme uses a first fit algorithm and, unlike scheme 2, does combine adjacent free memory blocks into a single large block (it does include a coalescence algorithm).

The total amount of available heap space is set by configTOTAL_HEAP_SIZE - which is defined in FreeRTOSConfig.h.

The xPortGetFreeHeapSize() API function returns the total amount of heap space that remains unallocated (allowing the configTOTAL_HEAP_SIZE setting to be optimised), but does not provided information on how the unallocated memory is fragmented into smaller blocks.

This implementation:

  • Can be used even when the application repeatedly deletes tasks, queues, semaphores, mutexes, etc..

  • Is much less likely than the heap_2 implementation to result in a heap space that is badly fragmented into multiple small blocks - even when the memory being allocated and freed is of random size.

  • Is not deterministic - but is much more efficient that most standard C library malloc implementations.

heap_4.c is particularly useful for applications that want to use the portable layer memory allocation schemes directly in the application code (rather than just indirectly by calling API functions that themselves call pvPortMalloc() and vPortFree()).





[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2013 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.