CMSIS-RTOS  Version 1.03
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...

Macros

#define osMutexDef(name)   const osMutexDef_t os_mutex_def_##name = { 0 }
 Define a Mutex. More...
 
#define osMutex(name)   &os_mutex_def_##name
 Access a Mutex definition. More...
 

Functions

osMutexId osMutexCreate (const osMutexDef_t *mutex_def)
 Create and Initialize a Mutex object. More...
 
osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec)
 Wait until a Mutex becomes available. More...
 
osStatus osMutexRelease (osMutexId mutex_id)
 Release a Mutex that was obtained by osMutexWait. More...
 
osStatus osMutexDelete (osMutexId mutex_id)
 Delete a Mutex that was created by osMutexCreate. 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.
  • CMSIS-RTOS uses reentrant/recursive mutexes only.

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:
    osMutexDef (uart_mutex); // Declare mutex
    osMutexId (uart_mutex_id); // Mutex ID
  2. Create the mutex in a thread:
    uart_mutex_id = osMutexCreate(osMutex(uart_mutex));
  3. Acquire the mutex when peripheral access is required:
    osMutexWait(uart_mutex_id, osWaitForever);
  4. When finished with the peripheral access, release the mutex:
    osMutexRelease(uart_mutex_id);

Macro Definition Documentation

#define osMutex (   name)    &os_mutex_def_##name

Access to mutex object for the functions osMutexCreate.

Parameters
namename of the mutex object.
Note
CAN BE CHANGED: The parameter to osMutex shall be consistent but the macro body is implementation specific in every CMSIS-RTOS.
#define osMutexDef (   name)    const osMutexDef_t os_mutex_def_##name = { 0 }

Define a mutex object that is referenced by osMutex.

Parameters
namename of the mutex object.
Note
CAN BE CHANGED: The parameter to osMutexDef shall be consistent but the macro body is implementation specific in every CMSIS-RTOS.

Function Documentation

osMutexId osMutexCreate ( const osMutexDef_t mutex_def)
Parameters
[in]mutex_defmutex definition referenced with osMutex.
Returns
mutex ID for reference by other functions or NULL in case of error.
Note
MUST REMAIN UNCHANGED: osMutexCreate shall be consistent in every CMSIS-RTOS.

Create and initialize a Mutex object.

Note
Cannot be called from Interrupt Service Routines.

Code Example

#include "cmsis_os.h"
osMutexDef (MutexIsr); // Mutex name definition
void CreateMutex (void) {
osMutexId mutex_id;
mutex_id = osMutexCreate (osMutex (MutexIsr));
if (mutex_id != NULL) {
// Mutex object created
}
}
osStatus osMutexDelete ( osMutexId  mutex_id)
Parameters
[in]mutex_idmutex ID obtained by osMutexCreate.
Returns
status code that indicates the execution status of the function.
Note
MUST REMAIN UNCHANGED: osMutexDelete shall be consistent in every CMSIS-RTOS.

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 osMutexCreate.

Status and Error Codes

  • 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_os.h"
osMutexDef (MutexIsr); // Mutex name definition
osMutexId mutex_id; // Mutex id populated by the function CreateMutex()
osMutexId CreateMutex (void); // function prototype that creates the Mutex
void DeleteMutex (osMutexId mutex_id) {
osStatus status;
if (mutex_id != NULL) {
status = osMutexDelete(mutex_id);
if (status != osOK) {
// handle failure code
}
}
}
osStatus osMutexRelease ( osMutexId  mutex_id)
Parameters
[in]mutex_idmutex ID obtained by osMutexCreate.
Returns
status code that indicates the execution status of the function.
Note
MUST REMAIN UNCHANGED: osMutexRelease shall be consistent in every CMSIS-RTOS.

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

Status and Error Codes

  • 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_os.h"
osMutexDef (MutexIsr); // Mutex name definition
osMutexId mutex_id; // Mutex id populated by the function CreateMutex()
osMutexId CreateMutex (void); // function prototype that creates the Mutex
void ReleaseMutex (osMutexId mutex_id) {
osStatus status;
if (mutex_id != NULL) {
status = osMutexRelease(mutex_id);
if (status != osOK) {
// handle failure code
}
}
}
osStatus osMutexWait ( osMutexId  mutex_id,
uint32_t  millisec 
)
Parameters
[in]mutex_idmutex ID obtained by osMutexCreate.
[in]millisecTimout Value or 0 in case of no time-out.
Returns
status code that indicates the execution status of the function.
Note
MUST REMAIN UNCHANGED: osMutexWait shall be consistent in every CMSIS-RTOS.

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 millisec 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 WAITING. The millisec timeout can have the following values:

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

Status and Error Codes

  • 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: osMutexWait cannot be called from interrupt service routines.
Note
Cannot be called from Interrupt Service Routines.

Code Example

#include "cmsis_os.h"
osMutexDef (MutexIsr);
void WaitMutex (void) {
osMutexId mutex_id;
osStatus status;
mutex_id = osMutexCreate (osMutex (MutexIsr));
if (mutex_id != NULL) {
status = osMutexWait (mutex_id, 0);
if (status != osOK) {
// handle failure code
}
}
}