]> begriffs open source - cmsis/blob - CMSIS/DoxyGen/RTOS2/src/cmsis_os.txt
first iteration of feedback
[cmsis] / CMSIS / DoxyGen / RTOS2 / src / cmsis_os.txt
1 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2 /**
3 \mainpage
4
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>.
11
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.
16
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.
19
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
22
23 <hr>
24
25 CMSIS-RTOS in ARM::CMSIS Pack
26 -----------------------------
27
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                                                        |
34 */
35
36
37 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
38 /**
39 \page rtos_revisionHistory Revision History
40
41 <table class="cmtable" summary="Revision History">
42     <tr>
43       <th>Version</th>
44       <th>Description</th>
45     </tr>
46     <tr>
47       <td>V2.00</td>
48       <td>
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
57      </td>
58     </tr>
59     <tr>
60       <td>V1.02 - only documentation changes</td>
61       <td>
62       Added: Overview of the \ref RtosValidation "CMSIS-RTOS Validation" Software Pack.\n
63           Clarified: Behavior of \ref CMSIS_RTOS_TimeOutValue.
64      </td>
65     </tr>
66     <tr>
67       <td>V1.02</td>
68       <td>Added: New control functions for short timeouts in microsecond resolution \ref osKernelSysTick,
69       \ref osKernelSysTickFrequency, \ref osKernelSysTickMicroSec.\n
70       Removed: osSignalGet.
71      </td>
72     </tr>
73     <tr>
74       <td>V1.01</td>
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
80       </td>
81     </tr>
82     <tr>
83       <td>
84       V1.00</td>
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.
90       </td>
91     </tr>
92     <tr>
93       <td>V0.02</td>
94       <td>Preview Release.</td>
95     </tr>
96 </table>
97 */
98
99
100 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
101 /**
102 \page UsingOS Using a CMSIS-RTOS Implementation
103
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.
107
108 \image html "CMSIS_RTOS_Files.png" "CMSIS-RTOS File Structure"
109
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.
114
115 Once the files are added to a project, the user can start working with the CMSIS-RTOS functions. A code example is provided
116 below:
117  
118 <b>Code Example</b>
119 \code
120 #include "cmsis_os.h"                            // CMSIS-RTOS header file
121  
122 void job1 (void const *argument)  {              // thread function 'job1'
123   while (1)  {
124       :                                          // execute some code
125     osDelay (10);                                // delay execution for 10 milliseconds
126   }
127 }
128  
129 osThreadDef(job1, osPriorityAboveNormal, 1, 0);  // define job1 as thread function
130  
131 void job2 (void const *argument)  {              // thread function 'job2'
132   osThreadCreate(osThread(job1),NULL);           // create job1 thread
133   while (1)   {
134     :                                            // execute some code
135   }
136 }
137  
138 osThreadDef(job2, osPriorityNormal, 1, 0);       // define job2 as thread function
139  
140 void job3 (void const *argument)  {              // thread function 'job3'
141   while (1)   {
142       :                                          // execute some code
143     osDelay (20);                                // delay execution for 20 milliseconds
144   }
145 }
146  
147 osThreadDef(job3, osPriorityNormal, 1, 0);       // define job3 as thread function
148  
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
155 }
156 \endcode
157 */
158
159
160 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
161 /**
162 \page FunctionOverview Function Overview
163
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
166     communication.
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.
170
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.
173
174 \section CMSIS_RTOS_TimeOutValue Timeout Value   
175
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. 
178
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. 
181
182 \image html TimerValues.png "Timer Values"
183
184 \section CMSIS_RTOS_ISR_Calls Calls from Interrupt Service Routines 
185
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
193
194
195 In addition, the following legacy CMSIS-RTOS1 functions can be called from threads and Interrupt Service Routines (ISR):
196 \todo verify
197   - \ref osKernelRunning
198   - \ref osMailQueueAlloc, \ref osMailQueueGet, \ref osMailQueuePut, \ref osMailQueueFree
199
200   
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
203 FAULT vector.
204
205 */
206
207
208
209 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
210 /**
211 \page RTOS_API2 CMSIS-RTOS C API Version 2  
212
213 Overview of all CMSIS-RTOS C API v2 functions.
214
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.
225
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.
236
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.
241
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.
248
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
254
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.
262
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.
268
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?
275
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
282
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.
290
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.
300 */
301
302
303
304 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
305 /**
306 \page RTOS_APICPP CMSIS-RTOS C++ API
307
308 Coming soon
309 */
310
311
312
313 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
314 /**
315 \page cmsis_os_h Header File Template: cmsis_os.h
316
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
319 its implementation.
320
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
326
327
328 <b>Name conventions and header file modifications</b>
329
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.
333
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.
336
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
339 implementation.
340
341 <b>Define and reference object definitions</b>
342
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:
345
346 <i>Header File</i>
347 \code
348 #include <cmsis_os.h>                                         // CMSIS RTOS header file
349
350 // Thread definition
351 extern void thread_sample (void const *argument);             // function prototype
352 osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100);
353
354 // Pool definition
355 osPoolDef(MyPool, 10, long);
356 \endcode
357
358
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.
362
363 <i>Example</i>
364 \code
365 #include "osObjects.h"     // Definition of the CMSIS-RTOS objects
366 \endcode
367
368 \code
369 #define osObjectsExternal  // Objects will be defined as external symbols
370 #include "osObjects.h"     // Reference to the CMSIS-RTOS objects
371 \endcode
372
373 <b>Header file %cmsis_os.h</b>
374
375 \include Template/cmsis_os.h
376 */
377
378 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
379 /**
380 \page RtosValidation RTOS Validation
381
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:
384
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.
388
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 
391 functions from ISR.
392
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)
398  
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 
406  
407 The RTOS Validation output can be printed to a console, output via ITM printf, or output to a memory buffer.
408  
409 \section test_output Sample Test Output
410 \verbatim
411 CMSIS-RTOS Test Suite   Oct 21 2015   16:39:16 
412
413 TEST 01: TC_ThreadCreate                  PASSED
414 TEST 02: TC_ThreadMultiInstance           PASSED
415 TEST 03: TC_ThreadTerminate               PASSED
416   :
417   :
418 TEST 08: TC_ThreadChainedCreate           PASSED
419 TEST 09: TC_ThreadYield                   NOT EXECUTED
420 TEST 10: TC_ThreadParam                   PASSED
421   :
422   :
423 TEST 60: TC_MailFromISRToThread           PASSED
424
425 Test Summary: 60 Tests, 59 Executed, 59 Passed, 0 Failed, 0 Warnings.
426 Test Result: PASSED
427 \endverbatim
428 */
429
430
431 /* ========================================================================================================================== */
432 // Reference 
433 /** 
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.
437  *  @{
438  */
439
440 /// @} 
441
442
443 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
444 //  ==== Kernel Control Functions ====
445 /** 
446 \addtogroup CMSIS_RTOS_KernelCtrl Kernel Information and Control
447 \ingroup CMSIS_RTOS
448 \brief Provide version/system information and start the RTOS Kernel.
449 \details 
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.
456
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.
459
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().
464
465 <b>Code Example</b>
466 \code
467 int main (void) {
468   osKernelInitialize ();                    // initialize CMSIS-RTOS
469  
470   // initialize peripherals here
471  
472   // create 'thread' functions that start executing,
473   // example: tid_name = osThreadCreate (osThread(name), NULL);
474  
475   osKernelStart ();                         // start thread execution 
476 }
477 \endcode
478 @{
479 */
480
481 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
482 /* \def osCMSIS
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.
485 */
486
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.
493 */
494
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>.
499 */
500
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.
504 */
505
506 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
507 /**
508 \typedef osKernelState_t
509 Kernel state definitions.
510 */
511
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.
522
523 The RTOS kernel does not start thread switching until the function \ref osKernelStart is called.
524
525 \note 
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.
528
529 <b>Code Example</b>
530 \code
531 #include "cmsis_os.h"
532  
533 int main (void)  {
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
537     }
538   }
539   :
540 }
541 \endcode
542 */
543
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.
547
548 \note
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.
551
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.
555
556 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
557
558 <b>Code Example</b>
559 \code
560 #include "cmsis_os.h"
561  
562 int main (void)  {
563   if (osKernelInitialize () != osOK)  {          // check osStatus for other possible valid values
564     // exit with an error message
565   }
566  
567   if (!osKernelRunning ())  {                    // is the kernel running ?
568     if (osKernelStart () != osOK)  {             // start the kernel
569                                                  // kernel could not be started
570     }
571   }
572 }
573 \endcode
574 */
575
576 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
577 /** \fn uint32_t osKernelSuspend (uint32_t tickless)
578  
579 */
580
581 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
582 /** \fn osStatus osKernelResume (uint32_t sleep_time)
583  
584 */
585
586 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
587 /** \fn osKernelState osKernelGetState (void)
588
589 */
590
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.
594
595 \todo add code example for osKernelTime
596
597 <b>Code Example</b>
598 \code
599 \endcode
600 */
601
602 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
603 /** \fn uint32_t osKernelSysTick (void)
604
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. 
608
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.
611
612 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
613
614 <b>Code Example</b>
615 \code
616 #include "cmsis_os.h"
617  
618 void SetupDevice (void)  {
619   uint32_t tick;
620   
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));  
626   if (Device.Busy)  {              
627     ;                                            // in case device still busy, signal error
628   }
629                                                  // start interacting with device
630 }
631 \endcode
632 */
633
634 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
635 /**
636 \def osKernelSysTickFrequency
637
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.
640
641 \sa osKernelSysTick
642
643 */
644
645 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
646 /**
647 \def osKernelSysTickMicroSec
648
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.
651
652 \sa osKernelSysTick
653 */
654 /// @}
655
656
657
658 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
659 //  ==== Thread Management Functions ====
660 /** 
661 \addtogroup CMSIS_RTOS_ThreadMgmt Thread Management
662 \ingroup CMSIS_RTOS CMSIS_RTOSv2
663 \brief Define, create, and control thread functions.
664 \details 
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
667 \a osPriorityNormal.
668
669 \anchor ThreadStates
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
672    state.
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
677    system resources.
678
679 \image html "ThreadStatus.png" "Thread State and State Transitions"
680
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. 
692
693 @{
694 */
695 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
696 /** \def osThreadJoinable
697
698 Reference: 
699  - \ref osThreadAttr_t
700  - \ref osThreadJoin
701 */
702
703 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
704 /** \def osThreadDetached
705
706 Reference: 
707  - \ref osThreadAttr_t
708  - \ref osThreadDetach
709 */
710
711 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
712 /** \def osThreadAttrInit
713 Thread attributes initialization.
714 */
715
716 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
717 /**
718 \typedef osThreadState_t
719 Thread state definitions.
720 */
721
722 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
723 /**
724 \struct osThreadAttr_t
725 Attributes structure for thread.
726 */
727
728 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
729 /**
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".
733
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.
737
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. 
741 */
742
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.
750
751 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
752
753 <b>Code Example</b>
754 \code
755 #include "cmsis_os.h"
756  
757 void Thread_1 (void const *arg);                           // function prototype for Thread_1
758 osThreadDef (Thread_1, osPriorityNormal, 1, 0);            // define Thread_1
759  
760 void ThreadCreate_example (void) {
761   osThreadId id;
762   
763   id = osThreadCreate (osThread (Thread_1), NULL);         // create the thread
764   if (id == NULL) {                                        // handle thread creation
765     // Failed to create a thread
766   }
767   //do something
768   osThreadTerminate (id);                                  // stop the thread
769 }
770 \endcode
771 */
772
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.
776
777 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
778
779 <b>Code Example</b>
780 \code
781 void ThreadGetId_example (void)  {
782   osThreadId id;                                           // id for the currently running thread
783    
784   id = osThreadGetId ();
785   if (id == NULL) {
786     // Failed to get the id; not in a thread
787   }
788 }
789 \endcode
790 */
791
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.
795
796 <b>Code Example</b>
797 \code
798 #include "cmsis_os.h"
799  
800 void Thread_1 (void const *arg)  {                         // Thread function
801   osThreadId id;                                           // id for the currently running thread
802   osThreadState status;                                    // thread state
803    
804   id = osThreadGetId ();                                   // Obtain ID of current running thread
805    
806   if (id != NULL) {
807     status = osThreadGetState (id);
808     if (status == osThreadRunning)  {
809       // Thread is currently running
810     }
811     else {
812       // Check other options
813     }
814   }
815   else  {
816     // Failed to get the id
817   }
818 \endcode
819 */
820
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.
824
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.
831
832 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
833  
834 <b>Code Example</b>
835 \code
836 #include "cmsis_os.h"
837  
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
842    
843   :  
844   id = osThreadGetId ();                                   // Obtain ID of current running thread
845    
846   if (id != NULL) {
847     status = osThreadSetPriority (id, osPriorityBelowNormal);
848     if (status == osOK)  {
849       // Thread priority changed to BelowNormal
850     }
851     else {
852       // Failed to set the priority
853     }
854   }
855   else  {
856     // Failed to get the id
857   }
858   :  
859 }
860 \endcode
861 */
862
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.
866
867 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
868
869 <b>Code Example</b>
870 \code
871 #include "cmsis_os.h"
872  
873 void Thread_1 (void const *arg)  {                         // Thread function
874   osThreadId id;                                           // id for the currently running thread
875   osPriority priority;                                     // thread priority
876    
877   id = osThreadGetId ();                                   // Obtain ID of current running thread
878    
879   if (id != NULL)  {
880     priority = osThreadGetPriority (id);
881   }
882   else  {
883     // Failed to get the id
884   }
885 }
886 \endcode
887 */
888
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.
893
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.
897
898 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
899
900 <b>Code Example</b>
901 \code
902 #include "cmsis_os.h"
903  
904 void Thread_1 (void const *arg)  {                         // Thread function
905   osStatus   status;                                       // status of the executed function
906  
907   while (1)  {
908     status = osThreadYield();                              // 
909     if (status != osOK)  {
910       // thread switch not occurred, not in a thread function
911     }
912   }
913 }
914 \endcode
915 */
916
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.
920
921 <b>Code Example</b>
922 \code
923 #include "cmsis_os.h"
924  
925 void Thread_1 (void const *arg)  {                         // Thread function
926   osThreadId id;                                           // id for the currently running thread
927   osStatus status;                                         // thread status
928    
929   id = osThreadGetId ();                                   // Obtain ID of current running thread
930    
931   if (id != NULL) {
932     status = osThreadSuspend(id);
933     if (status == osOK)  {
934       // Thread is suspended
935     }
936     else {
937       // Failed to suspend the thread
938     }
939   }
940   else  {
941     // Failed to get the id
942   }
943 \endcode
944 */
945
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.
949
950 <b>Code Example</b>
951 \code
952 #include "cmsis_os.h"
953  
954 void Thread_1 (void const *arg)  {                         // Thread function
955   osThreadId id;                                           // id for the currently running thread
956   osStatus status;                                         // thread status
957    
958   id = osThreadGetId ();                                   // Obtain ID of current running thread
959    
960   if (id != NULL) {
961     status = osThreadResume(id);
962     if (status == osOK)  {
963       // Thread is resumed
964     }
965     else {
966       // Failed to resume the thread
967     }
968   }
969   else  {
970     // Failed to get the id
971   }
972 \endcode
973 */
974
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.
978
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.
981
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.
987
988 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
989
990 <b>Code Example</b>
991 \code
992 #include "cmsis_os.h"
993  
994 void Thread_1 (void const *arg);                           // function prototype for Thread_1
995 osThreadDef (Thread_1, osPriorityNormal, 1, 0);            // define Thread_1
996  
997 void ThreadTerminate_example (void) {
998   osStatus status;
999   osThreadId id;
1000  
1001   id = osThreadCreate (osThread (Thread_1), NULL);         // create the thread
1002   // do something  
1003   status = osThreadTerminate (id);                         // stop the thread
1004   if (status == osOK) {
1005     // Thread was terminated successfully
1006   }
1007   else {
1008     // Failed to terminate a thread
1009   }
1010 }
1011 \endcode
1012 */
1013
1014 /// @}
1015
1016
1017 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1018 //  ==== Thread Flags Management Functions ====
1019 /** 
1020 \addtogroup CMSIS_RTOS_ThreadFlagsMgmt Thread Flags Management Functions
1021 \ingroup CMSIS_RTOS
1022 \brief Lorem ipsum
1023 \details
1024 Lorem ipsum
1025
1026 @{
1027 */
1028
1029 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1030 /** \def osFlagsWaitAny
1031 Wait forever timeout value. 
1032
1033 Reference: 
1034  - \ref osEventFlagsWait
1035  - \ref osThreadFlagsWait
1036 */
1037
1038 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1039 /** \def osFlagsWaitAll
1040
1041 Reference: 
1042  - \ref osEventFlagsWait
1043  - \ref osThreadFlagsWait
1044 */
1045
1046 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1047 /** \def osFlagsAutoClear
1048
1049 Reference: 
1050  - \ref osEventFlagsWait
1051  - \ref osThreadFlagsWait
1052 */
1053
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.
1057 */
1058
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 )       
1061 <b>Code Example</b>
1062 \code
1063 \endcode
1064 */
1065
1066 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1067 /** \fn osStatus osThreadFlagsClear (osThreadId thread_id, int32_t flags);
1068  
1069 <b>Code Example</b>
1070 \code
1071 \endcode
1072 */
1073
1074 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1075 /** \fn int32_t osThreadFlagsGet (osThreadId thread_id);
1076  
1077 <b>Code Example</b>
1078 \code
1079 \endcode
1080 */
1081
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);
1084
1085 <b>Code Example</b>
1086 \code
1087 \endcode
1088 */
1089
1090 /// @}
1091
1092
1093 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1094 //  ==== Generic Wait Functions ====
1095 /** 
1096 \addtogroup CMSIS_RTOS_Wait Generic Wait Functions
1097 \ingroup CMSIS_RTOS
1098 \brief Wait for a time period or unspecified events.
1099 \details 
1100 The Generic Wait function group provides means for a time delay and allow to wait for unspecified events.
1101
1102 @{
1103 */
1104
1105 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1106 /** \def osWaitForever
1107 Wait forever timeout value. 
1108
1109 Reference: 
1110  - \ref osDelay
1111  - \ref osDelayUntil
1112 */
1113
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.
1117
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. 
1120
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.
1123
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.
1127
1128 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1129  
1130 <b>Code Example</b>
1131 \code
1132 #include "cmsis_os.h"
1133  
1134 void Thread_1 (void const *arg)  {               // Thread function
1135   osStatus status;                               // capture the return status
1136   uint32_t delayTime;                            // delay time in milliseconds
1137  
1138   delayTime = 1000;                              // delay 1 second
1139   status = osDelay (delayTime);                  // suspend thread execution
1140   if (status != osOK) {
1141     // handle error code
1142   }  
1143 }
1144 \endcode
1145 */
1146
1147 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1148 /** \fn osStatus osDelayUntil (uint64_t millisec)
1149
1150 */
1151
1152 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1153 /** \fn uint32_t osEventWait (uint32_t millisec)
1154
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.
1158
1159 \todo Update osEventWait description.
1160
1161 <b>Code Example</b>
1162 \code
1163 \endcode
1164 */
1165 /// @}
1166
1167
1168 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1169 //  ==== Timer Management Functions ====
1170 /** 
1171 \addtogroup CMSIS_RTOS_TimerMgmt Timer Management
1172 \ingroup CMSIS_RTOS
1173 \brief Create and control timer and timer callback functions.
1174 \details 
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".
1180
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.
1183
1184 The figure below shows the behavior of a periodic timer. For one-shot timers, the timer stops after execution of the
1185 callback function.
1186
1187 \image html "Timer.png" "Behavior of a Periodic Timer"
1188
1189 Working with Timers
1190 --------------------
1191 The following steps are required to use a timer:
1192 -# Define the timers:
1193 \code
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;
1197 \endcode
1198 -# Instantiate and start the timers in an RTOS thread:
1199 \code
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);
1208 \endcode
1209
1210 @{
1211 */
1212
1213
1214 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1215 /** \def osTimerAttrInit
1216 Timer attributes initialization.
1217 */
1218
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.
1222 */
1223
1224 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1225 /** \struct osTimerAttr_t
1226 Attributes structure for timer.
1227 */
1228
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.
1233
1234 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1235
1236 <b>Code Example</b>
1237 \code
1238 #include "cmsis_os.h"
1239  
1240 void Timer1_Callback  (void const *arg);                   // prototypes for timer callback function
1241 void Timer2_Callback  (void const *arg);                   
1242  
1243 osTimerDef (Timer1, Timer1_Callback);                      // define timers
1244 osTimerDef (Timer2, Timer2_Callback);
1245  
1246 uint32_t  exec1;                                           // argument for the timer call back function
1247 uint32_t  exec2;                                           // argument for the timer call back function
1248  
1249 void TimerCreate_example (void)  {
1250   osTimerId id1;                                           // timer id
1251   osTimerId id2;                                           // timer id
1252  
1253   // Create one-shoot timer
1254   exec1 = 1;
1255   id1 = osTimerCreate (osTimer(Timer1), osTimerOnce, &exec1);
1256   if (id1 != NULL)  {
1257     // One-shoot timer created
1258   }
1259  
1260   // Create periodic timer
1261   exec2 = 2;
1262   id2 = osTimerCreate (osTimer(Timer2), osTimerPeriodic, &exec2);
1263   if (id2 != NULL)  {
1264     // Periodic timer created
1265   }
1266 }
1267 \endcode
1268 */
1269
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.
1273
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.
1278
1279 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1280  
1281 <b>Code Example</b>
1282 \code
1283 #include "cmsis_os.h"
1284  
1285 void Time_Callback  (void const *arg)  {                   // timer callback function
1286                                                            // arg contains &exec
1287                                                            // called every second after osTimerStart
1288
1289  
1290 osTimerDef (Timer, Time_Callback);                         // define timer
1291 uint32_t  exec;                                            // argument for the timer call back function
1292  
1293 void TimerStart_example (void)  {
1294   osTimerId id;                                            // timer id
1295   uint32_t  timerDelay;                                    // timer value
1296   osStatus  status;                                        // function return status
1297  
1298   // Create periodic timer
1299   exec = 1;
1300   id = osTimerNew (osTimer(Timer), osTimerPeriodic, &exec);
1301   if (id)  {
1302     timerDelay = 1000;
1303     status = osTimerStart (id, timerDelay);                // start timer
1304     if (status != osOK)  {
1305       // Timer could not be started
1306     } 
1307   }
1308 }
1309 \endcode
1310 */
1311
1312 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1313 /** \fn osStatus osTimerStop  (osTimerId timer_id)
1314 Stop the timer.
1315
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.
1321
1322 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1323
1324 <b>Code Example</b>
1325 \code
1326 #include "cmsis_os.h"
1327  
1328 void Timer_Callback  (void const *arg);                    // prototype for timer callback function
1329 osTimerDef (Timer, Timer_Callback);                        // define timer
1330  
1331 void TimerStop_example (void)  {
1332   osTimerId id;                                            // timer id
1333   osStatus status;                                         // function return status
1334  
1335   // Create periodic timer
1336   exec = 1;
1337   id = osTimerCreate (osTimer(Timer2), osTimerPeriodic, NULL);
1338   osTimerStart (id, 1000);                                 // start timer
1339   // do something
1340   status = osTimerStop (id);                               // stop timer
1341   if (status != osOK)  {
1342     // Timer could not be stopped
1343   } 
1344   osTimerStart (id, 1000);                                 // start timer again
1345 }
1346 \endcode
1347 */
1348
1349 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1350 /** \fn int32_t osTimerIsRunning (osTimerId timer_id)
1351
1352 */
1353
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.
1357
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.
1362
1363 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1364
1365 <b>Code Example</b>
1366 \code
1367 #include "cmsis_os.h"
1368
1369 void Timer_Callback  (void const *arg);                    // prototype for timer callback function
1370 osTimerDef (Timer, Timer_Callback);                        // define timer
1371  
1372 void TimerDelete_example (void)  {
1373   osTimerId id;                                            // timer id
1374   osStatus status;                                         // function return status  
1375  
1376   // Create periodic timer
1377   exec = 1;
1378   id = osTimerCreate (osTimer(Timer2), osTimerPeriodic, NULL);
1379   osTimerStart (id, 1000UL);                               // start timer
1380   // do something
1381   status = osTimerDelete (id);                             // stop and delete timer
1382   if (status != osOK)  {
1383     // Timer could not be deleted
1384   } 
1385 }
1386 \endcode
1387 */
1388 /// @}
1389
1390
1391
1392 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1393 //  ==== Inter-Thread Communication Functions ====
1394 /** 
1395 \addtogroup CMSIS_RTOS_InterThread Inter-Thread Communication and Resource Sharing
1396 \ingroup CMSIS_RTOS
1397 \brief Functions for inter-thread communication.
1398 \details
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.
1401
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).
1405
1406
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
1416
1417 Resource Sharing
1418 ----------------
1419 - \ref CMSIS_RTOS_MutexMgmt
1420 - \ref CMSIS_RTOS_SemaphoreMgmt
1421 */
1422 /// @}
1423
1424
1425 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1426 //  ==== Event Flag Management Functions ====
1427 /** 
1428 \addtogroup CMSIS_RTOS_EventFlags Event Flag Objects
1429 \ingroup CMSIS_RTOS_InterThread
1430 \brief Synchronize threads using flags.
1431 \details 
1432 \todo add details here.
1433 @{
1434 */
1435
1436 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1437 /** \def osEventFlagsAttrInit
1438 Event Flags attributes initialization.
1439 */
1440
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.
1444 */
1445
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.
1449 */
1450
1451 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1452 /** \struct osEventFlagsAttr_t
1453 Attributes structure for event flags.
1454 */
1455
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.
1459
1460 <b>Code Example</b>
1461 \code
1462 #include "cmsis_os.h"
1463   
1464 osFlagDef (my_flag);                             // Flag name definition
1465   
1466 void CreateFlag (void)  {
1467 osFlagId  my_flag_id;
1468  
1469   my_flag_id = osFlagCreate (osFlag(my_flag));
1470   if (my_flag_id != NULL)  {
1471     // Flag object created
1472   }   
1473 }
1474 \endcode
1475 */
1476
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.
1480
1481 <b>Code Example</b>
1482 \code
1483 #include "cmsis_os.h"
1484   
1485 osFlagDef my_flag;                               // Flag name definition 
1486 osFlagId  my_flag_id;                            // Flag ID populated by the function osFlagCreate()
1487  
1488 void SetFlagValues (osFlagId my_flag_id)  {
1489 int32_t flags;
1490   
1491   if (my_flag_id != NULL)  {
1492     flags = osFlagSet(my_flag_id, 0x17);
1493   }
1494 }
1495 \endcode
1496 */
1497
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.
1501
1502 <b>Code Example</b>
1503 \code
1504 #include "cmsis_os.h"
1505   
1506 osFlagDef my_flag;                               // Flag name definition 
1507 osFlagId  my_flag_id;                            // Flag ID populated by the function osFlagCreate()
1508  
1509 void ClearFlagValues (osFlagId my_flag_id)  {
1510 int32_t flags;
1511   
1512   if (my_flag_id != NULL)  {
1513     flags = osFlagClear(my_flag_id, 0x10);
1514   }
1515 }
1516 \endcode
1517 */
1518
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.
1523
1524 <b>Code Example</b>
1525 \code
1526 #include "cmsis_os.h"
1527   
1528 osFlagDef my_flag;                               // Flag name definition 
1529 osFlagId  my_flag_id;                            // Flag ID populated by the function osFlagCreate()
1530  
1531 void GetFlagValues (osFlagId my_flag_id)  {
1532 int32_t flags;
1533   
1534   if (my_flag_id != NULL)  {
1535     flags = osFlagGet(my_flag_id);
1536     // work with the flags
1537     }
1538   }
1539 }
1540 \endcode
1541 */
1542
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.
1547
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.
1552
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.
1558  
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.
1561
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.
1567
1568 <b>Code Example</b>
1569 \code
1570 #include "cmsis_os.h"
1571   
1572 osFlagDef my_flag;                               // Flag name definition 
1573 osFlagId  my_flag_id;                            // Flag ID populated by the function osFlagCreate()
1574  
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
1581     } else {
1582       // do something
1583     }
1584   } else {
1585     // flag object not created
1586   }
1587 }
1588 \endcode
1589 */
1590
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.
1595
1596 <b>Code Example</b>
1597 \code
1598 #include "cmsis_os.h"
1599   
1600 osFlagDef my_flag;                               // Flag name definition 
1601 osFlagId  my_flag_id;                            // Flag ID populated by the function osFlagCreate()
1602  
1603 void DeleteFlag (osFlagId my_flag_id)  {
1604 osStatus status;
1605   
1606   if (my_flag_id != NULL)  {
1607     status = osFlagDelete(my_flag_id);
1608     if (status != osOK)  {
1609       // handle failure code
1610     }
1611   }
1612 }
1613 \endcode
1614 */
1615 /// @}
1616
1617
1618
1619 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1620 //  ==== Mutex Management Functions ====
1621 /** 
1622 \addtogroup CMSIS_RTOS_MutexMgmt Mutexes
1623 \ingroup CMSIS_RTOS_InterThread
1624 \brief Synchronize resource access using Mutual Exclusion (Mutex).
1625 \details 
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).
1630
1631 \image html "Mutex.png" "CMSIS-RTOS Mutex"
1632
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.
1638
1639 \note
1640 - Mutex management functions cannot be called from interrupt service routines (ISR), unlike a binary semaphore that can be
1641   released from an ISR.
1642
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:
1647 \code
1648 //osMutexDef (uart_mutex);    // Declare mutex
1649 osMutexId  (uart_mutex_id); // Mutex ID
1650 \endcode
1651 -# Create the mutex in a thread:
1652 \code
1653 uart_mutex_id = osMutexCreate(osMutex(uart_mutex));
1654 \endcode
1655 -# Acquire the mutex when peripheral access is required:
1656 \code
1657 osMutexWait(uart_mutex_id, osWaitForever);
1658 \endcode
1659 -# When finished with the peripheral access, release the mutex:
1660 \code
1661 osMutexRelease(uart_mutex_id);
1662 \endcode
1663
1664 @{
1665 */
1666
1667
1668 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1669 /** \def osMutexAttrInit
1670 Mutex attributes initialization.
1671 */
1672
1673 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1674 /** \struct osMutexAttr_t
1675 Attributes structure for mutex.
1676 */
1677
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.
1681
1682 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1683
1684 <b>Code Example</b>
1685 \code
1686 #include "cmsis_os.h"
1687   
1688 osMutexDef (MutexIsr);                                     // Mutex name definition
1689   
1690 void CreateMutex (void)  {
1691 osMutexId mutex_id;   
1692  
1693   mutex_id = osMutexCreate  (osMutex (MutexIsr));
1694   if (mutex_id != NULL)  {
1695     // Mutex object created
1696   }   
1697 }
1698 \endcode
1699 */
1700
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
1704 the mutex object. 
1705
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.
1712
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.
1719
1720 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1721  
1722 <b>Code Example</b>
1723 \code
1724 #include "cmsis_os.h"
1725   
1726 osMutexDef (MutexIsr);
1727   
1728 void WaitMutex (void)  {
1729 osMutexId mutex_id;   
1730 osStatus status;
1731  
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
1737     }
1738   }
1739 }
1740 \endcode
1741 */
1742
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.
1747
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.
1753
1754 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1755  
1756 <b>Code Example</b>
1757 \code
1758 #include "cmsis_os.h"
1759   
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
1763  
1764 void ReleaseMutex (osMutexId mutex_id)  {
1765 osStatus status;
1766   
1767   if (mutex_id != NULL)  {
1768     status = osMutexRelease(mutex_id);
1769     if (status != osOK)  {
1770       // handle failure code
1771     }
1772   }
1773 }
1774 \endcode
1775 */
1776  
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.
1781
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.
1787
1788 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1789  
1790 <b>Code Example</b>
1791 \code
1792 #include "cmsis_os.h"
1793   
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
1797  
1798 void DeleteMutex (osMutexId mutex_id)  {
1799 osStatus status;
1800   
1801   if (mutex_id != NULL)  {
1802     status = osMutexDelete(mutex_id);
1803     if (status != osOK)  {
1804       // handle failure code
1805     }
1806   }
1807 }
1808 \endcode
1809 */
1810 /// @}
1811
1812
1813 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1814 //  ==== Semaphore Management Functions ====
1815 /** 
1816 \addtogroup CMSIS_RTOS_SemaphoreMgmt Semaphores
1817 \ingroup CMSIS_RTOS_InterThread
1818 \brief Access shared resources simultaneously from different threads.
1819 \details 
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).
1824
1825 \image html "Semaphore.png" "CMSIS-RTOS Semaphore"
1826
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.
1832
1833 \note Semaphore tokens can be acquired from threads and released from threads and ISRs.
1834
1835 Working with Semaphores
1836 --------------------
1837 Follow these steps to create and use a semaphore:
1838 -# Declare the semaphore container and initialize the semaphore:
1839 \code
1840 osSemaphoreDef (my_semaphore);    // Declare semaphore
1841 osSemaphoreId  (my_semaphore_id); // Semaphore ID
1842 \endcode
1843 -# Initialize the semaphore container with a number of tokens within a thread:
1844 \code
1845 my_semaphore_id = osSemaphoreCreate(osSemaphore(my_semaphore), 4);  // Create semaphore with 4 tokens
1846 \endcode
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:
1851 \code
1852 osSemaphoreWait(my_semaphore_id, osWaitForever);
1853 \endcode
1854 -# When finished using the semaphore resource, send the token back to the semaphore container:
1855 \code
1856 osSemaphoreRelease(my_semaphore_id);
1857 \endcode
1858
1859 Semaphore Use Cases
1860 -------------------
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.
1865
1866 <b>Non-binary Semaphore (Multiplex)</b>
1867
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.
1870
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:
1876
1877 \code
1878 osSemaphoreDef(multiplex);
1879 osSemaphoreId (multiplex_id);
1880  
1881 void thread_n (void)
1882   {
1883     multiplex_id = osSemaphoreCreate(osSemaphore(multiplex), 3);
1884     while(1)
1885       {
1886         osSemaphoreWait(multiplex_id, osWaitForever);
1887         // do something
1888         osSemaphoreRelease(multiplex_id);
1889       }
1890   }
1891 \endcode
1892
1893 @{
1894 */
1895
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.
1899 */
1900
1901 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1902 /** \def osSemaphoreAttrInit
1903 Semaphore attributes initialization.
1904 */
1905
1906 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
1907 /** \struct osSemaphoreAttr_t
1908 Attributes structure for semaphore.
1909 */
1910
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.
1915
1916 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1917
1918 <b>Code Example</b>
1919 \code
1920 #include "cmsis_os.h"
1921    
1922 osThreadId tid_thread1;                          // ID for thread 1
1923 osThreadId tid_thread2;                          // ID for thread 2
1924   
1925 osSemaphoreId semaphore;                         // Semaphore ID
1926 osSemaphoreDef(semaphore);                       // Semaphore definition
1927    
1928 //
1929 //   Thread 1 - High Priority - Active every 3ms
1930 //
1931 void thread1 (void const *argument) {
1932   int32_t value;
1933
1934   while (1) {
1935     osDelay(3);                                  // Pass control to other tasks for 3ms
1936     val = osSemaphoreWait (semaphore, 1);        // Wait 1ms for the free semaphore
1937     if (val > 0) {
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
1941     }
1942   }
1943 }
1944   
1945 //
1946 //   Thread 2 - Normal Priority - looks for a free semaphore and uses
1947 //                                the resource whenever it is available
1948 //
1949 void thread2 (void const *argument) {
1950   while (1) {
1951     osSemaphoreWait (semaphore, osWaitForever);  // Wait indefinitely for a free semaphore
1952                                                  // OK, the interface is free now, use it.
1953     :
1954     osSemaphoreRelease (semaphore);              // Return a token back to a semaphore.
1955   }
1956 }
1957   
1958 // Thread definitions 
1959 osThreadDef(thread1, osPriorityHigh,   1, 0);
1960 osThreadDef(thread2, osPriorityNormal, 1, 0);
1961    
1962 void StartApplication (void) {
1963   semaphore = osSemaphoreCreate(osSemaphore(semaphore), 1);
1964  
1965   tid_thread1 = osThreadCreate(osThread(thread1), NULL);
1966   tid_thread2 = osThreadCreate(osThread(thread2), NULL);
1967   :
1968 }
1969 \endcode
1970 */
1971
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.
1976
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
1982    available.
1983  - all other values specify a time in millisecond for a timeout.
1984
1985 The return value indicates the number of available tokens (the semaphore count value). If 0 is returned, then no semaphore
1986 was available.
1987
1988 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
1989 */
1990
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.
1994
1995 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
1996
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.
2001 */
2002
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.
2008
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.
2014
2015 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
2016 */
2017 /// @}
2018
2019
2020 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2021 //  ==== Memory Pool Management Functions ====
2022 /** 
2023 \addtogroup CMSIS_RTOS_PoolMgmt Memory Pool
2024 \ingroup CMSIS_RTOS_InterThread
2025 \brief Manage thread-safe fixed-size blocks of dynamic memory.
2026 \details
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.
2029
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.
2033
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:
2038 \code
2039 typedef struct {
2040   uint32_t length;
2041   uint32_t width;
2042   uint32_t height;
2043   uint32_t weight;
2044 } properties_t;
2045 \endcode
2046 -# Declare a memory pool of these objects as a block of memory:
2047 \code
2048 osPoolDef (object_pool, 10, properties_t);  // Declare memory pool
2049 osPoolId  (object_pool_id);                 // Memory pool ID
2050 \endcode
2051 -# Then, create the memory pool in a thread:
2052 \code
2053 object_pool_id = osPoolCreate(osPool(object_pool));
2054 \endcode
2055 -# Allocate the pool within a thread and fill it with data:
2056 \code
2057 properties_t *object_data;
2058 *object_data = (properties_t *) osPoolAlloc(object_pool_id);
2059  
2060 object_data->length = 100;
2061 object_data->width  = 10;
2062 object_data->height = 23;
2063 object_data->weight = 1000;
2064 \endcode
2065
2066 @{
2067 */
2068
2069 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2070 /** \def osMemoryPoolAttrInit
2071 Memory Pool attributes initialization.
2072 */
2073
2074 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2075 /** \def osMemoryPoolMem
2076 User memory allocation for Memory Pool data.
2077 */
2078
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.
2082 */
2083
2084 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2085 /** \struct osMemoryPoolAttr_t
2086 Attributes structure for memory pool.
2087 */
2088
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.
2092
2093 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
2094
2095 <b>Code Example</b>
2096 \code
2097 #include "cmsis_os.h"
2098  
2099 typedef struct {
2100   uint8_t Buf[32];
2101   uint8_t Idx;
2102 } MEM_BLOCK;
2103  
2104 osPoolDef (MemPool, 8, MEM_BLOCK);
2105   
2106 void CreateMemoryPool (void)  {
2107 osPoolId MemPool_Id;
2108  
2109   MemPool_Id = osPoolCreate (osPool (MemPool));
2110   if (MemPool_Id != NULL)  {
2111     // memory pool created
2112   }
2113 }
2114 \endcode
2115 */
2116
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.
2120
2121 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2122
2123 <b>Code Example</b>
2124 \code
2125 #include "cmsis_os.h"
2126  
2127 typedef struct {
2128   uint8_t Buf[32];
2129   uint8_t Idx;
2130 } MEM_BLOCK;
2131  
2132 osPoolDef (MemPool, 8, MEM_BLOCK);
2133  
2134 void AlocMemoryPoolBlock (void)  {
2135   osPoolId   MemPool_Id;
2136   MEM_BLOCK *addr;
2137  
2138   MemPool_Id = osPoolCreate (osPool (MemPool));
2139   if (MemPool_Id != NULL)  {
2140     :
2141     // allocate a memory block
2142     addr = (MEM_BLOCK *)osPoolAlloc (MemPool_Id);
2143     
2144     if (addr != NULL) {
2145       // memory block was allocated
2146       :
2147     }
2148   }
2149 }
2150 \endcode
2151 */
2152
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.
2156
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.
2161
2162 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2163
2164 <b>Code Example</b>
2165 \code
2166 #include "cmsis_os.h"
2167  
2168 typedef struct {
2169   uint8_t Buf[32];
2170   uint8_t Idx;
2171 } MEM_BLOCK;
2172  
2173 osPoolDef (MemPool, 8, MEM_BLOCK);
2174   
2175 void CAlocMemoryPoolBlock (void)  {
2176   osPoolId   MemPool_Id;
2177   MEM_BLOCK *addr;
2178   osStatus   status;
2179   
2180   MemPool_Id = osPoolCreate (osPool (MemPool));
2181   if (MemPool_Id != NULL)  {
2182     addr = (MEM_BLOCK *)osPoolCAlloc (MemPool_Id);
2183     if (addr != NULL) {
2184       :
2185       // return a memory block back to pool
2186       status = osPoolFree (MemPool_Id, addr);
2187       if (status==osOK)  {
2188         // handle status code
2189       }
2190     }
2191   }
2192 }
2193 \endcode
2194 */
2195
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)
2198  
2199 */
2200
2201 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2202 /** \fn osStatus osMemoryPoolDelete (osMemoryPoolId pool_id)
2203
2204 */
2205
2206 /// @}
2207
2208
2209 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2210 //  ==== Message Queue Management Functions ====
2211 /** 
2212 @addtogroup CMSIS_RTOS_Message Message Queue
2213 @ingroup CMSIS_RTOS_InterThread
2214 @brief Exchange messages between threads in a FIFO-like operation.
2215 @details 
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:
2221
2222 \image html "MessageQueue.png" "CMSIS-RTOS Message Queue"
2223
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.
2226
2227 Working with Message Queues
2228 ---------------------------
2229 Follow these steps to create and use a message queue:
2230 -# Setup the message queue:
2231 \code
2232 osMessageQDef(message_q, 5, uint32_t); // Declare a message queue
2233 osMessageQId (message_q_id);           // Declare an ID for the message queue
2234 \endcode
2235 -# Then, create the message queue in a thread:
2236 \code
2237 message_q_id = osMessageCreate(osMessageQ(message_q), NULL);
2238 \endcode
2239 -# Fill the message queue with data:
2240 \code
2241 uint32_t data = 512;
2242  
2243 osMailPut(message_q_id, data, osWaitForever);
2244 \endcode
2245 -# From the receiving thread access the data using:
2246 \code
2247 osEvent event = osMessageGet(message_q_id, osWaitForever);
2248 \endcode
2249
2250 @{
2251 */
2252
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.
2256 */
2257
2258 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2259 /** \def osMessageQueueAttrInit
2260 Message Queue attributes initialization.
2261 */
2262
2263 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2264 /** \def osMessageQueueMem
2265 User memory allocation for Message Queue data.
2266 */
2267
2268 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2269 /** \struct osMessageQueueAttr_t
2270 Attributes structure for message queue.
2271 */
2272
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.
2276
2277 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
2278
2279 <b>Code Example</b>
2280 \code
2281 #include "cmsis_os.h"
2282  
2283 osThreadId tid_thread1;                          // ID for thread 1
2284 osThreadId tid_thread2;                          // for thread 2
2285  
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
2290 } T_MEAS;
2291  
2292 osPoolDef(mpool, 16, T_MEAS);                    // Define memory pool
2293 osPoolId  mpool;
2294 osMessageQDef(MsgBox, 16, T_MEAS);               // Define message queue
2295 osMessageQId  MsgBox;
2296  
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);
2302  
2303 //
2304 //  Thread 1: Send thread
2305 //
2306 void send_thread (void const *argument) {
2307   T_MEAS    *mptr;
2308  
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
2314   osDelay(100);
2315  
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
2323 }
2324  
2325 //
2326 //  Thread 2: Receive thread
2327 //
2328 void recv_thread (void const *argument) {
2329   T_MEAS  *rptr;
2330   osEvent  evt;
2331    
2332   for (;;) {
2333     evt = osMessageGet(MsgBox, osWaitForever);  // wait for message
2334     if (evt.status == osEventMessage) {
2335       rptr = evt.value.p;
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
2340     }
2341   }
2342 }
2343  
2344 void StartApplication (void) {
2345   mpool = osPoolCreate(osPool(mpool));                 // create memory pool
2346   MsgBox = osMessageCreate(osMessageQ(MsgBox), NULL);  // create msg queue
2347    
2348   tid_thread1 = osThreadCreate(osThread(send_thread), NULL);
2349   tid_thread2 = osThreadCreate(osThread(recv_thread), NULL);
2350   :
2351 }
2352 \endcode
2353 */
2354
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. 
2358
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
2364    available.
2365  - all other values specify a time in millisecond for a timeout.
2366
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.
2369
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.
2375
2376 <b>Code Example</b>
2377 Refer to \ref osMessageQueueNew.
2378 */
2379
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.
2384
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.
2391  
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.
2394
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.
2400
2401 <b>Code Example</b>
2402 Refer to \ref osMessageQueueNew.
2403 */
2404
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);
2407  
2408 */
2409
2410 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2411 /** \fn osStatus osMessageQueueReset (osMessageQueueId queue_id);
2412  
2413 */
2414
2415 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2416 /** \fn osStatus osMessageQueueDelete (osMessageQueueId queue_id);
2417
2418 */
2419
2420 /// @}
2421
2422
2423 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2424 //  ==== Mail Queue Management Functions ====
2425 /** 
2426 \addtogroup CMSIS_RTOS_Mail Mail Queue
2427 \ingroup CMSIS_RTOS_InterThread
2428 \brief Exchange data between threads using a queue of memory blocks.
2429 \details
2430
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.
2437
2438 \image html "MailQueue.png" "CMSIS-RTOS Mail Queue"
2439
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:
2444 \code
2445 typedef struct {
2446   uint32_t length;
2447   uint32_t width;
2448   uint32_t height;
2449   uint32_t weight;
2450 } properties_t;
2451 \endcode
2452 -# Declare a mail queue made up of these objects:
2453 \code
2454 //osMailQDef (object_pool_q, 10, properties_t);  // Declare mail queue
2455 osMailQId  (object_pool_q_id);                 // Mail queue ID
2456 \endcode
2457 -# Then, create the mail pool in a thread:
2458 \code
2459 object_pool_q_id = osMailCreate(osMailQ(object_pool_q), NULL);
2460 \endcode
2461 -# Allocate the mail queue within a thread and fill it with data:
2462 \code
2463 properties_t *object_data;
2464 *object_data = (properties_t *) osMailAlloc(object_pool_q_id, osWaitForever);
2465  
2466 object_data->length = 100;
2467 object_data->width = 10;
2468 object_data->height = 23;
2469 object_data->weight = 1000;
2470 \endcode
2471 -# Pass the pointer to the mail queue to another thread:
2472 \code
2473 osMailPut(object_pool_q_id, object_data);
2474 \endcode
2475 -# Access the data in another thread:
2476 \code
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);
2480 \endcode
2481 -# Once the data has been used, the memory block must be freed so that the memory pool can be reused
2482 \code
2483 osMailFree(object_pool_q_id, received);
2484 \endcode
2485
2486 @{
2487 */
2488
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.
2492 */
2493
2494 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2495 /** \def osMailQueueAttrInit
2496 Mail Queue attributes initialization.
2497 */
2498
2499 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2500 /** \def osMailQueueMem
2501 User memory allocation for Mail Queue data.
2502 */
2503
2504 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2505 /** \struct osMailQueueAttr_t
2506 Attributes structure for mail queue.
2507 */
2508
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.
2512
2513 \note Cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
2514
2515 <b>Code Example</b>
2516 \code
2517 #include "cmsis_os.h"
2518  
2519 osThreadId tid_thread1;                          // ID for thread 1
2520 osThreadId tid_thread2;                          // ID for thread 2
2521  
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
2526 } T_MEAS;
2527  
2528 osMailQDef(mail, 16, T_MEAS);                    // Define mail queue
2529 osMailQId  mail;
2530  
2531 void send_thread (void const *argument);         // forward reference
2532 void recv_thread (void const *argument);
2533  
2534 osThreadDef(send_thread, osPriorityNormal, 1, 0);     // thread definitions
2535 osThreadDef(recv_thread, osPriorityNormal, 1, 2000);
2536  
2537 //
2538 //  Thread 1: Send thread
2539 //
2540 void send_thread (void const *argument) {
2541   T_MEAS *mptr;
2542  
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
2548   osDelay(100);
2549    
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
2557 }
2558  
2559 //
2560 //  Thread 2: Receive thread
2561 //
2562 void recv_thread (void const *argument) {
2563   T_MEAS  *rptr;
2564   osEvent  evt;
2565    
2566   for (;;) {
2567     evt = osMailGet(mail, osWaitForever);        // wait for mail
2568     if (evt.status == osEventMail) {
2569       rptr = evt.value.p;
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
2574     }
2575   }
2576 }
2577  
2578 void StartApplication (void) {
2579   mail = osMailCreate(osMailQ(mail), NULL);      // create mail queue
2580  
2581   tid_thread1 = osThreadCreate(osThread(send_thread), NULL);
2582   tid_thread2 = osThreadCreate(osThread(recv_thread), NULL);
2583   :
2584 }
2585 \endcode
2586 */
2587
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.
2591
2592 The argument \a queue_id specifies a mail queue identifier that is obtain with \ref osMailQueueNew.
2593
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.
2600  
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.
2603
2604 A NULL pointer is returned when no memory slot can be obtained or \a queue specifies an illegal parameter.
2605 */
2606
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. 
2610
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.
2615
2616 <b>Code Example</b>
2617 Refer to \ref osMailQueueNew.
2618 */
2619
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.
2624
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.
2631  
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.
2634
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.
2640
2641 <b>Code Example</b>
2642 Refer to \ref osMailQueueNew.
2643 */
2644
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.
2648
2649 \note \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" can call this function.
2650
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.
2655
2656 <b>Code Example</b>
2657 Refer to \ref osMailQueueNew.
2658 */
2659
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       )       
2662  
2663 */
2664
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)
2667  
2668 */
2669
2670 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2671 /** \fn osStatus osMailQueueReset (osMailQueueId queue_id)
2672  
2673 */
2674
2675 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2676 /** \fn osStatus osMailQueueDelete (osMailQueueId queue_id)
2677
2678 */
2679 /// @}
2680
2681 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2682 // ==== Status and Error Codes ====
2683 /**
2684 \addtogroup CMSIS_RTOS_Status Status and Error Codes
2685 \ingroup CMSIS_RTOS
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.
2688 @{
2689 */
2690
2691 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2692 /**
2693 \typedef osStatus
2694 \details
2695 The \b osStatus enumeration defines the event status and error codes that are returned by the CMSIS-RTOS functions.
2696 */
2697 /// @} 
2698
2699
2700