Memory Protection Unit (MPU) Support
FreeRTOS includes two ports for ARM Cortex-M3 microcontrollers and two ports for
ARM Cortex-M4F 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 project in the
FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC directory, which uses Keil uVision
to build and simulate a GCC project, provides a worked worked example.
[The FreeRTOS-MPU demo projects located in the FreeRTOS/Demo/CORTEX_MPU_LPC1768_GCC_RedSuite and
FreeRTOS/Demo/CORTEX_MPU_LM3Sxxxx_Rowley directories were retired prior to the
release of FreeRTOS V9.0.0]
Compatible with the standard ARM Cortex-M3 and Cortex-M4F ports.
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, and can
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 only have access to 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 uses an 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 step through the
heavily commented FreeRTOS-MPU demonstration project located in the
FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC directory of the main
FreeRTOS download. The demo builds with GCC, and uses the Keil uVision IDE and
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.