]> begriffs open source - cmsis/blob - CMSIS/DoxyGen/RTOS2/src/cmsis_os2_Mutex.txt
Fix arch profile detection:
[cmsis] / CMSIS / DoxyGen / RTOS2 / src / cmsis_os2_Mutex.txt
1 // 
2 // close group struct osMutexAttr_t
3 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
4 //  ==== Mutex Management ====
5 /** 
6 \addtogroup CMSIS_RTOS_MutexMgmt Mutex Management
7 \ingroup CMSIS_RTOS
8 \brief Synchronize resource access using Mutual Exclusion (Mutex).
9 \details 
10 <b>Mutual exclusion</b> (widely known as \b Mutex) is used in various operating systems for resource management. Many
11 resources in a microcontroller device can be used repeatedly, but only by one thread at a time (for example communication
12 channels, memory, and files). Mutexes are used to protect access to a shared resource. A mutex is created and then passed
13 between the threads (they can acquire and release the mutex).
14
15 \image html "Mutex.png" "CMSIS-RTOS Mutex"
16
17 A mutex is a special version of a \ref CMSIS_RTOS_SemaphoreMgmt "semaphore". Like the semaphore, it is a container for
18 tokens. But instead of being able to have multiple tokens, a mutex can only carry one (representing the resource). Thus, a
19 mutex token is binary and bounded, i.e. it is either \em available, or \em blocked by a owning thread. The advantage of a
20 mutex is that it introduces thread ownership. When a thread acquires a mutex and becomes its owner, subsequent mutex acquires
21 from that thread will succeed immediately without any latency (if \ref osMutexRecursive is specified). Thus, mutex acquires/releases
22 can be nested.
23
24 \image html "mutex_states.png" "CMSIS-RTOS Mutex States"
25
26 \note Mutex management functions cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" (ISR), unlike a
27 binary semaphore that can be released from an ISR.
28 \note Refer to \ref mutexConfig for RTX5 configuration options.  
29   
30 @{
31 */
32 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
33 /**
34 \def osMutexRecursive
35 \details
36 Recursive flag in osMutexAttr_t.
37
38 The same thread can consume a mutex multiple times without locking itself.
39 Each time the owning thread acquires the mutex the lock count is incremented. The mutex must
40 be released multiple times as well until the lock count reaches zero. At reaching zero the
41 mutex is actually released and can be acquired by other threads.
42
43 \note The maximum amount of recursive locks possible is implementation specific, i.e. the type size used for the lock count.
44 If the maximum amount of recursive locks is depleted mutex acquire might fail.
45
46 <b>Code Example</b>
47 \code
48 #include "cmsis_os2.h"
49  
50 osMutexId_t mutex_id; 
51  
52 const osMutexAttr_t Thread_Mutex_attr = {
53   "myThreadMutex",     // human readable mutex name
54   osMutexRecursive,    // attr_bits
55   NULL,                // memory for control block   
56   0U                   // size for control block
57 };
58  
59 // must be called from a thread context
60 void UseMutexRecursively(int count) {
61   osStatus_t result = osMutexAcquire(mutex_id, osWaitForever);  // lock count is incremented, might fail when lock count is depleted
62   if (result == osOK) {
63     if (count < 10) {
64       UseMutexRecursively(count + 1);
65     }
66     osMutexRelease(mutex_id); // lock count is decremented, actually releases the mutex on lock count zero
67   }
68 }
69 \endcode
70 */
71
72 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
73 /**
74 \def osMutexPrioInherit
75 \details
76 Priority inheritance flag in osMutexAttr_t.
77
78 A mutex using priority inheritance protocol transfers a waiting threads priority to the
79 current mutex owner if the owners thread priority is lower. This assures that a low priority
80 thread does not block a high priority thread.
81
82 Otherwise a low priority thread might hold a mutex but is not granted execution time due to
83 another mid priority thread. Without priority inheritance the high priority thread waiting
84 for the mutex would be blocked by the mid priority thread, called priority inversion.
85
86 <b>Code Example</b>
87
88 This example reveals a blocked high priority thread if \ref osMutexPrioInherit is removed.
89
90 \code
91 #include "cmsis_os2.h"
92  
93 osMutexId_t mutex_id;  
94  
95 const osMutexAttr_t Thread_Mutex_attr = {
96   "myThreadMutex",     // human readable mutex name
97   osMutexPrioInherit,  // attr_bits
98   NULL,                // memory for control block   
99   0U                   // size for control block
100 };
101  
102 void HighPrioThread(void *argument) {
103   osDelay(1000U); // wait 1s until start actual work
104   while(1) {
105     osMutexAcquire(mutex_id, osWaitForever); // try to acquire mutex
106     // do stuff
107     osMutexRelease(mutex_id);
108   }
109 }
110  
111 void MidPrioThread(void *argument) {
112   osDelay(1000U); // wait 1s until start actual work
113   while(1) {
114     // do non blocking stuff
115   }
116 }
117  
118 void LowPrioThread(void *argument) {
119   while(1) {
120     osMutexAcquire(mutex_id, osWaitForever);
121     osDelay(5000U); // block mutex for 5s
122     osMutexRelease(mutex_id);
123     osDelay(5000U); // sleep for 5s
124   }
125 }
126 \endcode
127
128 During the first second the high and mid priority threads are delayed. Thus the low priority
129 thread can start its work, acquires the mutex and delays while holding it.
130
131 After the first second the high and mid priority threads become ready. Thus the high priority
132 thread gets precedence and tries to acquire the mutex. Because the mutex is already owned by
133 the low priority thread the high priority thread gets blocked.
134
135 Finally the mid priority thread gets executed and start doing a lot of non-blocking stuff,
136 i.e. it does not call any blocking RTOS functionality.
137
138 Without \ref osMutexPrioInherit we would stuck here forever. Even if the low priority thread
139 gets ready after 5s. Due to its low priority the mid priority thread always gets precedence.
140 The effect called priority inversion leads to the mid priority thread blocking the high
141 priority thread indirectly.
142
143 Using \ref osMutexPrioInherit as shown in the example code we get rid of this situation. Due
144 to the priority inheritance protocol the low priority thread inherits the high priority
145 while holding the mutex. Thus the low priority thread gets precedence over the mid priority
146 thread until it release the mutex. On osMutexRelease the high priority thread get ready and
147 is scheduled immediately.
148
149 */
150
151 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
152 /**
153 \def osMutexRobust
154 \details
155 Robust flag in osMutexAttr_t.
156
157 Robust mutexes are automatically released if the owning thread is terminated (either by
158 \ref osThreadExit or \ref osThreadTerminate). Non-robust mutexes are not released and the user must
159 assure mutex release manually.
160
161 <b>Code Example</b>
162
163 This example reveals a blocked mutex if osMutexRobust is removed.
164
165 \code
166 #include "cmsis_os2.h"
167  
168 osMutexId_t mutex_id;
169  
170 const osMutexAttr_t Thread_Mutex_attr = {
171   "myThreadMutex",     // human readable mutex name
172   osMutexRobust,       // attr_bits
173   NULL,                // memory for control block   
174   0U                   // size for control block
175 };
176  
177 void Thread(void *argument) {
178   osMutexAcquire(mutex_id, osWaitForever);
179   osThreadExit();
180 }
181 \endcode
182
183 Due to \ref osMutexRobust the mutex gets released automatically. A non-robust mutex would stay locked and cannot be released anymore.
184 */
185
186 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
187 /**
188 \typedef osMutexId_t
189 \details
190 Returned by:
191 - \ref osMutexNew
192 */ 
193
194 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
195 /**
196 \struct osMutexAttr_t
197 \details
198 Specifies the following attributes for the \ref osMutexNew function.
199 */
200
201 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
202 /**
203 \fn osMutexId_t osMutexNew (const osMutexAttr_t *attr)
204 \details
205 The function \b osMutexNew creates and initializes a new mutex object and returns the pointer to the mutex object identifier
206 or \token{NULL} in case of an error. It can be safely called before the RTOS is
207 started (call to \ref osKernelStart), but not before it is initialized (call to \ref osKernelInitialize).
208
209 The parameter \a attr sets the mutex object attributes (refer to \ref osMutexAttr_t). Default attributes will be used if set
210 to \token{NULL}.
211
212 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
213
214 <b>Code Example</b>
215 \code
216 #include "cmsis_os2.h"
217  
218 osMutexId_t mutex_id;  
219  
220 const osMutexAttr_t Thread_Mutex_attr = {
221   "myThreadMutex",                          // human readable mutex name
222   osMutexRecursive | osMutexPrioInherit,    // attr_bits
223   NULL,                                     // memory for control block   
224   0U                                        // size for control block
225 };
226  
227 void CreateMutex (void)  {
228   mutex_id = osMutexNew(&Thread_Mutex_attr);
229   if (mutex_id != NULL)  {
230     // Mutex object created
231   }
232 }
233 \endcode
234 */
235
236 */
237 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
238 /**
239 \fn const char *osMutexGetName (osMutexId_t mutex_id)
240 \details
241 The function \b osMutexGetName returns the pointer to the name string of the mutex identified by parameter \a mutex_id or
242 \token{NULL} in case of an error.
243
244 \note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
245 */
246
247 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
248 /**
249 \fn osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout)
250 \details
251 The blocking function \b osMutexAcquire waits until a mutex object specified by parameter \a mutex_id becomes available. If
252 no other thread has obtained the mutex, the function instantly returns and blocks the mutex object. 
253
254 The parameter \a timeout specifies how long the system waits to acquire the mutex. While the system waits, the thread that is
255 calling this function is put into the \ref ThreadStates "BLOCKED" state. The parameter \ref CMSIS_RTOS_TimeOutValue "timeout"
256 can have the following values:
257  - when \a timeout is \token{0}, the function returns instantly (i.e. try semantics).
258  - when \a timeout is set to \b osWaitForever the function will wait for an infinite time until the mutex becomes available (i.e. wait semantics).
259  - all other values specify a time in kernel ticks for a timeout (i.e. timed-wait semantics).
260
261 Possible \ref osStatus_t return values:
262  - \em osOK: the mutex has been obtained.
263  - \em osErrorTimeout: the mutex could not be obtained in the given time.
264  - \em osErrorResource: the mutex could not be obtained when no \a timeout was specified.
265  - \em osErrorParameter: parameter \em mutex_id is \token{NULL} or invalid.
266  - \em osErrorISR: cannot be called from interrupt service routines.
267  - \em osErrorSafetyClass: the calling thread safety class is lower than the safety class of the specified mutex.
268
269 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
270
271 <b>Code Example</b>
272 \code
273 #include "cmsis_os2.h"
274  
275 void WaitMutex (void) {
276   osMutexId_t mutex_id;
277   osStatus_t  status;
278  
279   mutex_id = osMutexNew(NULL);
280   if (mutex_id != NULL) {
281     status = osMutexAcquire(mutex_id, 0U);
282     if (status != osOK)  {
283       // handle failure code
284     }
285   }
286 }
287 \endcode
288 */
289
290 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
291 /**
292 \fn osStatus_t osMutexRelease (osMutexId_t mutex_id)
293 \details
294 The function \b osMutexRelease releases a mutex specified by parameter \a mutex_id. Other threads that currently wait for
295 this mutex will be put into the \ref ThreadStates "READY" state.
296
297 Possible \ref osStatus_t return values:
298  - \em osOK: the mutex has been correctly released.
299  - \em osErrorResource: the mutex could not be released (mutex was not acquired or running thread is not the owner).
300  - \em osErrorParameter: parameter \em mutex_id is \token{NULL} or invalid.
301  - \em osErrorISR: \b osMutexRelease cannot be called from interrupt service routines.
302
303 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
304
305 <b>Code Example</b>
306 \code
307 #include "cmsis_os2.h"
308  
309 osMutexId_t mutex_id;                                        // Mutex id populated by the function osMutexNew()
310  
311 void ReleaseMutex (osMutexId_t mutex_id) {
312   osStatus_t status;
313  
314   if (mutex_id != NULL)  {
315     status = osMutexRelease(mutex_id);
316     if (status != osOK)  {
317       // handle failure code
318     }
319   }
320 }
321 \endcode
322 */
323
324 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
325 /**
326 \fn osThreadId_t osMutexGetOwner (osMutexId_t mutex_id)
327 \details
328 The function \b osMutexGetOwner returns the thread ID of the thread that acquired a mutex specified by parameter \a
329 mutex_id. In case of an error or if the mutex is not blocked by any thread, it returns \token{NULL}.
330
331 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
332 */
333
334 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
335 /**
336 \fn osStatus_t osMutexDelete (osMutexId_t mutex_id)
337 \details
338 The function \b osMutexDelete deletes a mutex object specified by parameter \a mutex_id. It releases internal memory obtained
339 for mutex handling. After this call, the \a mutex_id is no longer valid and cannot be used. The mutex may be created again
340 using the function \ref osMutexNew.
341
342 Possible \ref osStatus_t return values:
343  - \em osOK: the mutex object has been deleted.
344  - \em osErrorParameter: parameter \em mutex_id is \token{NULL} or invalid.
345  - \em osErrorResource: the mutex is in an invalid state.
346  - \em osErrorISR: \b osMutexDelete cannot be called from interrupt service routines.
347  - \em osErrorSafetyClass: the calling thread safety class is lower than the safety class of the specified mutex.
348
349 \note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines".
350
351 <b>Code Example</b>
352 \code
353 #include "cmsis_os2.h"
354  
355 osMutexId_t mutex_id;                           // Mutex id populated by the function osMutexNew()
356  
357 void DeleteMutex (osMutexId_t mutex_id)  {
358   osStatus_t status;
359  
360   if (mutex_id != NULL)  {
361     status = osMutexDelete(mutex_id);
362     if (status != osOK)  {
363       // handle failure code
364     }
365   }
366 }
367 \endcode
368 */
369 /// @}
370
371 // these struct members must stay outside the group to avoid double entries in documentation
372 /**
373 \var osMutexAttr_t::attr_bits
374 \details
375 The following bit masks can be used to set options:
376  - \ref osMutexRecursive : a thread can consume the mutex multiple times without locking itself.
377  - \ref osMutexPrioInherit : the owner thread inherits the priority of a (higher priority) waiting thread.
378  - \ref osMutexRobust : the mutex is automatically released when owner thread is terminated.
379
380 Use logical \em 'OR' operation to select multiple options, for example:
381 \code
382 osMutexRecursive | osMutexPrioInherit;
383 \endcode
384
385 Default: \token{0} which specifies:
386  - <i>non recursive mutex</i>: a thread cannot consume the mutex multiple times.
387  - <i>non priority raising</i>: the priority of an owning thread is not changed.
388  - <i>mutex is not automatically release</i>: the mutex object must be always is automatically released when owner thread is terminated.
389
390 */
391 /**
392 \var osMutexAttr_t::cb_mem
393 \details
394 Pointer to a memory for the mutex control block object. Refer to \ref StaticObjectMemory for more information.
395
396 Default: \token{NULL} to use \ref CMSIS_RTOS_MemoryMgmt_Automatic for the mutex control block.
397 */
398 /**
399 \var osMutexAttr_t::cb_size
400 \details
401 The size (in bytes) of memory block passed with \ref cb_mem. For RTX, the minimum value is defined with \ref osRtxMutexCbSize (higher values are permitted).
402
403 Default: \token{0} as the default is no memory provided with \ref cb_mem.
404 */
405 /**
406 \var osMutexAttr_t::name
407 \details
408 Pointer to a constant string with a human readable name (displayed during debugging) of the mutex object.
409
410 Default: \token{NULL} no name specified.
411 */