CMSIS-RTOS2  Version 2.0.0
Real-Time Operating System: API and RTX Reference Implementation
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages

Synchronize resource access using Mutual Exclusion (Mutex). More...

Data Structures

struct  osMutexAttr_t
 Attributes structure for mutex. More...
 

Macros

#define osMutexRecursive   0x00000001U
 Mutex attributes (attr_bits in osMutexAttr_t). More...
 
#define osMutexPrioInherit   0x00000002U
 Priority inherit protocol. More...
 
#define osMutexRobust   0x00000008U
 Robust mutex. More...
 

Typedefs

typedef void * osMutexId_t
 

Functions

osMutexId_t osMutexNew (const osMutexAttr_t *attr)
 Create and Initialize a Mutex object. More...
 
const char * osMutexGetName (osMutexId_t mutex_id)
 Get name of a Mutex object. More...
 
osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout)
 Acquire a Mutex or timeout if it is locked. More...
 
osStatus_t osMutexRelease (osMutexId_t mutex_id)
 Release a Mutex that was acquired by osMutexAcquire. More...
 
osThreadId_t osMutexGetOwner (osMutexId_t mutex_id)
 Get Thread which owns a Mutex object. More...
 
osStatus_t osMutexDelete (osMutexId_t mutex_id)
 Delete a Mutex object. More...
 

Description

Mutual exclusion (widely known as Mutex) is used in various operating systems for resource management. Many resources in a microcontroller device can be used repeatedly, but only by one thread at a time (for example communication channels, memory, and files). Mutexes are used to protect access to a shared resource. A mutex is created and then passed between the threads (they can acquire and release the mutex).

Mutex.png
CMSIS-RTOS Mutex

A mutex is a special version of a semaphore. Like the semaphore, it is a container for tokens. But instead of being able to have multiple tokens, a mutex can only carry one (representing the resource). Thus, a mutex token is binary and bounded. The advantage of a mutex is that it introduces thread ownership. When a thread acquires a mutex and becomes its owner, subsequent mutex acquires from that thread will succeed immediately without any latency. Thus, mutex acquires/releases can be nested.

Note
  • Mutex management functions cannot be called from interrupt service routines (ISR), unlike a binary semaphore that can be released from an ISR.
Refer to Mutex Configuration for RTX5 configuration options.

Working with Mutexes

To use mutexes, you need to follow these steps for creating and using them:

  1. Declare the mutex container and initialize the mutex:
    osMutexId (uart_mutex_id); // Mutex ID
  2. Create the mutex in a thread:
    uart_mutex_id = osMutexNew(NULL);
  3. Acquire the mutex when peripheral access is required:
    osMutexAcquire(uart_mutex_id, osWaitForever);
  4. When finished with the peripheral access, release the mutex:
    osMutexRelease(uart_mutex_id);

Data Structure Documentation

struct osMutexAttr_t
Data Fields
const char * name name of the mutex

String with a human readable name of the mutex object.

osMutexId_t mid_Thread_Mutex; // mutex id
const osMutexAttr_t Thread_Mutex_attr = {
"myThreadMutex",
NULL, // memory for control block
NULL // size for control block
};
mid_Mutex = osMutexNew (&Thread_Mutex_attr);
uint32_t attr_bits attribute bits

The following predefined bit masks can be assigned to set options for a mutex object.

Bit Mask Description
osMutexRecursive Mutex is recursive. The same thread can consume a mutex multiple times without locking itself.
osMutexPrioInherit Priority inheritance protocol. While a thread owns this mutex it cannot be preempted by a higher priority thread to avoid starvation.
osMutexRobust Robust mutex. Notify threads that acquire a mutex if the previous owner was terminated.
void * cb_mem memory for control block

Pointer to a memory location for the mutex object. This can optionally be used for custom memory management systems. Specify NULL to use the kernel memory management.

uint32_t cb_size size of provided memory for control block

The size of the memory block passed with cb_mem. Must be the size of a mutex object or larger.

Macro Definition Documentation

#define osMutexRecursive   0x00000001U

Recursive mutex.

#define osMutexPrioInherit   0x00000002U
#define osMutexRobust   0x00000008U

Typedef Documentation

Mutex ID identifies the mutex.

Function Documentation

osMutexId_t osMutexNew ( const osMutexAttr_t attr)
Parameters
[in]attrmutex attributes; NULL: default values.
Returns
mutex ID for reference by other functions or NULL in case of error.

