1 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
5 The <b>CMSIS-RTOS API v2</b> addresses the following new requirements:
6 - Dynamic object creation no longer requires static memory, static memory buffers are now optional.
7 - Support for ARMv8-M architecture that provides a Secure and Non-Secure state of code execution.
8 - Provisions for message passing in multi-core systems.
9 - Full support of C++ run-time environments.
10 - C interface which is binary compatible across <a class="el" href="http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html">ABI compatible compilers</a>.
12 As a consequence of these requirements the CMSIS-RTOS API v2 has the following fundamental modifications:
13 - The functions osXxxxNew replace osXxxxCreate functions; osXxxxNew and osXxxxDelete create and destroy objects.
14 - The C function main is not longer started as a thread (this was an optional feature in CMSIS-RTOS v1).
15 - Functions that return osEvent have been replaced.
17 CMSIS-RTOS API v2 provides an translation layer for the
18 <a class="el" href="../../RTOS/html/index.html">CMSIS-RTOS API v1</a> that simplifies migration.
20 CMSIS-RTOS API v2 is not POSIX compliant, but has provisions to enable a POSIX translation layer and a C++ interface.
21 \todo Investigate into a flexible C++ interface and potential POSIX translation
25 CMSIS-RTOS in ARM::CMSIS Pack
26 -----------------------------
28 The following files relevant to CMSIS-RTOS are present in the <b>ARM::CMSIS</b> Pack directories:
29 |File/Folder | Content |
30 |-----------------------------|------------------------------------------------------------------------|
31 |\b CMSIS/Documentation/RTOS2 | This documentation |
32 |\b CMSIS/Documentation/RTOS | CMSIS-RTOS API v1 documentation |
33 |\b CMSIS/RTOS2/Template | \ref cmsis_os_h |
37 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
39 \page rtos_revisionHistory Revision History
41 <table class="cmtable" summary="Revision History">
49 Extended number of thread priorities.\n
50 Added: osKernelTime, osKernelStop.\n
51 Added: osThreadState, osThreadGetState, osThreadSuspend, osThreadResume.\n
52 Added: osTimerRunning.\n
53 Added: osPoolDelete.\n
54 Added: osMessageCount, osMessageReset, osMessageDelete.\n
55 Added: osMailCount, osMailReset, osMailDelete.\n
56 Added: osFlag object.\n
60 <td>V1.02 - only documentation changes</td>
62 Added: Overview of the \ref RtosValidation "CMSIS-RTOS Validation" Software Pack.\n
63 Clarified: Behavior of \ref CMSIS_RTOS_TimeOutValue.
68 <td>Added: New control functions for short timeouts in microsecond resolution \ref osKernelSysTick,
69 \ref osKernelSysTickFrequency, \ref osKernelSysTickMicroSec.\n
75 <td>Added capabilities for C++, kernel initialization and object deletion.\n
76 Prepared for C++ class interface. In this context to \em const attribute has been moved from osXxxxDef_t typedefs to
77 the osXxxxDef macros.\n
78 Added: \ref osTimerDelete, \ref osMutexDelete, \ref osSemaphoreDelete.\n
79 Added: \ref osKernelInitialize that prepares the Kernel for object creation.\n
85 <td>First official Release.\n
86 Added: \ref osKernelStart; starting 'main' as a thread is now an optional feature.\n
87 Semaphores have now the standard behavior.\n
88 \b osTimerCreate does no longer start the timer. Added: \ref osTimerStart (replaces osTimerRestart).\n
89 Changed: osThreadPass is renamed to \ref osThreadYield.
94 <td>Preview Release.</td>
100 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
102 \page UsingOS Using a CMSIS-RTOS Implementation
104 A CMSIS-RTOS implementation is typically provided as a library. To add the RTOS functionality to an existing CMSIS-based
105 application, the RTOS library (and typically a configuration file) needs to be added. The available functionality of the
106 RTOS library is defined in the header file \b cmsis_os.h that is specific for each CMSIS-RTOS implementation.
108 \image html "CMSIS_RTOS_Files.png" "CMSIS-RTOS File Structure"
110 Depending on the CMSIS-RTOS implementation, execution may start with the \b main function as the first thread. This has the
111 benefit that an application programmer may use other middleware libraries that create threads internally, but the remaining
112 part of the user application just uses the \b main thread. Therefore, the usage of the RTOS can be invisible to the
113 application programmer, but libraries can use CMSIS-RTOS features.
115 Once the files are added to a project, the user can start working with the CMSIS-RTOS functions. A code example is provided
120 #include "cmsis_os.h" // CMSIS-RTOS header file
122 void job1 (void const *argument) { // thread function 'job1'
124 : // execute some code
125 osDelay (10); // delay execution for 10 milliseconds
129 osThreadDef(job1, osPriorityAboveNormal, 1, 0); // define job1 as thread function
131 void job2 (void const *argument) { // thread function 'job2'
132 osThreadCreate(osThread(job1),NULL); // create job1 thread
134 : // execute some code
138 osThreadDef(job2, osPriorityNormal, 1, 0); // define job2 as thread function
140 void job3 (void const *argument) { // thread function 'job3'
142 : // execute some code
143 osDelay (20); // delay execution for 20 milliseconds
147 osThreadDef(job3, osPriorityNormal, 1, 0); // define job3 as thread function
149 int main (void) { // program execution starts here
150 osKernelInitialize (); // initialize RTOS kernel
151 : // setup and initialize peripherals
152 osThreadCreate (osThread(job2));
153 osThreadCreate (osThread(job3));
154 osKernelStart (); // start kernel with job2 execution
160 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
162 \page FunctionOverview Function Overview
164 CMSIS-RTOS v2 provides multiple API functions:
165 - \subpage RTOS_API2 is the new C function API that support dynamic object creation, ARMv8-M, and multi-processor
167 - <a class="el" href="../../RTOS/html/functionOverview.html">CMSIS-RTOS C API Version 1</a> is a C function API the is
168 backward compatible with CMSIS-RTOS v2.
169 - \subpage RTOS_APICPP is a C++ class function API.
171 It is possible to intermix the different API variants in the same application and even in the same C/C++ source module.
172 However, the functions of the <b>C API Version 1</b> may be deprecated in future versions of CMSIS-RTOS.
174 \section CMSIS_RTOS_TimeOutValue Timeout Value
176 The timeout value specifies the number of timer ticks until a timeout or time delay elapses. The value is an upper bound and
177 depends on the actual time elapsed since the last timer tick.
179 For a value of \b 1 the system waits until the next timer tick occurs. That means that the actual timeout value can be one
180 timer tick less than the specified timeout value.
182 \image html TimerValues.png "Timer Values"
184 \section CMSIS_RTOS_ISR_Calls Calls from Interrupt Service Routines
186 The following CMSIS-RTOS2 functions can be called from threads and Interrupt Service Routines (ISR):
187 \todo what about - \ref osKernelGetState
188 - \ref osThreadFlagsSet, \ref osThreadFlagsClear, \ref osThreadFlagsGet
189 - \ref osEventFlagsSet, \ref osEventFlagsClear, \ref osEventFlagsGet, \ref osEventFlagsWait
190 - \ref osSemaphoreAcquire, \ref osSemaphoreRelease, \ref osSemaphoreGetCount
191 - \ref osMemoryPoolAlloc, \ref osMemoryPoolFree, \ref osMemoryPoolGetCapacity, \ref osMemoryPoolGetBlockSize, \ref osMemoryPoolGetCount, \ref osMemoryPoolGetSpace
192 - \ref osMessageQueuePut, \ref osMessageQueueGet, \ref osMessageQueueGetCapacity, \ref osMessageQueueGetMsgSize, \ref osMessageQueueGetCount, \ref osMessageQueueGetSpace
195 In addition, the following legacy CMSIS-RTOS1 functions can be called from threads and Interrupt Service Routines (ISR):
197 - \ref osKernelRunning
198 - \ref osMailQueueAlloc, \ref osMailQueueGet, \ref osMailQueuePut, \ref osMailQueueFree
201 Functions that cannot be called from an ISR are verifying the interrupt status and return, in case they are called
202 from an ISR context, the status code \b osErrorISR. In some implementations, this condition might be caught using the HARD
209 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
211 \page RTOS_API2 CMSIS-RTOS C API Version 2
213 Overview of all CMSIS-RTOS C API v2 functions.
215 - \ref CMSIS_RTOS_KernelCtrl
216 - \ref osKernelInitialize : Initialize the RTOS kernel for creating objects.
217 - \ref osKernelStart : Start the RTOS kernel scheduler.
218 - \ref osKernelSuspend : Suspend the RTOS Kernel scheduler.
219 - \ref osKernelResume : Resume the RTOS Kernel scheduler.
220 - \ref osKernelState : Query if the RTOS kernel is inactive, running, or suspended.
221 - \ref osKernelTime : Get the RTOS kernel time (milli-second).
222 - \ref osKernelSysTick : Get RTOS kernel system timer counter.
223 - \ref osKernelSysTickFrequency : RTOS kernel system timer frequency in Hz.
224 - \ref osKernelSysTickMicroSec : Convert microseconds value to RTOS kernel system timer value.
226 - \ref CMSIS_RTOS_ThreadMgmt
227 - \ref osThreadNew : Create and start execution of a thread function.
228 - \ref osThreadTerminate : Stop execution of a thread function.
229 - \ref osThreadSuspend : Suspend a thread function.
230 - \ref osThreadResume : Resume a thread function.
231 - \ref osThreadGetState : Get current state of an active thread.
232 - \ref osThreadYield : Pass execution to next ready thread function.
233 - \ref osThreadGetId : Get the thread identifier to reference this thread.
234 - \ref osThreadSetPriority : Change the execution priority of a thread function.
235 - \ref osThreadGetPriority : Obtain the current execution priority of a thread function.
237 - \ref CMSIS_RTOS_Wait
238 - \ref osDelay : Wait for a specified time.
239 - \ref osDelayUntil : Wait until a specified kernel time.
240 - \ref osEventWait : Wait for Thread Flags, Event Flags, Message, Mail, or Timeout.
242 - \ref CMSIS_RTOS_TimerMgmt
243 - \ref osTimerNew : Create and define timer with related callback function.
244 - \ref osTimerDelete : Step a timer and remove related callback function.
245 - \ref osTimerStart : Start or restart the timer with a time value.
246 - \ref osTimerStop : Stop the timer.
247 - \ref osTimerIsRunning : Check if a timer is running.
249 - \ref CMSIS_RTOS_ThreadFlagsMgmt
250 - \ref osThreadFlagsSet : Set the specified Thread Flags of an active thread
251 - \ref osThreadFlagsClear : Clear the specified Thread Flags of an active thread
252 - \ref osThreadFlagsGet : Get the current Thread Flags of an active thread.
253 - \ref osThreadFlagsWait : Wait for one or more Thread Flags of the current running thread to become signaled
255 - \ref CMSIS_RTOS_EventFlags
256 - \ref osEventFlagsNew : Create and initialize an Event Flags object.
257 - \ref osEventFlagsDelete : Delete an Event Flags object.
258 - \ref osEventFlagsSet : Set the specified Event Flags.
259 - \ref osEventFlagsClear : Clear the specified Event Flags.
260 - \ref osEventFlagsGet : Get the current Event Flags.
261 - \ref osEventFlagsWait : Wait for one or more Event Flags to become signalled.
263 - \ref CMSIS_RTOS_MutexMgmt
264 - \ref osMutexNew : Create and initialize a Mutex object.
265 - \ref osMutexDelete : Delete a Mutex object
266 - \ref osMutexAcquire : Obtain a Mutex or Wait until it becomes available.
267 - \ref osMutexRelease : Release a MMutex.
269 - \ref CMSIS_RTOS_SemaphoreMgmt
270 - \ref osSemaphoreNew : Create and initialize a Semaphore object
271 - \ref osSemaphoreDelete : Delete a Semaphore object.
272 - \ref osSemaphoreAcquire : Obtain a Semaphore token or Wait until it becomes available.
273 - \ref osSemaphoreRelease : Release a Semaphore token.
274 \todo do we need a function that retrieves how many semaphores are available?
276 - \ref CMSIS_RTOS_PoolMgmt
277 - \ref osMemoryPoolNew : Define and initialize a fix-size memory pool.
278 - \ref osMemoryPoolAlloc : Allocate a memory block.
279 - \ref osMemoryPoolFree : Return a memory block to the memory pool.
280 - \ref osMemoryPoolGetInfo : Get a Memory Pool information
281 - \ref osMemoryPoolDelete : Delete a Memory Pool object
283 - \ref CMSIS_RTOS_Message
284 - \ref osMessageQueueNew : Create and initialize a message queue.
285 - \ref osMessageQueuePut : Put a message into a message queue.
286 - \ref osMessageQueueGet : Get a message or suspend thread execution until message arrives.
287 - \ref osMessageQueueGetInfo : Get a Message Queue information.
288 - \ref osMessageQueueReset : Reset a Message Queue to initial empty state.
289 - \ref osMessageQueueDelete : Delete a Message Queue object.
291 - \ref CMSIS_RTOS_Mail
292 - \ref osMailQueueNew : Create and Initialize a Mail Queue object.
293 - \ref osMailQueueAlloc : Allocate a memory block for mail from a mail memory pool.
294 - \ref osMailQueuePut : Put a Mail into a Queue.
295 - \ref osMailQueueGet : Get a Mail from a Queue or timeout if Queue is empty.
296 - \ref osMailQueueFree : Free a memory block by returning it to a mail memory pool.
297 - \ref osMailQueueGetInfo : Get a Mail Queue information.
298 - \ref osMailQueueReset : Reset a Mail Queue to initial empty state.
299 - \ref osMailQueueDelete : Delete a Mail Queue object.
304 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
306 \page RTOS_APICPP CMSIS-RTOS C++ API
313 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
315 \page cmsis_os_h Header File Template: cmsis_os.h
317 The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS).
318 Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents
321 The file cmsis_os.h contains:
322 - CMSIS-RTOS API function definitions
323 - struct definitions for parameters and return types
324 - status and priority values used by CMSIS-RTOS API functions
325 - macros for defining threads and other kernel objects
328 <b>Name conventions and header file modifications</b>
330 All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions.
331 Definitions that are prefixed \b os_ are not used in the application code but local to this header file.
332 All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread.
334 Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS
335 implementation. These definitions can be specific to the underlying RTOS kernel.
337 Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is
338 no longer compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS
341 <b>Define and reference object definitions</b>
343 With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header
344 file that is used throughout a project as shown below:
348 #include <cmsis_os.h> // CMSIS RTOS header file
351 extern void thread_sample (void const *argument); // function prototype
352 osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100);
355 osPoolDef(MyPool, 10, long);
359 This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is
360 present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be
361 used throughout the whole project.
365 #include "osObjects.h" // Definition of the CMSIS-RTOS objects
369 #define osObjectsExternal // Objects will be defined as external symbols
370 #include "osObjects.h" // Reference to the CMSIS-RTOS objects
373 <b>Header file %cmsis_os.h</b>
375 \include Template/cmsis_os.h
378 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
380 \page RtosValidation RTOS Validation
382 ARM offers a <a class=el href="http://www.keil.com/pack" target="_blank">Software Pack</a> for the CMSIS-RTOS Validation.
383 The <b>ARM::CMSIS-RTOS_Validation</b> Pack contains the following:
385 - Source code of a CMSIS-RTOS Validation Suite along with configuration file.
386 - Documentation of the CMSIS-RTOS Validation Suite.
387 - Example that shows the usage of the CMSIS-RTOS Validation Suite using simulation.
389 The CMSIS-RTOS Validation Suite is currently available in beta release and performs generic validation of various
390 RTOS features. The test cases verify the functional behavior, test invalid parameters and call management
393 The following CMSIS-RTOS features can be tested with the current release:
394 - Thread : Create multiple threads, terminate, restart, yield, change priority
395 - Timer : Create periodic and one-shot timers
396 - GenWait : Call generic wait functions (osDelay and osWait)
397 - WaitFunc : Measure wait ticks (delay, mail, message, mutex, semaphore, signal)
399 Moreover the following inter-thread communication functions can be tested:
400 - Signal : Verify signal events
401 - Memory Pool : Verify memory allocation
402 - Message Queue : Exchange messages between threads
403 - Mail Queue : Exchange data between threads
404 - Mutex : Synchronize resource access
405 - Semaphore : Access shared resources
407 The RTOS Validation output can be printed to a console, output via ITM printf, or output to a memory buffer.
409 \section test_output Sample Test Output
411 CMSIS-RTOS Test Suite Oct 21 2015 16:39:16
413 TEST 01: TC_ThreadCreate PASSED
414 TEST 02: TC_ThreadMultiInstance PASSED
415 TEST 03: TC_ThreadTerminate PASSED
418 TEST 08: TC_ThreadChainedCreate PASSED
419 TEST 09: TC_ThreadYield NOT EXECUTED
420 TEST 10: TC_ThreadParam PASSED
423 TEST 60: TC_MailFromISRToThread PASSED
425 Test Summary: 60 Tests, 59 Executed, 59 Passed, 0 Failed, 0 Warnings.
431 /* ========================================================================================================================== */
434 * \addtogroup CMSIS_RTOS CMSIS-RTOS API v2
435 * \brief This section describes the CMSIS-RTOS API v2.
436 * \details The CMSIS-RTOS is a generic API layer that interfaces to an existing RTOS kernel.
443 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
444 // ==== Kernel Control Functions ====
446 \addtogroup CMSIS_RTOS_KernelCtrl Kernel Information and Control
448 \brief Provide version/system information and start the RTOS Kernel.
450 The Kernel Information and Control function group allows to:
451 - obtain information about the system and the underlying kernel.
452 - obtain version information about the CMSIS-RTOS API.
453 - initialize of the RTOS kernel for creating objects.
454 - start the RTOS kernel and thread switching.
455 - check the execution status of the RTOS kernel.
457 The function \b main is a special thread function that may be started at system initialization. In this case it has the
458 initial priority \a osPriorityNormal.
460 When reaching \b main, it is necessary to:
461 -# Call osKernelInitialize() to initialize the CMSIS-RTOS Kernel
462 -# Setup device peripherals and create other RTOS objects using the \b os*Create functions.
463 -# Start the Kernel and begin thread switching by calling osKernelStart().
468 osKernelInitialize (); // initialize CMSIS-RTOS
470 // initialize peripherals here
472 // create 'thread' functions that start executing,
473 // example: tid_name = osThreadCreate (osThread(name), NULL);
475 osKernelStart (); // start thread execution
481 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
483 Version information of the CMSIS-RTOS API whereby major version is in bits [31:16] and sub version in bits [15:0].
484 The value 0x10000 represents version 1.00.
487 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
488 /* \def osCMSIS_KERNEL
489 Identifies the underlying RTOS kernel and version number. The actual name of that define depends on the RTOS Kernel used in
490 the implementation. For example, \b osCMSIS_FreeRTOS identifies the FreeRTOS kernel and the value indicates the version
491 number of that kernel whereby the major version is in bits [31:16] and sub version in bits [15:0]. The value 0x10000
492 represents version 1.00.
495 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
496 /* \def osKernelSystemId
497 Defines a string that identifies the underlying RTOS Kernel and provides version information. The length of that string is
498 limited to 21 bytes. A valid identification string is for example, <b>"FreeRTOS V1.00"</b>.
501 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
502 /* \def osFeature_KernelSysTick
503 Defines if a Kernel SysTick timer is available or not.
506 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
508 \typedef osKernelState_t
509 Kernel state definitions.
512 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
513 /** \fn osStatus osKernelInitialize (void)
514 Initialize of the RTOS Kernel to allow peripheral setup and creation of other RTOS objects with the functions:
515 - \ref osThreadNew : Create a thread function.
516 - \ref osTimerNew : Define attributes of the timer callback function.
517 - \ref osMutexNew : Define and initialize a mutex.
518 - \ref osSemaphoreNew : Define and initialize a semaphore.
519 - \ref osMemoryPoolNew : Define and initialize a fix-size memory pool.
520 - \ref osMessageQueueNew : Define and initialize a message queue.
521 - \ref osMailQueueNew : Define and initialize a mail queue with fix-size memory blocks.
523 The RTOS kernel does not start thread switching until the function \ref osKernelStart is called.
526 In case that the RTOS Kernel starts thread execution with the function \em main the function osKernelInitialize stops thread switching.
527 This allows you to setup the system to a defined state before thread switching is resumed with \ref osKernelStart.
531 #include "cmsis_os.h"
534 if (!osKernelRunning ()) { // if kernel is not running, initialize the kernel
535 if (osKernelInitialize () != osOK) { // check osStatus for other possible valid values
536 // exit with an error message
544 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
545 /** \fn osStatus osKernelStart (void)
546 Start the RTOS Kernel and begin thread switching.
549 When the CMSIS-RTOS starts thread execution with the function \em main this function resumes thread switching. The \em main
550 thread will continue executing after \ref osKernelStart.
552 <b>\ref CMSIS_RTOS_Status</b>\n
553 - \em osOK: the RTOS kernel has been successfully started.
554 - \em osErrorISR: \ref osKernelStart cannot be called from interrupt service routines.
556 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
560 #include "cmsis_os.h"
563 if (osKernelInitialize () != osOK) { // check osStatus for other possible valid values
564 // exit with an error message
567 if (!osKernelRunning ()) { // is the kernel running ?
568 if (osKernelStart () != osOK) { // start the kernel
569 // kernel could not be started
576 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
577 /** \fn uint32_t osKernelSuspend (uint32_t tickless)
581 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
582 /** \fn osStatus osKernelResume (uint32_t sleep_time)
586 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
587 /** \fn osKernelState osKernelGetState (void)
591 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
592 /** \fn uint32_t osKernelTime (void)
593 Returns the current kernel time in milliseconds.
595 \todo add code example for osKernelTime
602 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
603 /** \fn uint32_t osKernelSysTick (void)
605 Get the value of the Kernel SysTick timer for time comparison. The value is a rolling
606 32-bit counter that is typically composed of the kernel system interrupt timer value
607 and an counter that counts these interrupts.
609 This function allows the implementation of timeout checks. These are for example
610 required when checking for a busy status in a device or peripheral initialization routine.
612 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
616 #include "cmsis_os.h"
618 void SetupDevice (void) {
621 tick = osKernelSysTick(); // get start value of the Kernel system tick
622 Device.Setup (); // initialize a device or peripheral
623 do { // poll device busy status for 100 microseconds
624 if (!Device.Busy) break; // check if device is correctly initialized
625 } while ((osKernelSysTick() - tick) < osKernelSysTickMicroSec(100));
627 ; // in case device still busy, signal error
629 // start interacting with device
634 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
636 \def osKernelSysTickFrequency
638 Specifies the frequency of the Kernel SysTick timer in Hz. The value is typically
639 use to scale a time value and is for example used in \ref osKernelSysTickMicroSec.
645 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
647 \def osKernelSysTickMicroSec
649 Allows you to scale a microsecond value to the frequency of the Kernel SysTick timer.
650 This macro is typically used to check for short timeouts in polling loops.
658 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
659 // ==== Thread Management Functions ====
661 \addtogroup CMSIS_RTOS_ThreadMgmt Thread Management
662 \ingroup CMSIS_RTOS CMSIS_RTOSv2
663 \brief Define, create, and control thread functions.
665 The Thread Management function group allows defining, creating, and controlling thread functions in the system. The function
666 \b main is a special thread function that is started at system initialization and has the initial priority
670 Threads can be in the following states:
671 - \b RUNNING: The thread that is currently running is in the \b RUNNING state. Only one thread at a time can be in this
673 - \b READY: Threads which are ready to run are in the \b READY state. Once the \b RUNNING thread has terminated or is
674 \b WAITING, the next \b READY thread with the highest priority becomes the \b RUNNING thread.
675 - \b WAITING: Threads that are waiting for an event to occur are in the \b WAITING state.
676 - \b INACTIVE: Threads that are not created or terminated are in the \b INACTIVE state. These threads typically consume no
679 \image html "ThreadStatus.png" "Thread State and State Transitions"
681 A CMSIS-RTOS assumes that threads are scheduled as shown in the figure <b>Thread State and State Transitions</b>. The thread
682 states change as follows:
683 - A thread is created using the function \ref osThreadNew. This puts the thread into the \b READY or \b RUNNING state
684 (depending on the thread priority).
685 - CMSIS-RTOS is pre-emptive. The active thread with the highest priority becomes the \b RUNNING thread provided it does not
686 wait for any event. The initial priority of a thread is defined with the \ref osThreadAttrInit but may be changed during
687 execution using the function \ref osThreadSetPriority.
688 - The \b RUNNING thread transfers into the \b WAITING state when it is waiting for an event.
689 - Active threads can be terminated any time using the function \ref osThreadTerminate. Threads can terminate also by just
690 returning from the thread function. Threads that are terminated are in the \b INACTIVE state and typically do not consume
691 any dynamic memory resources.
695 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
696 /** \def osThreadJoinable
699 - \ref osThreadAttr_t
703 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
704 /** \def osThreadDetached
707 - \ref osThreadAttr_t
708 - \ref osThreadDetach
711 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
712 /** \def osThreadAttrInit
713 Thread attributes initialization.
716 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
718 \typedef osThreadState_t
719 Thread state definitions.
722 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
724 \struct osThreadAttr_t
725 Attributes structure for thread.
728 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
730 \typedef osPriority_t
731 \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS.
732 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
734 The \ref osPriority value specifies the priority for a thread. The default thread priority should be \a osPriorityNormal.
735 If a Thread is active that has a higher priority than the currently executing thread, then a thread switch occurs immediately
736 to execute the new task.
738 To prevent from a priority inversion, a CMSIS-RTOS compliant OS may optionally implement a <b>priority inheritance</b> method.
739 A priority inversion occurs when a high priority thread is waiting for a resource or event that is controlled by a thread
740 with a lower priority.
743 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
744 /** \fn osThreadId osThreadNew (os_pthread pthread, void *argument, const osThreadAttr_t *attr)
745 \todo update osThreadNew description
746 Start a thread function by adding it to the Active Threads list and set it to state \b READY.
747 The thread function receives the \a argument pointer as function argument when the function is started.
748 When the priority of the created thread function is higher than the current \b RUNNING thread,
749 the created thread function starts instantly and becomes the new \b RUNNING thread.
751 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
755 #include "cmsis_os.h"
757 void Thread_1 (void const *arg); // function prototype for Thread_1
758 osThreadDef (Thread_1, osPriorityNormal, 1, 0); // define Thread_1
760 void ThreadCreate_example (void) {
763 id = osThreadCreate (osThread (Thread_1), NULL); // create the thread
764 if (id == NULL) { // handle thread creation
765 // Failed to create a thread
768 osThreadTerminate (id); // stop the thread
773 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
774 /** \fn osThreadId osThreadGetId (void)
775 Get the thread ID of the current running thread.
777 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
781 void ThreadGetId_example (void) {
782 osThreadId id; // id for the currently running thread
784 id = osThreadGetId ();
786 // Failed to get the id; not in a thread
792 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
793 /** \fn osThreadState osThreadGetState (osThreadId thread_id)
794 Get the state of a thread. In case of a failure the value \b osPriorityError is returned.
798 #include "cmsis_os.h"
800 void Thread_1 (void const *arg) { // Thread function
801 osThreadId id; // id for the currently running thread
802 osThreadState status; // thread state
804 id = osThreadGetId (); // Obtain ID of current running thread
807 status = osThreadGetState (id);
808 if (status == osThreadRunning) {
809 // Thread is currently running
812 // Check other options
816 // Failed to get the id
821 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
822 /** \fn osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority)
823 Change the priority of an active thread.
825 <b>\ref CMSIS_RTOS_Status</b>\n
826 - \em osOK: the priority of the specified thread has been successfully changed.
827 - \em osErrorParameter: thread_id is incorrect.
828 - \em osErrorValue: incorrect priority value.
829 - \em osErrorResource: thread_id refers to a thread that is not an active thread.
830 - \em osErrorISR: \ref osThreadSetPriority cannot be called from interrupt service routines.
832 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
836 #include "cmsis_os.h"
838 void Thread_1 (void const *arg) { // Thread function
839 osThreadId id; // id for the currently running thread
840 osPriority pr; // thread priority
841 osStatus status; // status of the executed function
844 id = osThreadGetId (); // Obtain ID of current running thread
847 status = osThreadSetPriority (id, osPriorityBelowNormal);
848 if (status == osOK) {
849 // Thread priority changed to BelowNormal
852 // Failed to set the priority
856 // Failed to get the id
863 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
864 /** \fn osPriority osThreadGetPriority (osThreadId thread_id)
865 Get the priority of an active thread. In case of a failure the value \b osPriorityError is returned.
867 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
871 #include "cmsis_os.h"
873 void Thread_1 (void const *arg) { // Thread function
874 osThreadId id; // id for the currently running thread
875 osPriority priority; // thread priority
877 id = osThreadGetId (); // Obtain ID of current running thread
880 priority = osThreadGetPriority (id);
883 // Failed to get the id
889 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
890 /** \fn osStatus osThreadYield (void)
891 Pass control to the next thread that is in state \b READY. If there is no other thread in the state \b READY,
892 the current thread continues execution and no thread switching occurs.
894 <b>\ref CMSIS_RTOS_Status</b>\n
895 - \em osOK: the function has been correctly executed.
896 - \em osErrorISR: \ref osThreadYield cannot be called from interrupt service routines.
898 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
902 #include "cmsis_os.h"
904 void Thread_1 (void const *arg) { // Thread function
905 osStatus status; // status of the executed function
908 status = osThreadYield(); //
909 if (status != osOK) {
910 // thread switch not occurred, not in a thread function
917 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
918 /** \fn osStatus osThreadSuspend (osThreadId thread_id)
919 Suspends the execution of a thread. If the thread is currently RUNNING the execution will stop.
923 #include "cmsis_os.h"
925 void Thread_1 (void const *arg) { // Thread function
926 osThreadId id; // id for the currently running thread
927 osStatus status; // thread status
929 id = osThreadGetId (); // Obtain ID of current running thread
932 status = osThreadSuspend(id);
933 if (status == osOK) {
934 // Thread is suspended
937 // Failed to suspend the thread
941 // Failed to get the id
946 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
947 /** \fn osStatus osThreadResume (osThreadId thread_id)
948 Resumes the execution of a thread.
952 #include "cmsis_os.h"
954 void Thread_1 (void const *arg) { // Thread function
955 osThreadId id; // id for the currently running thread
956 osStatus status; // thread status
958 id = osThreadGetId (); // Obtain ID of current running thread
961 status = osThreadResume(id);
962 if (status == osOK) {
966 // Failed to resume the thread
970 // Failed to get the id
975 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
976 /** \fn osStatus osThreadTerminate (osThreadId thread_id)
977 Remove the thread function from the active thread list. If the thread is currently RUNNING the execution will stop.
979 \note In case that \ref osThreadTerminate terminates the currently running task, the function never returns and other threads
980 that are in the READY state are started.
982 <b>\ref CMSIS_RTOS_Status</b>\n
983 - \em osOK: the specified thread has been successfully terminated.
984 - \em osErrorParameter: thread_id is incorrect.
985 - \em osErrorResource: thread_id refers to a thread that is not an active thread.
986 - \em osErrorISR: \ref osThreadTerminate cannot be called from interrupt service routines.
988 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
992 #include "cmsis_os.h"
994 void Thread_1 (void const *arg); // function prototype for Thread_1
995 osThreadDef (Thread_1, osPriorityNormal, 1, 0); // define Thread_1
997 void ThreadTerminate_example (void) {
1001 id = osThreadCreate (osThread (Thread_1), NULL); // create the thread
1003 status = osThreadTerminate (id); // stop the thread
1004 if (status == osOK) {
1005 // Thread was terminated successfully
1008 // Failed to terminate a thread
1017 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1018 // ==== Thread Flags Management Functions ====
1020 \addtogroup CMSIS_RTOS_ThreadFlagsMgmt Thread Flags Management Functions
1029 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1030 /** \def osFlagsWaitAny
1031 Wait forever timeout value.
1034 - \ref osEventFlagsWait
1035 - \ref osThreadFlagsWait
1038 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1039 /** \def osFlagsWaitAll
1042 - \ref osEventFlagsWait
1043 - \ref osThreadFlagsWait
1046 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1047 /** \def osFlagsAutoClear
1050 - \ref osEventFlagsWait
1051 - \ref osThreadFlagsWait
1054 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1055 /* \def osFeature_ThreadFlags
1056 Defined the maximum number of Thread Flags available per thread.
1059 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1060 /** \fn int32_t osThreadFlagsSet (osThreadId_t thread_id, int32_t flags )
1066 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1067 /** \fn osStatus osThreadFlagsClear (osThreadId thread_id, int32_t flags);
1074 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1075 /** \fn int32_t osThreadFlagsGet (osThreadId thread_id);
1082 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1083 /** \fn int32_t osThreadFlagsWait (int32_t flags, uint32_t options, uint32_t millisec);
1093 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1094 // ==== Generic Wait Functions ====
1096 \addtogroup CMSIS_RTOS_Wait Generic Wait Functions
1098 \brief Wait for a time period or unspecified events.
1100 The Generic Wait function group provides means for a time delay and allow to wait for unspecified events.
1105 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1106 /** \def osWaitForever
1107 Wait forever timeout value.
1114 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1115 /** \fn osStatus osDelay (uint32_t millisec)
1116 Wait for a specified time period in \a millisec.
1118 The \ref CMSIS_RTOS_TimeOutValue "millisec" value specifies the number of timer ticks and is therefore an upper bound. The
1119 exact time delay depends on the actual time elapsed since the last timer tick.
1121 For a value of <b>1</b>, the system waits until the next timer tick occurs. That means that the actual time delay may be up
1122 to one timer tick less.
1124 <b>\ref CMSIS_RTOS_Status</b>\n
1125 - \em osEventTimeout: the time delay is executed.
1126 - \em osErrorISR: \ref osDelay cannot be called from interrupt service routines.
1128 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1132 #include "cmsis_os.h"
1134 void Thread_1 (void const *arg) { // Thread function
1135 osStatus status; // capture the return status
1136 uint32_t delayTime; // delay time in milliseconds
1138 delayTime = 1000; // delay 1 second
1139 status = osDelay (delayTime); // suspend thread execution
1140 if (status != osOK) {
1141 // handle error code
1147 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1148 /** \fn osStatus osDelayUntil (uint64_t millisec)
1152 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1153 /** \fn uint32_t osEventWait (uint32_t millisec)
1155 Wait for an event for a specified time period in \a millisec. While the system waits, the thread that is calling this
1156 function is put into the state \b WAITING. When \a millisec is set to \b osWaitForever, the function will wait for an
1157 infinite time until an event occurs.
1159 \todo Update osEventWait description.
1168 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1169 // ==== Timer Management Functions ====
1171 \addtogroup CMSIS_RTOS_TimerMgmt Timer Management
1173 \brief Create and control timer and timer callback functions.
1175 In addition to the \ref CMSIS_RTOS_Wait CMSIS-RTOS also supports virtual timer objects. These timer objects can
1176 trigger the execution of a function (not threads). When a timer expires, a callback function is executed to run associated
1177 code with the timer. The timer number is passed as a parameter to the callback function. Each timer can be configured as a
1178 one-shot or a periodic timer. A periodic timer repeats its operation until it is \ref osTimerDelete "deleted" or
1179 \ref osTimerStop "stopped". All timers can be \ref osTimerStart "started, restarted", or \ref osTimerStop "stopped".
1181 Timers are handled in the thread \b osTimerThread. Callback functions run under control of this thread and may use other
1182 CMSIS-RTOS API calls.
1184 The figure below shows the behavior of a periodic timer. For one-shot timers, the timer stops after execution of the
1187 \image html "Timer.png" "Behavior of a Periodic Timer"
1190 --------------------
1191 The following steps are required to use a timer:
1192 -# Define the timers:
1194 //osTimerDef(one_shot, start_machine); // when the timer expires, the function start_machine is called
1195 //osTimerDef(periodic, toggle_power); // when the timer expires, the function toggle_power is called
1196 osTimerId one_shot_id, periodic_id;
1198 -# Instantiate and start the timers in an RTOS thread:
1200 one_shot_id = osTimerCreate(osTimer(one_shot), osTimerOnce, (void *)0); // creates a one-shot timer;
1201 // (void*)0 is passed as an argument
1202 // to the callback function
1203 periodic_id = osTimerCreate(osTimer(periodic), osTimerPeriodic, (void *)5); // creates a periodic timer;
1204 // (void*)5 is passed as an argument
1205 // to the callback function
1206 osTimerStart(one_shot_id, 500);
1207 osTimerStart(periodic, 1500);
1214 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1215 /** \def osTimerAttrInit
1216 Timer attributes initialization.
1219 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1220 /** \typedef os_timer_type
1221 The \ref os_timer_type specifies the a repeating (periodic) or one-shot timer for the function \ref osTimerNew.
1224 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1225 /** \struct osTimerAttr_t
1226 Attributes structure for timer.
1229 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1230 /** \fn osTimerId osTimerNew (os_ptimer ptimer, os_timer_type type, void *argument, const osTimerAttr_t *attr)
1231 Create a one-shot or periodic timer and associate it with a callback function argument. The timer is in stopped until it is
1232 started with \ref osTimerStart.
1234 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1238 #include "cmsis_os.h"
1240 void Timer1_Callback (void const *arg); // prototypes for timer callback function
1241 void Timer2_Callback (void const *arg);
1243 osTimerDef (Timer1, Timer1_Callback); // define timers
1244 osTimerDef (Timer2, Timer2_Callback);
1246 uint32_t exec1; // argument for the timer call back function
1247 uint32_t exec2; // argument for the timer call back function
1249 void TimerCreate_example (void) {
1250 osTimerId id1; // timer id
1251 osTimerId id2; // timer id
1253 // Create one-shoot timer
1255 id1 = osTimerCreate (osTimer(Timer1), osTimerOnce, &exec1);
1257 // One-shoot timer created
1260 // Create periodic timer
1262 id2 = osTimerCreate (osTimer(Timer2), osTimerPeriodic, &exec2);
1264 // Periodic timer created
1270 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1271 /** \fn osStatus osTimerStart (osTimerId timer_id, uint32_t millisec)
1272 Start or restart the timer.
1274 <b>\ref CMSIS_RTOS_Status</b>\n
1275 - \em osOK: the specified timer has been started or restarted.
1276 - \em osErrorISR: \b osTimerStart cannot be called from interrupt service routines.
1277 - \em osErrorParameter: \a timer_id is incorrect.
1279 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1283 #include "cmsis_os.h"
1285 void Time_Callback (void const *arg) { // timer callback function
1286 // arg contains &exec
1287 // called every second after osTimerStart
1290 osTimerDef (Timer, Time_Callback); // define timer
1291 uint32_t exec; // argument for the timer call back function
1293 void TimerStart_example (void) {
1294 osTimerId id; // timer id
1295 uint32_t timerDelay; // timer value
1296 osStatus status; // function return status
1298 // Create periodic timer
1300 id = osTimerNew (osTimer(Timer), osTimerPeriodic, &exec);
1303 status = osTimerStart (id, timerDelay); // start timer
1304 if (status != osOK) {
1305 // Timer could not be started
1312 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1313 /** \fn osStatus osTimerStop (osTimerId timer_id)
1316 <b>\ref CMSIS_RTOS_Status</b>\n
1317 - \em osOK: the specified timer has been stopped.
1318 - \em osErrorISR: \ref osTimerStop cannot be called from interrupt service routines.
1319 - \em osErrorParameter: \a timer_id is incorrect.
1320 - \em osErrorResource: the timer is not started.
1322 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1326 #include "cmsis_os.h"
1328 void Timer_Callback (void const *arg); // prototype for timer callback function
1329 osTimerDef (Timer, Timer_Callback); // define timer
1331 void TimerStop_example (void) {
1332 osTimerId id; // timer id
1333 osStatus status; // function return status
1335 // Create periodic timer
1337 id = osTimerCreate (osTimer(Timer2), osTimerPeriodic, NULL);
1338 osTimerStart (id, 1000); // start timer
1340 status = osTimerStop (id); // stop timer
1341 if (status != osOK) {
1342 // Timer could not be stopped
1344 osTimerStart (id, 1000); // start timer again
1349 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1350 /** \fn int32_t osTimerIsRunning (osTimerId timer_id)
1354 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1355 /** \fn osStatus osTimerDelete (osTimerId timer_id)
1356 Delete the timer object.
1358 <b>\ref CMSIS_RTOS_Status</b>\n
1359 - \em osOK: the specified timer has been deleted.
1360 - \em osErrorISR: \ref osTimerDelete cannot be called from interrupt service routines.
1361 - \em osErrorParameter: \a timer_id is incorrect.
1363 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1367 #include "cmsis_os.h"
1369 void Timer_Callback (void const *arg); // prototype for timer callback function
1370 osTimerDef (Timer, Timer_Callback); // define timer
1372 void TimerDelete_example (void) {
1373 osTimerId id; // timer id
1374 osStatus status; // function return status
1376 // Create periodic timer
1378 id = osTimerCreate (osTimer(Timer2), osTimerPeriodic, NULL);
1379 osTimerStart (id, 1000UL); // start timer
1381 status = osTimerDelete (id); // stop and delete timer
1382 if (status != osOK) {
1383 // Timer could not be deleted
1392 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1393 // ==== Inter-Thread Communication Functions ====
1395 \addtogroup CMSIS_RTOS_InterThread Inter-Thread Communication and Resource Sharing
1397 \brief Functions for inter-thread communication.
1399 In most applications, threads need to \b communicate \b with \b each \b other or \b access \b shared \b resources together.
1400 There are many ways to exchange data between threads, for example using shared data, polling loops and message passing.
1402 Many resources in a microcontroller can be considered as \b serially-reusable. This means that they can be used repeatedly by
1403 different threads, but only by \b one \b thread \b at \b a \b time (for example communication peripherals such as \b UARTs,
1404 \b memory, and \b files that need to be modified).
1407 The CMSIS-RTOS API provides different means to pass messages between threads to make inter-thread communication more
1408 efficient. Also, resource sharing is inherently supported. The following methods are available to the user:
1409 Inter-Thread Communication
1410 --------------------------
1411 - \ref CMSIS_RTOS_ThreadFlagsMgmt
1412 - \ref CMSIS_RTOS_EventFlags
1413 - \ref CMSIS_RTOS_Message
1414 - \ref CMSIS_RTOS_PoolMgmt
1415 - \ref CMSIS_RTOS_Mail
1419 - \ref CMSIS_RTOS_MutexMgmt
1420 - \ref CMSIS_RTOS_SemaphoreMgmt
1425 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1426 // ==== Event Flag Management Functions ====
1428 \addtogroup CMSIS_RTOS_EventFlags Event Flag Objects
1429 \ingroup CMSIS_RTOS_InterThread
1430 \brief Synchronize threads using flags.
1432 \todo add details here.
1436 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1437 /** \def osEventFlagsAttrInit
1438 Event Flags attributes initialization.
1441 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1442 /** \def osFeature_EventWait
1443 Defines if \ref osEventWait is available or not.
1446 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1447 /** \def osFeature_EventFlags
1448 Defines the maximum number of Event Flags available per object.
1451 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1452 /** \struct osEventFlagsAttr_t
1453 Attributes structure for event flags.
1456 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1457 /** \fn osEventFlagsId osEventFlagsNew (const osEventFlagsAttr_t *attr)
1458 Create and initialize a flag object.
1462 #include "cmsis_os.h"
1464 osFlagDef (my_flag); // Flag name definition
1466 void CreateFlag (void) {
1467 osFlagId my_flag_id;
1469 my_flag_id = osFlagCreate (osFlag(my_flag));
1470 if (my_flag_id != NULL) {
1471 // Flag object created
1477 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1478 /** \fn osStatus osEventFlagsSet (osEventFlagsId flags_id, int32_t flags)
1479 Set one or more flags for a flag object. Returns all flags for the specified flag object \a after the manipulation.
1483 #include "cmsis_os.h"
1485 osFlagDef my_flag; // Flag name definition
1486 osFlagId my_flag_id; // Flag ID populated by the function osFlagCreate()
1488 void SetFlagValues (osFlagId my_flag_id) {
1491 if (my_flag_id != NULL) {
1492 flags = osFlagSet(my_flag_id, 0x17);
1498 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1499 /** \fn osStatus osEventFlagsClear (osEventFlagsId flags_id, int32_t flags)
1500 Clear one or more flags of a flag object. Returns all flags for the specified flag object \a after the manipulation.
1504 #include "cmsis_os.h"
1506 osFlagDef my_flag; // Flag name definition
1507 osFlagId my_flag_id; // Flag ID populated by the function osFlagCreate()
1509 void ClearFlagValues (osFlagId my_flag_id) {
1512 if (my_flag_id != NULL) {
1513 flags = osFlagClear(my_flag_id, 0x10);
1519 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1520 /** \fn int32_t osEventFlagsGet (osEventFlagsId flags_id)
1521 Retrieve the current flags of a flag object without changing the flag values. The functions \ref osEventFlagsSet and
1522 \ref osEventFlagsClear also return the flags for a given flag object but after they have changed them.
1526 #include "cmsis_os.h"
1528 osFlagDef my_flag; // Flag name definition
1529 osFlagId my_flag_id; // Flag ID populated by the function osFlagCreate()
1531 void GetFlagValues (osFlagId my_flag_id) {
1534 if (my_flag_id != NULL) {
1535 flags = osFlagGet(my_flag_id);
1536 // work with the flags
1543 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1544 /** \fn int32_t osEventFlagsWait (osEventFlagsId flags_id, int32_t flags, uint32_t options, uint32_t millisec)
1545 Suspend the execution of the current \b RUNNING thread until one or more \a flags are set for flag object specified by
1546 \a flag_id. When the flags that are waited for are already set, the function returns instantly.
1548 The argument \a attributes can be used to specify whether to wait for \b any specified flag in the \a flags argument
1549 (default) or to wait for all \a flags to be set (use \c osFlagWaitForAll). Specifying \c osFlagAutoClear will automatically
1550 clear \b any specified flag in the \a flags argument (default) or all \a flags when used in conjunction with
1551 \c osFlagWaitForAll.
1553 The argument \a millisec specifies how long the system waits for a message to become available. While the system waits, the
1554 calling thread is put into the state \b WAITING. The \a millisec timeout value can have the following values:
1555 - when \a millisec is 0, the function returns instantly.
1556 - when \a millisec is set to \b osWaitForever the function will wait for an infinite time until a message arrives.
1557 - all other values specify a time in millisecond for a timeout.
1559 \note The parameter \a millisec must be 0 for using this function in an ISR.
1560 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
1562 <b>\ref CMSIS_RTOS_Status</b>\n
1563 - \em osOK: no message is available in the queue and no timeout was specified.
1564 - \em osEventTimeout: no message has arrived during the given timeout period.
1565 - \em osEventMessage: message received, \em value.p contains the pointer to message.
1566 - \em osErrorParameter: a parameter is invalid or outside of a permitted range.
1570 #include "cmsis_os.h"
1572 osFlagDef my_flag; // Flag name definition
1573 osFlagId my_flag_id; // Flag ID populated by the function osFlagCreate()
1575 void StartApplication (void) {
1576 my_flag_id = osFlagCreate (osFlag(my_flag));
1577 if (my_flag_id != NULL) {
1578 event = osFlagWait(my_flag_id, 0x17, osFlagWaitForAll,0);
1579 if (event != osOK) {
1580 // handle failure code
1585 // flag object not created
1591 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1592 /** \fn osStatus osEventFlagsDelete (osEventFlagsId flags_id)
1593 Delete a flag object. The function releases internal memory obtained for flag handling. After this call the flag ID is no
1594 longer valid and cannot be used. The flag may be created again using the function \ref osEventFlagsNew.
1598 #include "cmsis_os.h"
1600 osFlagDef my_flag; // Flag name definition
1601 osFlagId my_flag_id; // Flag ID populated by the function osFlagCreate()
1603 void DeleteFlag (osFlagId my_flag_id) {
1606 if (my_flag_id != NULL) {
1607 status = osFlagDelete(my_flag_id);
1608 if (status != osOK) {
1609 // handle failure code
1619 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1620 // ==== Mutex Management Functions ====
1622 \addtogroup CMSIS_RTOS_MutexMgmt Mutexes
1623 \ingroup CMSIS_RTOS_InterThread
1624 \brief Synchronize resource access using Mutual Exclusion (Mutex).
1626 <b>Mutual exclusion</b> (widely known as \b Mutex) is used in various operating systems for resource management. Many
1627 resources in a microcontroller device can be used repeatedly, but only by one thread at a time (for example communication
1628 channels, memory, and files). Mutexes are used to protect access to a shared resource. A mutex is created and then passed
1629 between the threads (they can acquire and release the mutex).
1631 \image html "Mutex.png" "CMSIS-RTOS Mutex"
1633 A mutex is a special version of a \ref CMSIS_RTOS_SemaphoreMgmt "semaphore". Like the semaphore, it is a container for
1634 tokens. But instead of being able to have multiple tokens, a mutex can only carry one (representing the resource). Thus, a
1635 mutex token is binary and bounded. The advantage of a mutex is that it introduces thread ownership. When a thread acquires a
1636 mutex and becomes its owner, subsequent mutex acquires from that thread will succeed immediately without any latency. Thus,
1637 mutex acquires/releases can be nested.
1640 - Mutex management functions cannot be called from interrupt service routines (ISR), unlike a binary semaphore that can be
1641 released from an ISR.
1643 Working with Mutexes
1644 --------------------
1645 To use mutexes, you need to follow these steps for creating and using them:
1646 -# Declare the mutex container and initialize the mutex:
1648 //osMutexDef (uart_mutex); // Declare mutex
1649 osMutexId (uart_mutex_id); // Mutex ID
1651 -# Create the mutex in a thread:
1653 uart_mutex_id = osMutexCreate(osMutex(uart_mutex));
1655 -# Acquire the mutex when peripheral access is required:
1657 osMutexWait(uart_mutex_id, osWaitForever);
1659 -# When finished with the peripheral access, release the mutex:
1661 osMutexRelease(uart_mutex_id);
1668 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1669 /** \def osMutexAttrInit
1670 Mutex attributes initialization.
1673 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1674 /** \struct osMutexAttr_t
1675 Attributes structure for mutex.
1678 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1679 /** \fn osMutexId osMutexNew (const osMutexAttr_t *attr)
1680 Create and initialize a Mutex object.
1682 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1686 #include "cmsis_os.h"
1688 osMutexDef (MutexIsr); // Mutex name definition
1690 void CreateMutex (void) {
1693 mutex_id = osMutexCreate (osMutex (MutexIsr));
1694 if (mutex_id != NULL) {
1695 // Mutex object created
1701 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1702 /** \fn osStatus osMutexAcquire (osMutexId mutex_id, uint32_t millisec)
1703 Wait until a Mutex becomes available. If no other thread has obtained the Mutex, the function instantly returns and blocks
1706 The argument \a millisec specifies how long the system waits for a mutex.
1707 While the system waits the thread that is calling this function is put into the state \b WAITING.
1708 The \a millisec timeout can have the following values:
1709 - when \a millisec is 0, the function returns instantly.
1710 - when \a millisec is set to \b osWaitForever the function will wait for an infinite time until the mutex becomes available.
1711 - all other values specify a time in millisecond for a timeout.
1713 <b>\ref CMSIS_RTOS_Status</b>\n
1714 - \em osOK: the mutex has been obtained.
1715 - \em osErrorTimeoutResource: the mutex could not be obtained in the given time.
1716 - \em osErrorResource: the mutex could not be obtained when no timeout was specified.
1717 - \em osErrorParameter: the parameter \a mutex_id is incorrect.
1718 - \em osErrorISR: \b osMutexAcquire cannot be called from interrupt service routines.
1720 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1724 #include "cmsis_os.h"
1726 osMutexDef (MutexIsr);
1728 void WaitMutex (void) {
1732 mutex_id = osMutexCreate (osMutex (MutexIsr));
1733 if (mutex_id != NULL) {
1734 status = osMutexWait (mutex_id, 0);
1735 if (status != osOK) {
1736 // handle failure code
1743 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1744 /** \fn osStatus osMutexRelease (osMutexId mutex_id)
1745 Release a Mutex that was obtained with \ref osMutexAcquire. Other threads that currently wait for the same mutex will be now
1746 put into the state \b READY.
1748 <b>\ref CMSIS_RTOS_Status</b>\n
1749 - \em osOK: the mutex has been correctly released.
1750 - \em osErrorResource: the mutex was not obtained before.
1751 - \em osErrorParameter: the parameter \a mutex_id is incorrect.
1752 - \em osErrorISR: \ref osMutexRelease cannot be called from interrupt service routines.
1754 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1758 #include "cmsis_os.h"
1760 osMutexDef (MutexIsr); // Mutex name definition
1761 osMutexId mutex_id; // Mutex id populated by the function CreateMutex()
1762 osMutexId CreateMutex (void); // function prototype that creates the Mutex
1764 void ReleaseMutex (osMutexId mutex_id) {
1767 if (mutex_id != NULL) {
1768 status = osMutexRelease(mutex_id);
1769 if (status != osOK) {
1770 // handle failure code
1777 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1778 /** \fn osStatus osMutexDelete (osMutexId mutex_id)
1779 Delete a Mutex object. The function releases internal memory obtained for Mutex handling. After this call the \a mutex_id is
1780 no longer valid and cannot be used. The Mutex may be created again using the function \ref osMutexNew.
1782 <b>\ref CMSIS_RTOS_Status</b>\n
1783 - \em osOK: the mutex object has been deleted.
1784 - \em osErrorISR: \ref osMutexDelete cannot be called from interrupt service routines.
1785 - \em osErrorResource: all tokens have already been released.
1786 - \em osErrorParameter: the parameter \a mutex_id is incorrect.
1788 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1792 #include "cmsis_os.h"
1794 osMutexDef (MutexIsr); // Mutex name definition
1795 osMutexId mutex_id; // Mutex id populated by the function CreateMutex()
1796 osMutexId CreateMutex (void); // function prototype that creates the Mutex
1798 void DeleteMutex (osMutexId mutex_id) {
1801 if (mutex_id != NULL) {
1802 status = osMutexDelete(mutex_id);
1803 if (status != osOK) {
1804 // handle failure code
1813 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1814 // ==== Semaphore Management Functions ====
1816 \addtogroup CMSIS_RTOS_SemaphoreMgmt Semaphores
1817 \ingroup CMSIS_RTOS_InterThread
1818 \brief Access shared resources simultaneously from different threads.
1820 Semaphores are used to manage and protect access to shared resources. Semaphores are very similar to
1821 \ref CMSIS_RTOS_MutexMgmt "Mutexes". Whereas a Mutex permits just one thread to access a shared resource at a
1822 time, a semaphore can be used to permit a fixed number of threads to access a pool of shared resources. Using semaphores,
1823 access to a group of identical peripherals can be managed (for example multiple DMA channels).
1825 \image html "Semaphore.png" "CMSIS-RTOS Semaphore"
1827 A semaphore object should be initialized to the maximum number of available tokens. This number of available resources is
1828 specified as parameter of the \ref osSemaphoreNew function. Each time a semaphore token is obtained with
1829 \ref osSemaphoreAcquire, the semaphore count is decremented. When the semaphore count is 0, no semaphore token can be
1830 obtained. The thread that tries to obtain the semaphore token needs to wait until the next token is free. Semaphores are
1831 released with \ref osSemaphoreRelease incrementing the semaphore count.
1833 \note Semaphore tokens can be acquired from threads and released from threads and ISRs.
1835 Working with Semaphores
1836 --------------------
1837 Follow these steps to create and use a semaphore:
1838 -# Declare the semaphore container and initialize the semaphore:
1840 osSemaphoreDef (my_semaphore); // Declare semaphore
1841 osSemaphoreId (my_semaphore_id); // Semaphore ID
1843 -# Initialize the semaphore container with a number of tokens within a thread:
1845 my_semaphore_id = osSemaphoreCreate(osSemaphore(my_semaphore), 4); // Create semaphore with 4 tokens
1847 \b Important: semaphore tokens can be created and destroyed as threads run. This means that can initialize a semaphore with
1848 zero tokens and then use one thread to add/create tokens to the semaphore while a second thread removes them. In this way you
1849 can distinguish between producer and consumer threads.
1850 -# Acquire a token from the semaphore container:
1852 osSemaphoreWait(my_semaphore_id, osWaitForever);
1854 -# When finished using the semaphore resource, send the token back to the semaphore container:
1856 osSemaphoreRelease(my_semaphore_id);
1861 Due to their flexibility, semaphores cover a wide range of synchronizing applications. At the same time, they are perhaps the
1862 most challenging RTOS object to understand. The following explains a use case for semaphores, taken from the book
1863 <a href="http://www.greenteapress.com/semaphores/" target="_blank">The Little Book Of Semaphores</a> by Allen B. Downey which
1864 is available for free download.
1866 <b>Non-binary Semaphore (Multiplex)</b>
1868 A multiplex limits the number of threads that can access a critical section of code. For example, this could be a function
1869 accessing DMA resources which can only support a limited number of calls.
1871 To allow multiple threads to run the function, initialize a semaphore to the maximum number of threads that can be allowed.
1872 The number of tokens in the semaphore represents the number of additional threads that may enter. If this number is zero,
1873 then the next thread trying to access the function will have to wait until one of the other threads exits and releases its
1874 token. When all threads have exited the token number is back to n. Ths following example shows the code for one of the
1875 threads that might access the resource:
1878 osSemaphoreDef(multiplex);
1879 osSemaphoreId (multiplex_id);
1881 void thread_n (void)
1883 multiplex_id = osSemaphoreCreate(osSemaphore(multiplex), 3);
1886 osSemaphoreWait(multiplex_id, osWaitForever);
1888 osSemaphoreRelease(multiplex_id);
1896 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1897 /** \def osFeature_SemaphoreTokens
1898 Defines the maximum number of tokens per semaphore.
1901 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1902 /** \def osSemaphoreAttrInit
1903 Semaphore attributes initialization.
1906 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1907 /** \struct osSemaphoreAttr_t
1908 Attributes structure for semaphore.
1911 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1912 /** \fn osSemaphoreId osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
1913 Create and initialize a Semaphore object that is used to manage access to shared resources. The parameter \em count specifies
1914 the number of available resources. The \em count value 1 creates a binary semaphore.
1916 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1920 #include "cmsis_os.h"
1922 osThreadId tid_thread1; // ID for thread 1
1923 osThreadId tid_thread2; // ID for thread 2
1925 osSemaphoreId semaphore; // Semaphore ID
1926 osSemaphoreDef(semaphore); // Semaphore definition
1929 // Thread 1 - High Priority - Active every 3ms
1931 void thread1 (void const *argument) {
1935 osDelay(3); // Pass control to other tasks for 3ms
1936 val = osSemaphoreWait (semaphore, 1); // Wait 1ms for the free semaphore
1938 // If there was no time-out the semaphore was acquired
1939 : // OK, the interface is free now, use it.
1940 osSemaphoreRelease (semaphore); // Return a token back to a semaphore
1946 // Thread 2 - Normal Priority - looks for a free semaphore and uses
1947 // the resource whenever it is available
1949 void thread2 (void const *argument) {
1951 osSemaphoreWait (semaphore, osWaitForever); // Wait indefinitely for a free semaphore
1952 // OK, the interface is free now, use it.
1954 osSemaphoreRelease (semaphore); // Return a token back to a semaphore.
1958 // Thread definitions
1959 osThreadDef(thread1, osPriorityHigh, 1, 0);
1960 osThreadDef(thread2, osPriorityNormal, 1, 0);
1962 void StartApplication (void) {
1963 semaphore = osSemaphoreCreate(osSemaphore(semaphore), 1);
1965 tid_thread1 = osThreadCreate(osThread(thread1), NULL);
1966 tid_thread2 = osThreadCreate(osThread(thread2), NULL);
1972 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1973 /** \fn osStatus osSemaphoreAcquire (osSemaphoreId semaphore_id, uint32_t millisec)
1974 Wait until a Semaphore token becomes available. When no Semaphore token is available, the function waits for the time
1975 specified with the parameter \em millisec.
1977 The argument \a millisec specifies how long the system waits for a Semaphore token to become available.
1978 While the system waits the thread that is calling this function is put into the state \b WAITING.
1979 The \a millisec timeout can have the following values:
1980 - when \a millisec is 0, the function returns instantly.
1981 - when \a millisec is set to \b osWaitForever the function will wait for an infinite time until the Semaphore token becomes
1983 - all other values specify a time in millisecond for a timeout.
1985 The return value indicates the number of available tokens (the semaphore count value). If 0 is returned, then no semaphore
1988 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1991 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1992 /** \fn osStatus osSemaphoreRelease (osSemaphoreId semaphore_id)
1993 Release a Semaphore token. This increments the count of available semaphore tokens.
1995 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
1997 <b>\ref CMSIS_RTOS_Status</b>\n
1998 - \em osOK: the semaphore has been released.
1999 - \em osErrorResource: all tokens have already been released.
2000 - \em osErrorParameter: the parameter \a semaphore_id is incorrect.
2003 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2004 /** \fn osStatus osSemaphoreDelete (osSemaphoreId semaphore_id)
2005 Delete a Semaphore object. The function releases internal memory obtained for Semaphore handling. After this call the
2006 \a semaphore_id is no longer valid and cannot be used. The Semaphore may be created again using the function
2007 \ref osSemaphoreNew.
2009 <b>\ref CMSIS_RTOS_Status</b>\n
2010 - \em osOK: the semaphore object has been deleted.
2011 - \em osErrorISR: \ref osSemaphoreDelete cannot be called from interrupt service routines.
2012 - \em osErrorResource: the semaphore object could not be deleted.
2013 - \em osErrorParameter: the parameter \a semaphore_id is incorrect.
2015 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
2020 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2021 // ==== Memory Pool Management Functions ====
2023 \addtogroup CMSIS_RTOS_PoolMgmt Memory Pool
2024 \ingroup CMSIS_RTOS_InterThread
2025 \brief Manage thread-safe fixed-size blocks of dynamic memory.
2027 \b Memory \b pools are fixed-size blocks of memory that are thread-safe. They operate much faster than the dynamically
2028 allocated heap and do not suffer from fragmentation. Being thread-safe, they can be accessed from threads and ISRs alike.
2030 \b Shared \b memory is one of the basic models to exchange information between threads. Using memory pools for exchanging
2031 data, you can share more complex objects between threads if compared to a \ref CMSIS_RTOS_Message. Memory pool management
2032 functions are used to define and manage such fixed-sized memory pools.
2034 Working with Memory Pools
2035 -------------------------
2036 Follow these steps to create and use a memory pool:
2037 -# Declare a data structure that combines a number of elements:
2046 -# Declare a memory pool of these objects as a block of memory:
2048 osPoolDef (object_pool, 10, properties_t); // Declare memory pool
2049 osPoolId (object_pool_id); // Memory pool ID
2051 -# Then, create the memory pool in a thread:
2053 object_pool_id = osPoolCreate(osPool(object_pool));
2055 -# Allocate the pool within a thread and fill it with data:
2057 properties_t *object_data;
2058 *object_data = (properties_t *) osPoolAlloc(object_pool_id);
2060 object_data->length = 100;
2061 object_data->width = 10;
2062 object_data->height = 23;
2063 object_data->weight = 1000;
2069 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2070 /** \def osMemoryPoolAttrInit
2071 Memory Pool attributes initialization.
2074 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2075 /** \def osMemoryPoolMem
2076 User memory allocation for Memory Pool data.
2079 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2080 /** \def osFeature_MemoryPool
2081 Defines whether Memory Pools are available or not.
2084 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2085 /** \struct osMemoryPoolAttr_t
2086 Attributes structure for memory pool.
2089 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2090 /** \fn osMemoryPoolId osMemoryPoolNew (uint32_t block_max, uint32_t block_size, void *memory, const osMemoryPoolAttr_t *attr)
2091 Create and initialize a memory pool.
2093 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
2097 #include "cmsis_os.h"
2104 osPoolDef (MemPool, 8, MEM_BLOCK);
2106 void CreateMemoryPool (void) {
2107 osPoolId MemPool_Id;
2109 MemPool_Id = osPoolCreate (osPool (MemPool));
2110 if (MemPool_Id != NULL) {
2111 // memory pool created
2117 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2118 /** \fn void *osMemoryPoolAlloc (osMemoryPoolId pool_id)
2119 Allocate a memory block from the memory pool.
2121 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2125 #include "cmsis_os.h"
2132 osPoolDef (MemPool, 8, MEM_BLOCK);
2134 void AlocMemoryPoolBlock (void) {
2135 osPoolId MemPool_Id;
2138 MemPool_Id = osPoolCreate (osPool (MemPool));
2139 if (MemPool_Id != NULL) {
2141 // allocate a memory block
2142 addr = (MEM_BLOCK *)osPoolAlloc (MemPool_Id);
2145 // memory block was allocated
2153 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2154 /** \fn osStatus osMemoryPoolFree (osMemoryPoolId pool_id, void *block)
2155 Return a memory block to a memory pool.
2157 <b>\ref CMSIS_RTOS_Status</b>\n
2158 - \em osOK: the memory block is released.
2159 - \em osErrorValue: \a block does not belong to the memory pool.
2160 - \em osErrorParameter: a parameter is invalid or outside of a permitted range.
2162 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2166 #include "cmsis_os.h"
2173 osPoolDef (MemPool, 8, MEM_BLOCK);
2175 void CAlocMemoryPoolBlock (void) {
2176 osPoolId MemPool_Id;
2180 MemPool_Id = osPoolCreate (osPool (MemPool));
2181 if (MemPool_Id != NULL) {
2182 addr = (MEM_BLOCK *)osPoolCAlloc (MemPool_Id);
2185 // return a memory block back to pool
2186 status = osPoolFree (MemPool_Id, addr);
2188 // handle status code
2196 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2197 /** \fn osStatus osMemoryPoolGetInfo (osMemoryPoolId pool_id, uint32_t *block_max, uint32_t *block_size, uint32_t *block_used)
2201 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2202 /** \fn osStatus osMemoryPoolDelete (osMemoryPoolId pool_id)
2209 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2210 // ==== Message Queue Management Functions ====
2212 @addtogroup CMSIS_RTOS_Message Message Queue
2213 @ingroup CMSIS_RTOS_InterThread
2214 @brief Exchange messages between threads in a FIFO-like operation.
2216 \b Message \b passing is another basic communication model between threads. In the message passing model, one thread sends
2217 data explicitly, while another thread receives it. The operation is more like some kind of I/O rather than a direct access to
2218 information to be shared. In CMSIS-RTOS, this mechanism is called s \b message \b queue. The data is passed from one thread
2219 to another in a FIFO-like operation. Using message queue functions, you can control, send, receive, or wait for messages. The
2220 data to be passed can be of integer or pointer type:
2222 \image html "MessageQueue.png" "CMSIS-RTOS Message Queue"
2224 Compared to a \ref CMSIS_RTOS_PoolMgmt, message queues are less efficient in general, but solve a broader range of problems.
2225 Sometimes, threads do not have a common address space or the use of shared memory raises problems, such as mutual exclusion.
2227 Working with Message Queues
2228 ---------------------------
2229 Follow these steps to create and use a message queue:
2230 -# Setup the message queue:
2232 osMessageQDef(message_q, 5, uint32_t); // Declare a message queue
2233 osMessageQId (message_q_id); // Declare an ID for the message queue
2235 -# Then, create the message queue in a thread:
2237 message_q_id = osMessageCreate(osMessageQ(message_q), NULL);
2239 -# Fill the message queue with data:
2241 uint32_t data = 512;
2243 osMailPut(message_q_id, data, osWaitForever);
2245 -# From the receiving thread access the data using:
2247 osEvent event = osMessageGet(message_q_id, osWaitForever);
2253 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2254 /** \def osFeature_MessageQueue
2255 Defines whether Message Queues are available or not.
2258 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2259 /** \def osMessageQueueAttrInit
2260 Message Queue attributes initialization.
2263 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2264 /** \def osMessageQueueMem
2265 User memory allocation for Message Queue data.
2268 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2269 /** \struct osMessageQueueAttr_t
2270 Attributes structure for message queue.
2273 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2274 /** \fn osMessageQueueId osMessageQueueNew (uint32_t queue_size, void *memory, const osMessageQueueAttr_t *attr)
2275 Create and initialize a message queue.
2277 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
2281 #include "cmsis_os.h"
2283 osThreadId tid_thread1; // ID for thread 1
2284 osThreadId tid_thread2; // for thread 2
2286 typedef struct { // Message object structure
2287 float voltage; // AD result of measured voltage
2288 float current; // AD result of measured current
2289 int counter; // A counter value
2292 osPoolDef(mpool, 16, T_MEAS); // Define memory pool
2294 osMessageQDef(MsgBox, 16, T_MEAS); // Define message queue
2295 osMessageQId MsgBox;
2297 void send_thread (void const *argument); // forward reference
2298 void recv_thread (void const *argument); // forward reference
2299 // Thread definitions
2300 osThreadDef(send_thread, osPriorityNormal, 1, 0);
2301 osThreadDef(recv_thread, osPriorityNormal, 1, 2000);
2304 // Thread 1: Send thread
2306 void send_thread (void const *argument) {
2309 mptr = osPoolAlloc(mpool); // Allocate memory for the message
2310 mptr->voltage = 223.72; // Set the message content
2311 mptr->current = 17.54;
2312 mptr->counter = 120786;
2313 osMessagePut(MsgBox, (uint32_t)mptr, osWaitForever); // Send Message
2316 mptr = osPoolAlloc(mpool); // Allocate memory for the message
2317 mptr->voltage = 227.23; // Prepare a 2nd message
2318 mptr->current = 12.41;
2319 mptr->counter = 170823;
2320 osMessagePut(MsgBox, (uint32_t)mptr, osWaitForever); // Send Message
2321 osThreadYield(); // Cooperative multitasking
2322 // We are done here, exit this thread
2326 // Thread 2: Receive thread
2328 void recv_thread (void const *argument) {
2333 evt = osMessageGet(MsgBox, osWaitForever); // wait for message
2334 if (evt.status == osEventMessage) {
2336 printf ("\nVoltage: %.2f V\n", rptr->voltage);
2337 printf ("Current: %.2f A\n", rptr->current);
2338 printf ("Number of cycles: %d\n", rptr->counter);
2339 osPoolFree(mpool, rptr); // free memory allocated for message
2344 void StartApplication (void) {
2345 mpool = osPoolCreate(osPool(mpool)); // create memory pool
2346 MsgBox = osMessageCreate(osMessageQ(MsgBox), NULL); // create msg queue
2348 tid_thread1 = osThreadCreate(osThread(send_thread), NULL);
2349 tid_thread2 = osThreadCreate(osThread(recv_thread), NULL);
2355 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2356 /** \fn osStatus osMessageQueuePut (osMessageQueueId queue_id, uint32_t message, uint32_t millisec)
2357 Put the message \a info in a message queue specified by \a queue_id.
2359 When the message queue is full, the system retries for a specified time with \a millisec.
2360 While the system retries the thread that is calling this function is put into the state \b WAITING.
2361 The \a millisec timeout can have the following values:
2362 - when \a millisec is 0, the function returns instantly.
2363 - when \a millisec is set to \b osWaitForever the function will wait for an infinite time until a message queue slot becomes
2365 - all other values specify a time in millisecond for a timeout.
2367 \note The parameter \a millisec must be 0 for using this function in an ISR.
2368 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2370 <b>\ref CMSIS_RTOS_Status</b>\n
2371 - \em osOK: the message is put into the queue.
2372 - \em osErrorResource: no memory in the queue was available.
2373 - \em osErrorTimeoutResource: no memory in the queue was available during the given time limit.
2374 - \em osErrorParameter: a parameter is invalid or outside of a permitted range.
2377 Refer to \ref osMessageQueueNew.
2380 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2381 /** \fn osStatus osMessageQueueGet (osMessageQueueId queue_id, uint32_t *message, uint32_t millisec)
2382 Suspend the execution of the current \b RUNNING thread until a message arrives. When a message is already in the queue,
2383 the function returns instantly with the message information.
2385 The argument \a millisec specifies how long the system waits for a message to become available.
2386 While the system waits the thread that is calling this function is put into the state \b WAITING.
2387 The \a millisec timeout value can have the following values:
2388 - when \a millisec is 0, the function returns instantly.
2389 - when \a millisec is set to \b osWaitForever the function will wait for an infinite time until a message arrives.
2390 - all other values specify a time in millisecond for a timeout.
2392 \note The parameter \a millisec must be 0 for using this function in an ISR.
2393 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2395 <b>\ref CMSIS_RTOS_Status</b>\n
2396 - \em osOK: no message is available in the queue and no timeout was specified.
2397 - \em osEventTimeout: no message has arrived during the given timeout period.
2398 - \em osEventMessage: message received, \em value.p contains the pointer to message.
2399 - \em osErrorParameter: a parameter is invalid or outside of a permitted range.
2402 Refer to \ref osMessageQueueNew.
2405 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2406 /** \fn osStatus osMessageQueueGetInfo (osMessageQueueId queue_id, uint32_t *queue_size, uint32_t *message_count);
2410 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2411 /** \fn osStatus osMessageQueueReset (osMessageQueueId queue_id);
2415 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2416 /** \fn osStatus osMessageQueueDelete (osMessageQueueId queue_id);
2423 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2424 // ==== Mail Queue Management Functions ====
2426 \addtogroup CMSIS_RTOS_Mail Mail Queue
2427 \ingroup CMSIS_RTOS_InterThread
2428 \brief Exchange data between threads using a queue of memory blocks.
2431 A \b mail \b queue resembles a \ref CMSIS_RTOS_Message, but the data that is being transferred consists of memory blocks that
2432 need to be allocated (before putting data in) and freed (after taking data out). The mail queue uses a
2433 \ref CMSIS_RTOS_PoolMgmt to create formatted memory blocks and passes pointers to these blocks in a message queue. This
2434 allows the data to stay in an allocated memory block while only a pointer is moved between the separate threads. This is an
2435 advantage over \ref CMSIS_RTOS_Message "messages" that can transfer only a 32-bit value or a pointer. Using the mail queue
2436 functions, you can control, send, receive, or wait for mail.
2438 \image html "MailQueue.png" "CMSIS-RTOS Mail Queue"
2440 Working with Mail Queues
2441 ---------------------------
2442 Follow these steps to create and use a mail queue:
2443 -# Declare a data structure that combines a number of elements:
2452 -# Declare a mail queue made up of these objects:
2454 //osMailQDef (object_pool_q, 10, properties_t); // Declare mail queue
2455 osMailQId (object_pool_q_id); // Mail queue ID
2457 -# Then, create the mail pool in a thread:
2459 object_pool_q_id = osMailCreate(osMailQ(object_pool_q), NULL);
2461 -# Allocate the mail queue within a thread and fill it with data:
2463 properties_t *object_data;
2464 *object_data = (properties_t *) osMailAlloc(object_pool_q_id, osWaitForever);
2466 object_data->length = 100;
2467 object_data->width = 10;
2468 object_data->height = 23;
2469 object_data->weight = 1000;
2471 -# Pass the pointer to the mail queue to another thread:
2473 osMailPut(object_pool_q_id, object_data);
2475 -# Access the data in another thread:
2477 osEvent event = osMailGet(properties_q_id, osWaitForever);
2478 properties_t *received = (properties_t *)event.value.p; // ".p" indicates that the message is a pointer
2479 my_length(received->length);
2481 -# Once the data has been used, the memory block must be freed so that the memory pool can be reused
2483 osMailFree(object_pool_q_id, received);
2489 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2490 /** \def osFeature_MailQueue
2491 Defines whether Mail Queues are available or not.
2494 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2495 /** \def osMailQueueAttrInit
2496 Mail Queue attributes initialization.
2499 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2500 /** \def osMailQueueMem
2501 User memory allocation for Mail Queue data.
2504 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2505 /** \struct osMailQueueAttr_t
2506 Attributes structure for mail queue.
2509 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2510 /** \fn osMailQueueId osMailQueueNew (uint32_t queue_size, uint32_t mail_size, void *memory, const osMailQueueAttr_t *attr)
2511 Initialize and create a mail queue.
2513 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
2517 #include "cmsis_os.h"
2519 osThreadId tid_thread1; // ID for thread 1
2520 osThreadId tid_thread2; // ID for thread 2
2522 typedef struct { // Mail object structure
2523 float voltage; // AD result of measured voltage
2524 float current; // AD result of measured current
2525 int counter; // A counter value
2528 osMailQDef(mail, 16, T_MEAS); // Define mail queue
2531 void send_thread (void const *argument); // forward reference
2532 void recv_thread (void const *argument);
2534 osThreadDef(send_thread, osPriorityNormal, 1, 0); // thread definitions
2535 osThreadDef(recv_thread, osPriorityNormal, 1, 2000);
2538 // Thread 1: Send thread
2540 void send_thread (void const *argument) {
2543 mptr = osMailAlloc(mail, osWaitForever); // Allocate memory
2544 mptr->voltage = 223.72; // Set the mail content
2545 mptr->current = 17.54;
2546 mptr->counter = 120786;
2547 osMailPut(mail, mptr); // Send Mail
2550 mptr = osMailAlloc(mail, osWaitForever); // Allocate memory
2551 mptr->voltage = 227.23; // Prepare 2nd mail
2552 mptr->current = 12.41;
2553 mptr->counter = 170823;
2554 osMailPut(mail, mptr); // Send Mail
2555 osThreadYield(); // Cooperative multitasking
2556 // We are done here, exit this thread
2560 // Thread 2: Receive thread
2562 void recv_thread (void const *argument) {
2567 evt = osMailGet(mail, osWaitForever); // wait for mail
2568 if (evt.status == osEventMail) {
2570 printf ("\nVoltage: %.2f V\n", rptr->voltage);
2571 printf ("Current: %.2f A\n", rptr->current);
2572 printf ("Number of cycles: %d\n", rptr->counter);
2573 osMailFree(mail, rptr); // free memory allocated for mail
2578 void StartApplication (void) {
2579 mail = osMailCreate(osMailQ(mail), NULL); // create mail queue
2581 tid_thread1 = osThreadCreate(osThread(send_thread), NULL);
2582 tid_thread2 = osThreadCreate(osThread(recv_thread), NULL);
2588 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2589 /** \fn void *osMailQueueAlloc (osMailQueueId queue_id, uint32_t millisec)
2590 Allocate a memory block from the mail queue that is filled with the mail information.
2592 The argument \a queue_id specifies a mail queue identifier that is obtain with \ref osMailQueueNew.
2594 The argument \a millisec specifies how long the system waits for a mail slot to become available.
2595 While the system waits the tread calling this function is put into the state \b WAITING.
2596 The \a millisec timeout can have the following values:
2597 - when \a millisec is 0, the function returns instantly.
2598 - when \a millisec is set to \b osWaitForever the function will wait for an infinite time until a mail slot can be allocated.
2599 - all other values specify a time in millisecond for a timeout.
2601 \note The parameter \a millisec must be 0 for using this function in an ISR.
2602 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2604 A NULL pointer is returned when no memory slot can be obtained or \a queue specifies an illegal parameter.
2607 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2608 /** \fn osStatus osMailQueuePut (osMailQueueId queue_id, const void *mail)
2609 Put the memory block specified with \a mail into the mail queue specified by \a queue.
2611 <b>\ref CMSIS_RTOS_Status</b>\n
2612 - \em osOK: the message is put into the queue.
2613 - \em osErrorValue: \a mail was previously not allocated as memory slot.
2614 - \em osErrorParameter: a parameter is invalid or outside of a permitted range.
2617 Refer to \ref osMailQueueNew.
2620 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2621 /** \fn osStatus osMailQueueGet (osMailQueueId queue_id, void *mail, uint32_t millisec)
2622 Suspend the execution of the current \b RUNNING thread until a mail arrives. When a mail is already in the queue,
2623 the function returns instantly with the mail information.
2625 The argument \a millisec specifies how long the system waits for a mail to arrive.
2626 While the system waits the thread that is calling this function is put into the state \b WAITING.
2627 The \a millisec timeout can have the following values:
2628 - when \a millisec is 0, the function returns instantly.
2629 - when \a millisec is set to \b osWaitForever the function will wait for an infinite time until a mail arrives.
2630 - all other values specify a time in millisecond for a timeout.
2632 \note The parameter \a millisec must be 0 for using this function in an ISR.
2633 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2635 <b>\ref CMSIS_RTOS_Status</b>\n
2636 - \em osOK: no mail is available in the queue and no timeout was specified
2637 - \em osEventTimeout: no mail has arrived during the given timeout period.
2638 - \em osEventMail: mail received, \em value.p contains the pointer to mail content.
2639 - \em osErrorParameter: a parameter is invalid or outside of a permitted range.
2642 Refer to \ref osMailQueueNew.
2645 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2646 /** \fn osStatus osMailQueueFree (osMailQueueId queue_id, void *mail)
2647 Free the memory block specified by \a mail and return it to the mail queue.
2649 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2651 <b>\ref CMSIS_RTOS_Status</b>\n
2652 - \em osOK: the \a mail block is released.
2653 - \em osErrorValue: \a mail block does not belong to the mail queue pool.
2654 - \em osErrorParameter: the value to the parameter \a queue_id is incorrect.
2657 Refer to \ref osMailQueueNew.
2660 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2661 /** \fn osMailQId osMailCreate ( const osMailQDef_t * queue_def, osThreadId thread_id )
2665 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2666 /** \fn osStatus osMailQueueGetInfo (osMailQueueId queue_id, uint32_t *queue_size, uint32_t *mail_size, uint32_t *mail_count)
2670 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2671 /** \fn osStatus osMailQueueReset (osMailQueueId queue_id)
2675 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2676 /** \fn osStatus osMailQueueDelete (osMailQueueId queue_id)
2681 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2682 // ==== Status and Error Codes ====
2684 \addtogroup CMSIS_RTOS_Status Status and Error Codes
2686 \brief Status and Error Codes returned by CMSIS-RTOS API functions.
2687 \details The Status and Error Codes section lists all the return values that the CMSIS-RTOS functions will return.
2691 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2695 The \b osStatus enumeration defines the event status and error codes that are returned by the CMSIS-RTOS functions.