CMSIS-RTOS Version 1.03
Real-Time Operating System: API and RTX Reference Implementation.
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.
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|
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:
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.
At startup time, the CMSIS-RTOS RTX creates the following threads:
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.
The following CMSIS-RTOS functions can be called from threads and Interrupt Service Routines (ISR):
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.