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