Create and initialize a Mutex object.

Note
Cannot be called from Interrupt Service Routines.

Code Example

#include "cmsis_os2.h"
osMutexId_t mutex_id;
void CreateMutex (void) {
mutex_id = osMutexNew(NULL);
if (mutex_id != NULL) {
// Mutex object created
}
}
*const char * osMutexGetName ( osMutexId_t  mutex_id)
Parameters
[in]mutex_idmutex ID obtained by osMutexNew.
Returns
name as NULL terminated string.
osStatus_t osMutexAcquire ( osMutexId_t  mutex_id,
uint32_t  timeout 
)
Parameters
[in]mutex_idmutex ID obtained by osMutexNew.
[in]timeoutTimeout Value or 0 in case of no time-out.
Returns
status code that indicates the execution status of the function.

Wait until a Mutex becomes available. If no other thread has obtained the Mutex, the function instantly returns and blocks the mutex object.

The argument timeout specifies how long the system waits for a mutex. While the system waits the thread that is calling this function is put into the state BLOCKED. The timeout timeout can have the following values:

  • when timeout is 0, the function returns instantly.
  • when timeout is set to osWaitForever the function will wait for an infinite time until the mutex becomes available.
  • all other values specify a time in kernel ticks for a timeout.

osStatus_t return values:

  • osOK: the mutex has been obtained.
  • osErrorTimeoutResource: the mutex could not be obtained in the given time.
  • osErrorResource: the mutex could not be obtained when no timeout was specified.
  • osErrorParameter: the parameter mutex_id is incorrect.
  • osErrorISR: cannot be called from interrupt service routines.
Note
Cannot be called from Interrupt Service Routines.

Code Example

#include "cmsis_os2.h"
void WaitMutex (void) {
osMutexId_t mutex_id;
osStatus_t status;
mutex_id = osMutexNew(NULL);
if (mutex_id != NULL) {
status = osMutexAcquire(mutex_id, 0);
if (status != osOK) {
// handle failure code
}
}
}
osStatus_t osMutexRelease ( osMutexId_t  mutex_id)
Parameters
[in]mutex_idmutex ID obtained by osMutexNew.
Returns
status code that indicates the execution status of the function.

Release a Mutex that was obtained with osMutexAcquire. Other threads that currently wait for the same mutex will be now put into the state READY.

osStatus_t return values:

  • osOK: the mutex has been correctly released.
  • osErrorResource: the mutex was not obtained before.
  • osErrorParameter: the parameter mutex_id is incorrect.
  • osErrorISR: osMutexRelease cannot be called from interrupt service routines.
Note
Cannot be called from Interrupt Service Routines.

Code Example

#include "cmsis_os2.h"
osMutexId_t mutex_id; // Mutex id populated by the function CreateMutex()
void ReleaseMutex (osMutexId_t mutex_id) {
osStatus_t status;
if (mutex_id != NULL) {
status = osMutexRelease(mutex_id);
if (status != osOK) {
// handle failure code
}
}
}
osThreadId_t osMutexGetOwner ( osMutexId_t  mutex_id)
Parameters
[in]mutex_idmutex ID obtained by osMutexNew.
Returns
thread ID of owner thread or NULL when mutex was not acquired.

Returns the osThreadId_t of the thread that acquired a mutex.

osStatus_t osMutexDelete ( osMutexId_t  mutex_id)
Parameters
[in]mutex_idmutex ID obtained by osMutexNew.
Returns
status code that indicates the execution status of the function.

Delete a Mutex object. The function releases internal memory obtained for Mutex handling. After this call the mutex_id is no longer valid and cannot be used. The Mutex may be created again using the function osMutexNew.

osStatus_t return values:

  • osOK: the mutex object has been deleted.
  • osErrorISR: osMutexDelete cannot be called from interrupt service routines.
  • osErrorResource: all tokens have already been released.
  • osErrorParameter: the parameter mutex_id is incorrect.
Note
Cannot be called from Interrupt Service Routines.

Code Example

#include "cmsis_os2.h"
osMutexId_t mutex_id; // Mutex id populated by the function CreateMutex()
void DeleteMutex (osMutexId_t mutex_id) {
osStatus_t status;
if (mutex_id != NULL) {
status = osMutexDelete(mutex_id);
if (status != osOK) {
// handle failure code
}
}
}