CMSIS-RTOS: Theory of Operation

| CMSIS-RTOS Version 1.03 Real-Time Operating System: API and RTX Reference Implementation.

- Main Page
- Usage and Description
- Reference

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Theory of Operation

This section describes how CMSIS-RTOS RTX manages the resources of the target system. Many aspects of the CMSIS-RTOS RTX kernel can be configured. Information about configuration options is mentioned where applicable.

# Settings for osFeature_xxx in cmsis_os.h

CMSIS-RTOS RTX uses the following #defines.

osFeature_xxx #define | RTX Setting | Meaning
--- | --- | ---
osFeature_MainThread | 1 | main can be a thread
osFeature_Pool | 1 | Memory Pools are available
osFeature_MailQ | 1 | Mail Queues are available
osFeature_MessageQ | 1 | Message Queues are available
osFeature_Signals | 16 | 16 Signal Flags are available per thread
osFeature_Semaphore | 65535 | Maximum count for osSemaphoreCreate function
osFeature_Wait | 0 | osWait is not available
osFeature_SysTick | 1 | osKernelSysTick functions are available

# RTX Kernel Timer Tick and Thread Management

By default, CMSIS-RTOS RTX uses the Cortex-M SysTick timer to generate periodic interrupts for the RTX kernel timer tick. CMSIS-RTOS provides Timer Management functions and several CMSIS-RTOS functions have a timeout parameter. This periodic RTX kernel timer tick interrupt is used to derive the required time interval. CMSIS-RTOS RTX also provides configuration options for a alternative timer and tick-less operation. Refer to RTX Kernel Tick Timer Configuration for more information.

To handle timeout and time delays for threads, the CMSIS-RTOS RTX thread management is controlled by the RTX kernel timer tick interrupt. The thread context switch itself is implemented in the HAL_CMx.x hardware abstraction layer source files. The thread context contains all CPU registers (R0 - R12), the return address (LR), the program counter (PC), and the processor status register (xPSR). For the Cortex-M4 FPU and Cortex-M7 FPU the floating point status and registers (S0 - S32, FPSCR) are also part of the thread context.

When a thread switch occurs:

- the thread context of the current running thread is stored on the local stack of this thread.
- the stack pointer is switched to the next running thread.
- the thread context of this next running thread is restored and this thread starts to run.

Note
  - For Cortex-M0, Cortex-M3, Cortex-M4, and Cortex-M7 the thread context requires 64 bytes on the local stack.
  - For Cortex-M4 FPU and Cortex-M7 FPU the thread context requires 200 bytes on the local stack. For devices with Cortex-M4 FPU and Cortex-M7 FPU the default stack space should be increased to a minimum of 300 bytes.

Each thread is provided with an separate stack that holds the thread context and stack space for automatic variables and return addresses for function call nesting. The stack sizes of the RTX threads are flexible configurable as explained in the section Thread Configuration. RTX even offers a configurable checking for stack overflows. Refer to Stack Overflow Checking for more information.

# CMSIS-RTOS RTX Threads

At startup time, the CMSIS-RTOS RTX creates the following threads:

- main : the 'main' function of the application code is started as thread with the osPriorityNormal.
- os_idle_demon : this thread executes when no other thread is in RUNNING state. The code of that thread is provided in the RTX_Conf_CM.c file and is typically used to put the system into a power-saving mode.
- osTimerThread : this thread executes the Timer Management callback functions. This thread can be disabled; refer to User Timer Management for configuration options.

# Priority Inversion on Resource Sharing

The CMSIS-RTOS RTX employs a priority-based preemptive scheduler which ensures that from all the threads that are in the READY state, the thread with the highest priority gets executed and becomes the RUNNING thread. Because threads share resources, events that are outside of the control of the RTX scheduler can prevent the highest priority thread from running when it should. If this happens, a critical deadline could be missed, causing the system to fail. Priority inversion is the term of a scenario in which the highest-priority ready task fails to run when it should.

Threads typically share resources to communicate and process data by using the CMSIS-RTOS Mutexes. At any time, two or more threads share a resource, such as a memory buffer or a serial port, one of them may have a higher priority. It is expected that the higher-priority thread runs as soon as it is in the READY state. However, if the lower-priority thread is using a shared resource of a higher-priority thread, this higher-priority thread must wait until the lower-priority thread releases the shared resource.

To prevent priority inversions, the CMSIS-RTOS RTX implements a priority inheritance method for the Mutexes. A lower-priority thread inherit the priority of any higher-priority thread that is waiting with osMutexWait on a shared resource. During the time the higher-priority thread is in WAITING state, the lower-priority thread runs at the same priority of a higher-priority pending thread. When the lower-priority thread stops to share a resource with osMutexRelease, the original priority is assigned to this thread again.

# Function calls from Interrupt Service Routines (ISR)

The following CMSIS-RTOS functions can be called from threads and Interrupt Service Routines (ISR):

- osKernelRunning
- osSignalSet
- osSemaphoreRelease
- osPoolAlloc, osPoolCAlloc, osPoolFree
- osMessagePut, osMessageGet
- osMailAlloc, osMailCAlloc, osMailGet, osMailPut, osMailFree

Functions that cannot be called from an ISR are verifying the interrupt status and return the status code osErrorISR in case that they are called from an ISR context.