# Process Isolation {#CMSIS_RTOS_ProcessIsolation}
CMSIS-RTOS2 API supports a concept of **process isolation** that allows developers to protect execution of critical software tasks against potential flaws in other parts of a program.
Process Isolation in CMSIS-RTOS2 is enabled by following features:
- \subpage rtos_process_isolation_mpu for memory access protection in the system using Memory Protection Unit (MPU).
RTOS threads are executed with permission to access only memory regions and peripherals required for their operation. Hence thread code cannot accidentally modify critical RTOS kernel data or memory dedicated to other tasks.
.
- \subpage rtos_process_isolation_safety_class for access protection to RTOS objects via RTOS APIs.
The RTOS objects with a higher safety class assigned to them cannot be modified via RTOS API functions from threads that have lower safety class assigned.
.
- \subpage rtos_process_isolation_thread_wdt to verify execution times of threads.
Each thread can maintain own thread watchdog and in case of timing violations, corresponding thread watchdog alarm will be triggered.
.
- \subpage rtos_process_isolation_faults in case of a detected failure (for example thread watchdog alarm or MPU Fault).
The RTOS provides functions to block execution of malfunctioning components and with that dedicate system resources for operation of the safety critical threads.
\if FuSaRTS
Section \ref fusa_process_isolation lists safety requirements for Process Isolation functions.
\endif
\page rtos_process_isolation_mpu MPU Protected Zones
Memory Protection Unit (MPU) is available on many Cortex-M devices and allows to execute code with restricted access to memory regions and peripherals. Detailed information about the MPU can be found in [Cortex-M Reference Manuals](../Core/index.html#ref_man_sec).
CMSIS-RTOS2 provides a concept of **MPU Protected Zones** as a simple and flexible mechanism for using MPUs with RTOS threads. MPU Protected Zones are defined by a user as a set of memory regions and peripherals with specified access rights, and each RTOS threads gets assigned to a specific MPU Protected Zone that it is allowed to use.
The figure below illustrates the concept for MPU Protected Zones for isolating threads.

Sections below explain in details how to define and use MPU Protected Zones:
- \ref rtos_process_isolation_mpu_def
- \ref rtos_process_isolation_mpu_load
- \ref rtos_process_isolation_mpu_objects
- \ref rtos_process_isolation_mpu_fault
**Function references**
Following functions implement and use MPU Protected Zone functionality:
- \ref osThreadNew : \copybrief osThreadNew
- \ref osThreadZone : \copybrief osThreadZone
- \ref osThreadGetZone : \copybrief osThreadGetZone
- \ref osThreadTerminateZone : \copybrief osThreadTerminateZone
- \ref osZoneSetup_Callback : \copybrief osZoneSetup_Callback
## Define MPU Protected Zones {#rtos_process_isolation_mpu_def}
In the architectural design phase an application is logically split into functionalities with the same integrity level (same safety requirements). They can safely operate within the same MPU Protected Zone and hence access same memory areas and peripherals.
MPU protected zones are defined in an MPU table where each row describes an individual MPU zone and each cell in the row specifies an MPU region within that zone. For details see section [MPU Functions](../Core/group__mpu__functions.html) in CMSIS-Core(M) documentation.
> **Note**
> - Interrupt handlers bypass the MPU protection. For this reason, it is required that potential impact of all interrupt handlers is strictly analyzed to exclude unintended memory accesses.
**Zone Identifier** (Zone ID) is used to refer to a specific MPU protected zone. Zone ID value equals to the row index (starting from 0) in the MPU table that describes corresponding MPU Protected Zone.
An MPU Protected Zone is assigned to one or more RTOS threads. This is done by providing the Zone ID value in thread attributes \ref osThreadAttr_t when creating the thread with the \ref osThreadNew function.
**Example:**
```c
/* ThreadA thread attributes */
const osThreadAttr_t thread_A_attr = {
.name = "ThreadA", // human readable thread name
.attr_bits = osThreadZone(3U) // assign thread to MPU protected zone with Zone Id 3
};
osThreadNew(ThreadA, NULL, &thread_A_attr);
```
[CMSIS-Zone](../Zone/index.html) provides a utility that allows graphic configuration of MPU protected zones and generates MPU table in the CMSIS format.
## Load MPU Protected Zone {#rtos_process_isolation_mpu_load}
When switching threads the RTOS kernel compares Zone IDs of the currently running thread and the next thread to be executed. If the Zone Ids are different then a callback function \ref osZoneSetup_Callback is called. This callback function shall be implemented in the user application code to actually switch to the new MPU Protected Zone. In the function the user should load the MPU Protected Zone according to the Zone Id provided in the argument.
**Example:**
```c
/* Update MPU settings for newly activating Zone */
void osZoneSetup_Callback (uint32_t zone) {
if (zone >= ZONES_NUM) {
// Here issue an error for incorrect zone value
}
ARM_MPU_Load(mpu_table[zone], MPU_REGIONS);
}
```
## RTOS Objects and MPU Protection {#rtos_process_isolation_mpu_objects}
To access RTOS objects from the application RTOS APIs rely on a numeric `xxx_id` parameter associated with the object as explained in \ref rtos_objects. For example as `evt_flags` in this code:
```c
osEventFlagsId_t evt_flags;
evt_flags = osEventFlagsNew(NULL);
osEventFlagsSet(evt_flags, 1);
```
The allocation of an RTOS object to the memory in a specific MPU Protected Zone does not provide access restriction. The access restriction can be bypassed if another thread calls the CMSIS-RTOS2 API with the object ID of the RTOS object as argument. The CMSIS-RTOS2 function is executed in handler mode and therefore can access and modify the RTOS object without raising a Memory Fault.
To enable access control for RTOS objects the \ref rtos_process_isolation_safety_class concept is introduced in CMSIS-RTOS2.
## Handle Memory Access Faults {#rtos_process_isolation_mpu_fault}
A memory access fault is triggered when a thread tries to access memory or peripherals outside of the MPU Protected Zone loaded while the thread is running. In such case Memory Management Interrupt [MemoryManagement_IRQn](../Core/group__NVIC__gr.html) is triggered by the processor and its handling function is executed according to the exception vector table specified in the device startup file (by default \token{MemManage_Handler(void)} ).
The \e MemManage_Handler() interrupt handler is application specific and needs to be implemented by the user. In the handler it is possible to identify the thread that caused the memory access fault, the corresponding zone id and the safety class. This information can be used to define actions for entering a safe state. \ref rtos_process_isolation_faults provides more details on the available system recovery possibilities.
\page rtos_process_isolation_safety_class Safety Classes
\ref rtos_process_isolation_mpu_objects explains that MPU Protected Zones do not provide full access protection to RTOS objects accessed via CMSIS-RTOS2 API. The concept of a safety class fills this gap.
Every RTOS object, including thread is assigned with a numeric safety class value. A thread cannot modify an RTOS object if its safety class value is higher than the safety class value of the thread.
For example, it is not possible to change the priority or suspend a thread that has a higher safety class value than the thread that is currently executed.
**Function references**
- Following functions and macros are used explicitly for managing safety classes:
- \ref osSafetyClass : \copybrief osSafetyClass
- \ref osThreadGetClass : \copybrief osThreadGetClass
- \ref osSafetyWithSameClass : \copybrief osSafetyWithSameClass
- \ref osSafetyWithLowerClass : \copybrief osSafetyWithLowerClass
- \ref osKernelProtect : \copybrief osKernelProtect
- \ref osThreadSuspendClass : \copybrief osThreadSuspendClass
- \ref osThreadResumeClass : \copybrief osThreadResumeClass
- \ref osKernelDestroyClass : \copybrief osKernelDestroyClass
- CMSIS-RTOS2 API functions that support safety class assignment when creating RTOS objects are listed in \ref rtos_process_isolation_safety_class_assign.
- CMSIS-RTOS2 API functions that verify safety class assignment before execution are listed in \ref rtos_process_isolation_safety_class_error lists.
## Assign Safety Class to an RTOS Object {#rtos_process_isolation_safety_class_assign}
It is possible to create any objects regardless of the safety class after the kernel initialize with \ref osKernelInitialize, but before the kernel is started with \ref osKernelStart. This allows to setup a system before actually starting the RTOS kernel.
Threads of a higher safety class can create RTOS objects that belong to a lower or same safety class. For the object types listed below, the \e attr_bits can have an optional safety class value that is assigned when the RTOS object is created with the \e os function. The macro \ref osSafetyClass encodes the value for the \e attr_bits field in the attr struct. For example:
```c
const osEventFlagsAttr_t evt_flags_attr = {
.attr_bits = osSafetyClass(SAFETY_CLASS_SAFE_MODE_OPERATION)
};
osEventFlagsId_t evt_flags;
evt_flags = osEventFlagsNew(&evt_flags_attr);
```
The following object types support safety class assignment when creating an object with corresponding \e os