Memory Protection Unit (MPU) Support
FreeRTOS includes two ports for ARM Cortex-M3 microcontrollers - the standard FreeRTOS port and FreeRTOS-MPU.
FreeRTOS-MPU includes integrated memory protection.
Using a Memory Protection Unit (MPU) can protect applications from a number of potential errors, ranging
from undetected programming errors to errors introduced by system or hardware failures. FreeRTOS-MPU can
be used to protect the RTOS kernel itself from invalid execution by tasks and protect data from corruption.
It can also protect system peripherals from unintended modification by tasks and guarantee the detection
of task stack overflows.
The LPC17xx edition of the FreeRTOS eBook
contains a chapter on using FreeRTOS-MPU. The demo projects located in the FreeRTOS/Demo/CORTEX_MPU_LPC1768_GCC_RedSuite and
FreeRTOS/Demo/CORTEX_MPU_LM3Sxxxx_Rowley directories of the main FreeRTOS download demonstrate the use of FreeRTOS-MPU on
NXP LPC1768 and Luminary Micro/TI Stellaris microcontrollers respectively.
Backward compatible with the standard ARM Cortex-M3 port and FreeRTOS V5.x.x
Tasks can be created to run in either Privileged mode or User mode. User mode tasks can only
access their own stack and up to three user definable memory regions (three per task).
User definable memory regions are assigned to tasks when the task is created, but can then
be reconfigured at run time if required.
User definable memory regions can be parameterised individually.
For example, some regions may be set to read only, while others may be set to not executable
(execute never, or simply XN, in ARM terminology), etc.
No data memory is shared between User mode tasks, but User mode tasks can pass messages to
each other using the standard queue and semaphore mechanisms. Shared memory regions can be
explicitly created by using a user definable memory region but this is discouraged.
A Privileged mode task can set itself into User mode, but once in User mode it cannot set
itself back to Privileged mode.
The FreeRTOS API is located in a region of Flash that can only be accessed while the microcontroller
is in Privileged mode (calling an API function causes a temporary switch to Privilege mode).
The data maintained by the RTOS kernel (all non stack data that is private to the FreeRTOS source files)
is located in a region of RAM that can only be accessed while the microcontroller is in Privileged
System peripherals can only be accessed while the microcontroller is in Privileged mode. Standard
peripherals (UARTs, etc.) are accessible by any code but can be explicitly protected using a user
definable memory region.
Creating Restricted (protected) Tasks
Tasks that don't make use of the MPU can be created using the standard xTaskCreate() API function. The
created task can run in either Privileged or User modes. When Privileged mode it used the task will have
access to the entire memory map, when User mode is used the task will have access to only its stack. In
both cases the MPU will not automatically catch stack overflows, although the standard FreeRTOS
stack overflow detection
schemes can still be used. See the xTaskCreate() API
documentation for more information.
If a task wants to use the MPU then the following additional information has to be provided:
The total number of parameters required to create a task is therefore quite large. To make creating
MPU aware tasks easier FreeRTOS-MPU introduces a new API function called
This allows all but one of the parameters to be defined in a const struct, with the struct being passed
(by reference) into xTaskCreateRestricted() as a single parameter.
- The address of the task stack.
- The start, size and access parameters for up to three user definable memory regions.
Tasks created using xTaskCreateRestricted()
can also be created to execute in either Privileged mode
or User mode - but this time User mode tasks have access to their user defined memory regions in addition
to their stack. A Privileged mode task can call
portSWITCH_TO_USER_MODE() to set
itself into User mode. A task that is running in User mode cannot set itself into Privileged mode.
The memory regions allocated to a task can be changed using
vTaskAllocateMPURegions(). See the
xTaskCreateRestricted() and vTaskAllocateMPURegions() API documentation for more information.
Additional Information and Learning More
The LPC17xx edition of the FreeRTOS eBook
contains a chapter on using FreeRTOS-MPU.
Another way of learning more about FreeRTOS-MPU is to inspect and hopefully step through one of the
heavily commented FreeRTOS-MPU demonstration projects. These can be located in the
FreeRTOS/Demo/CORTEX_MPU_LM3Sxxxx_Rowley and FreeRTOS/Demo/CORTEX_MPU_LPC1768_GCC_RedSuite
directories for Rowley CrossWorks and LPCXpresso IDEs (Red Suite is no longer available
but the LPCXpresso IDE can be used in its place) respectively. Both projects demonstrate how to
configure, create and use restricted mode tasks and contain code that can be uncommented to see
the MPU working in practice.
A couple of points to note in the demo projects:
- Both projects use the linker script to defined both a Flash and a RAM region that can
only be accessed while the microcontroller is in privileged mode. The C startup code has
been altered to initialised the RAM region to zero before main() is called (the standard
C start up code only initialised the BSS section).
- The Idle task executes in Privileged mode.
- taskYIELD() must not be called from within a critical section.
Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 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.