]> git.sur5r.net Git - freertos/blob - Source/include/semphr.h
Update to V5.1.2.
[freertos] / Source / include / semphr.h
1 /*\r
2         FreeRTOS.org V5.1.2 - Copyright (C) 2003-2009 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS.org is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS.org; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS.org, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section \r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26     ***************************************************************************\r
27     ***************************************************************************\r
28     *                                                                         *\r
29     * Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *\r
30         *                                                                         *\r
31         * This is a concise, step by step, 'hands on' guide that describes both   *\r
32         * general multitasking concepts and FreeRTOS specifics. It presents and   *\r
33         * explains numerous examples that are written using the FreeRTOS API.     *\r
34         * Full source code for all the examples is provided in an accompanying    *\r
35         * .zip file.                                                              *\r
36     *                                                                         *\r
37     ***************************************************************************\r
38     ***************************************************************************\r
39 \r
40         Please ensure to read the configuration and relevant port sections of the\r
41         online documentation.\r
42 \r
43         http://www.FreeRTOS.org - Documentation, latest information, license and \r
44         contact details.\r
45 \r
46         http://www.SafeRTOS.com - A version that is certified for use in safety \r
47         critical systems.\r
48 \r
49         http://www.OpenRTOS.com - Commercial support, development, porting, \r
50         licensing and training services.\r
51 */\r
52 \r
53 #ifndef INC_FREERTOS_H\r
54         #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"\r
55 #endif\r
56 \r
57 #ifndef SEMAPHORE_H\r
58 #define SEMAPHORE_H\r
59 \r
60 #include "queue.h"\r
61 \r
62 typedef xQueueHandle xSemaphoreHandle;\r
63 \r
64 #define semBINARY_SEMAPHORE_QUEUE_LENGTH        ( ( unsigned portCHAR ) 1 )\r
65 #define semSEMAPHORE_QUEUE_ITEM_LENGTH          ( ( unsigned portCHAR ) 0 )\r
66 #define semGIVE_BLOCK_TIME                                      ( ( portTickType ) 0 )\r
67 \r
68 \r
69 /**\r
70  * semphr. h\r
71  * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>\r
72  *\r
73  * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.\r
74  * The queue length is 1 as this is a binary semaphore.  The data size is 0\r
75  * as we don't want to actually store any data - we just want to know if the\r
76  * queue is empty or full.\r
77  *\r
78  * This type of semaphore can be used for pure synchronisation between tasks or\r
79  * between an interrupt and a task.  The semaphore need not be given back once\r
80  * obtained, so one task/interrupt can continuously 'give' the semaphore while\r
81  * another continuously 'takes' the semaphore.  For this reason this type of\r
82  * semaphore does not use a priority inheritance mechanism.  For an alternative\r
83  * that does use priority inheritance see xSemaphoreCreateMutex().\r
84  *\r
85  * @param xSemaphore Handle to the created semaphore.  Should be of type xSemaphoreHandle.\r
86  *\r
87  * Example usage:\r
88  <pre>\r
89  xSemaphoreHandle xSemaphore;\r
90 \r
91  void vATask( void * pvParameters )\r
92  {\r
93     // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().\r
94     // This is a macro so pass the variable in directly.\r
95     vSemaphoreCreateBinary( xSemaphore );\r
96 \r
97     if( xSemaphore != NULL )\r
98     {\r
99         // The semaphore was created successfully.\r
100         // The semaphore can now be used.  \r
101     }\r
102  }\r
103  </pre>\r
104  * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary\r
105  * \ingroup Semaphores\r
106  */\r
107 #define vSemaphoreCreateBinary( xSemaphore )            {                                                                                                                                                                                               \\r
108                                                                                                                 xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH );      \\r
109                                                                                                                 if( xSemaphore != NULL )                                                                                                                                        \\r
110                                                                                                                 {                                                                                                                                                                                       \\r
111                                                                                                                         xSemaphoreGive( xSemaphore );                                                                                                                   \\r
112                                                                                                                 }                                                                                                                                                                                       \\r
113                                                                                                         }\r
114 \r
115 /**\r
116  * semphr. h\r
117  * xSemaphoreTake( \r
118  *                   xSemaphoreHandle xSemaphore, \r
119  *                   portTickType xBlockTime \r
120  *               )</pre>\r
121  *\r
122  * <i>Macro</i> to obtain a semaphore.  The semaphore must have previously been\r
123  * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
124  * xSemaphoreCreateCounting().\r
125  *\r
126  * @param xSemaphore A handle to the semaphore being taken - obtained when\r
127  * the semaphore was created.\r
128  *\r
129  * @param xBlockTime The time in ticks to wait for the semaphore to become\r
130  * available.  The macro portTICK_RATE_MS can be used to convert this to a\r
131  * real time.  A block time of zero can be used to poll the semaphore.  A block\r
132  * time of portMAX_DELAY can be used to block indefinitely (provided\r
133  * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).\r
134  *\r
135  * @return pdTRUE if the semaphore was obtained.  pdFALSE\r
136  * if xBlockTime expired without the semaphore becoming available.\r
137  *\r
138  * Example usage:\r
139  <pre>\r
140  xSemaphoreHandle xSemaphore = NULL;\r
141 \r
142  // A task that creates a semaphore.\r
143  void vATask( void * pvParameters )\r
144  {\r
145     // Create the semaphore to guard a shared resource.\r
146     vSemaphoreCreateBinary( xSemaphore );\r
147  }\r
148 \r
149  // A task that uses the semaphore.\r
150  void vAnotherTask( void * pvParameters )\r
151  {\r
152     // ... Do other things.\r
153 \r
154     if( xSemaphore != NULL )\r
155     {\r
156         // See if we can obtain the semaphore.  If the semaphore is not available\r
157         // wait 10 ticks to see if it becomes free.     \r
158         if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )\r
159         {\r
160             // We were able to obtain the semaphore and can now access the\r
161             // shared resource.\r
162 \r
163             // ...\r
164 \r
165             // We have finished accessing the shared resource.  Release the \r
166             // semaphore.\r
167             xSemaphoreGive( xSemaphore );\r
168         }\r
169         else\r
170         {\r
171             // We could not obtain the semaphore and can therefore not access\r
172             // the shared resource safely.\r
173         }\r
174     }\r
175  }\r
176  </pre>\r
177  * \defgroup xSemaphoreTake xSemaphoreTake\r
178  * \ingroup Semaphores\r
179  */\r
180 #define xSemaphoreTake( xSemaphore, xBlockTime )                xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )\r
181 \r
182 /**\r
183  * semphr. h\r
184  * xSemaphoreTakeRecursive( \r
185  *                          xSemaphoreHandle xMutex, \r
186  *                          portTickType xBlockTime \r
187  *                        )\r
188  *\r
189  * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.  \r
190  * The mutex must have previously been created using a call to \r
191  * xSemaphoreCreateRecursiveMutex();\r
192  * \r
193  * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
194  * macro to be available.\r
195  * \r
196  * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
197  *\r
198  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
199  * doesn't become available again until the owner has called \r
200  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example, \r
201  * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
202  * not be available to any other task until it has also  'given' the mutex back\r
203  * exactly five times.\r
204  *\r
205  * @param xMutex A handle to the mutex being obtained.  This is the\r
206  * handle returned by xSemaphoreCreateRecursiveMutex();\r
207  *\r
208  * @param xBlockTime The time in ticks to wait for the semaphore to become\r
209  * available.  The macro portTICK_RATE_MS can be used to convert this to a\r
210  * real time.  A block time of zero can be used to poll the semaphore.  If\r
211  * the task already owns the semaphore then xSemaphoreTakeRecursive() will\r
212  * return immediately no matter what the value of xBlockTime. \r
213  *\r
214  * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime\r
215  * expired without the semaphore becoming available.\r
216  *\r
217  * Example usage:\r
218  <pre>\r
219  xSemaphoreHandle xMutex = NULL;\r
220 \r
221  // A task that creates a mutex.\r
222  void vATask( void * pvParameters )\r
223  {\r
224     // Create the mutex to guard a shared resource.\r
225     xMutex = xSemaphoreCreateRecursiveMutex();\r
226  }\r
227 \r
228  // A task that uses the mutex.\r
229  void vAnotherTask( void * pvParameters )\r
230  {\r
231     // ... Do other things.\r
232 \r
233     if( xMutex != NULL )\r
234     {\r
235         // See if we can obtain the mutex.  If the mutex is not available\r
236         // wait 10 ticks to see if it becomes free.     \r
237         if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )\r
238         {\r
239             // We were able to obtain the mutex and can now access the\r
240             // shared resource.\r
241 \r
242             // ...\r
243             // For some reason due to the nature of the code further calls to \r
244                         // xSemaphoreTakeRecursive() are made on the same mutex.  In real\r
245                         // code these would not be just sequential calls as this would make\r
246                         // no sense.  Instead the calls are likely to be buried inside\r
247                         // a more complex call structure.\r
248             xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
249             xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
250 \r
251             // The mutex has now been 'taken' three times, so will not be \r
252                         // available to another task until it has also been given back\r
253                         // three times.  Again it is unlikely that real code would have\r
254                         // these calls sequentially, but instead buried in a more complex\r
255                         // call structure.  This is just for illustrative purposes.\r
256             xSemaphoreGiveRecursive( xMutex );\r
257                         xSemaphoreGiveRecursive( xMutex );\r
258                         xSemaphoreGiveRecursive( xMutex );\r
259 \r
260                         // Now the mutex can be taken by other tasks.\r
261         }\r
262         else\r
263         {\r
264             // We could not obtain the mutex and can therefore not access\r
265             // the shared resource safely.\r
266         }\r
267     }\r
268  }\r
269  </pre>\r
270  * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive\r
271  * \ingroup Semaphores\r
272  */\r
273 #define xSemaphoreTakeRecursive( xMutex, xBlockTime )   xQueueTakeMutexRecursive( xMutex, xBlockTime )\r
274 \r
275 \r
276 /* \r
277  * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().\r
278  *\r
279  * The source code that implements the alternative (Alt) API is much \r
280  * simpler      because it executes everything from within a critical section.  \r
281  * This is      the approach taken by many other RTOSes, but FreeRTOS.org has the \r
282  * preferred fully featured API too.  The fully featured API has more \r
283  * complex      code that takes longer to execute, but makes much less use of \r
284  * critical sections.  Therefore the alternative API sacrifices interrupt \r
285  * responsiveness to gain execution speed, whereas the fully featured API\r
286  * sacrifices execution speed to ensure better interrupt responsiveness.\r
287  */\r
288 #define xSemaphoreAltTake( xSemaphore, xBlockTime )             xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )\r
289 \r
290 /**\r
291  * semphr. h\r
292  * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>\r
293  *\r
294  * <i>Macro</i> to release a semaphore.  The semaphore must have previously been\r
295  * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
296  * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().\r
297  *\r
298  * This macro must not be used from an ISR.  See xSemaphoreGiveFromISR () for\r
299  * an alternative which can be used from an ISR.\r
300  *\r
301  * This macro must also not be used on semaphores created using \r
302  * xSemaphoreCreateRecursiveMutex().\r
303  *\r
304  * @param xSemaphore A handle to the semaphore being released.  This is the\r
305  * handle returned when the semaphore was created.\r
306  *\r
307  * @return pdTRUE if the semaphore was released.  pdFALSE if an error occurred.\r
308  * Semaphores are implemented using queues.  An error can occur if there is\r
309  * no space on the queue to post a message - indicating that the \r
310  * semaphore was not first obtained correctly.\r
311  *\r
312  * Example usage:\r
313  <pre>\r
314  xSemaphoreHandle xSemaphore = NULL;\r
315 \r
316  void vATask( void * pvParameters )\r
317  {\r
318     // Create the semaphore to guard a shared resource.\r
319     vSemaphoreCreateBinary( xSemaphore );\r
320 \r
321     if( xSemaphore != NULL )\r
322     {\r
323         if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
324         {\r
325             // We would expect this call to fail because we cannot give\r
326             // a semaphore without first "taking" it!\r
327         }\r
328 \r
329         // Obtain the semaphore - don't block if the semaphore is not\r
330         // immediately available.\r
331         if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )\r
332         {\r
333             // We now have the semaphore and can access the shared resource.\r
334 \r
335             // ...\r
336 \r
337             // We have finished accessing the shared resource so can free the\r
338             // semaphore.\r
339             if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
340             {\r
341                 // We would not expect this call to fail because we must have\r
342                 // obtained the semaphore to get here.\r
343             }\r
344         }\r
345     }\r
346  }\r
347  </pre>\r
348  * \defgroup xSemaphoreGive xSemaphoreGive\r
349  * \ingroup Semaphores\r
350  */\r
351 #define xSemaphoreGive( xSemaphore )            xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
352 \r
353 /**\r
354  * semphr. h\r
355  * <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>\r
356  *\r
357  * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.\r
358  * The mutex must have previously been created using a call to \r
359  * xSemaphoreCreateRecursiveMutex();\r
360  * \r
361  * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
362  * macro to be available.\r
363  *\r
364  * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
365  * \r
366  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
367  * doesn't become available again until the owner has called \r
368  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example, \r
369  * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
370  * not be available to any other task until it has also  'given' the mutex back\r
371  * exactly five times.\r
372  *\r
373  * @param xMutex A handle to the mutex being released, or 'given'.  This is the\r
374  * handle returned by xSemaphoreCreateMutex();\r
375  *\r
376  * @return pdTRUE if the semaphore was given.\r
377  *\r
378  * Example usage:\r
379  <pre>\r
380  xSemaphoreHandle xMutex = NULL;\r
381 \r
382  // A task that creates a mutex.\r
383  void vATask( void * pvParameters )\r
384  {\r
385     // Create the mutex to guard a shared resource.\r
386     xMutex = xSemaphoreCreateRecursiveMutex();\r
387  }\r
388 \r
389  // A task that uses the mutex.\r
390  void vAnotherTask( void * pvParameters )\r
391  {\r
392     // ... Do other things.\r
393 \r
394     if( xMutex != NULL )\r
395     {\r
396         // See if we can obtain the mutex.  If the mutex is not available\r
397         // wait 10 ticks to see if it becomes free.     \r
398         if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )\r
399         {\r
400             // We were able to obtain the mutex and can now access the\r
401             // shared resource.\r
402 \r
403             // ...\r
404             // For some reason due to the nature of the code further calls to \r
405                         // xSemaphoreTakeRecursive() are made on the same mutex.  In real\r
406                         // code these would not be just sequential calls as this would make\r
407                         // no sense.  Instead the calls are likely to be buried inside\r
408                         // a more complex call structure.\r
409             xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
410             xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
411 \r
412             // The mutex has now been 'taken' three times, so will not be \r
413                         // available to another task until it has also been given back\r
414                         // three times.  Again it is unlikely that real code would have\r
415                         // these calls sequentially, it would be more likely that the calls\r
416                         // to xSemaphoreGiveRecursive() would be called as a call stack\r
417                         // unwound.  This is just for demonstrative purposes.\r
418             xSemaphoreGiveRecursive( xMutex );\r
419                         xSemaphoreGiveRecursive( xMutex );\r
420                         xSemaphoreGiveRecursive( xMutex );\r
421 \r
422                         // Now the mutex can be taken by other tasks.\r
423         }\r
424         else\r
425         {\r
426             // We could not obtain the mutex and can therefore not access\r
427             // the shared resource safely.\r
428         }\r
429     }\r
430  }\r
431  </pre>\r
432  * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive\r
433  * \ingroup Semaphores\r
434  */\r
435 #define xSemaphoreGiveRecursive( xMutex )       xQueueGiveMutexRecursive( xMutex )\r
436 \r
437 /* \r
438  * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().\r
439  *\r
440  * The source code that implements the alternative (Alt) API is much \r
441  * simpler      because it executes everything from within a critical section.  \r
442  * This is      the approach taken by many other RTOSes, but FreeRTOS.org has the \r
443  * preferred fully featured API too.  The fully featured API has more \r
444  * complex      code that takes longer to execute, but makes much less use of \r
445  * critical sections.  Therefore the alternative API sacrifices interrupt \r
446  * responsiveness to gain execution speed, whereas the fully featured API\r
447  * sacrifices execution speed to ensure better interrupt responsiveness.\r
448  */\r
449 #define xSemaphoreAltGive( xSemaphore )         xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
450 \r
451 /**\r
452  * semphr. h\r
453  * <pre>\r
454  xSemaphoreGiveFromISR( \r
455                           xSemaphoreHandle xSemaphore, \r
456                           portBASE_TYPE *pxHigherPriorityTaskWoken\r
457                       )</pre>\r
458  *\r
459  * <i>Macro</i> to  release a semaphore.  The semaphore must have previously been\r
460  * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().\r
461  *\r
462  * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())\r
463  * must not be used with this macro.\r
464  *\r
465  * This macro can be used from an ISR.\r
466  *\r
467  * @param xSemaphore A handle to the semaphore being released.  This is the\r
468  * handle returned when the semaphore was created.\r
469  *\r
470  * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set\r
471  * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task\r
472  * to unblock, and the unblocked task has a priority higher than the currently\r
473  * running task.  If xSemaphoreGiveFromISR() sets this value to pdTRUE then\r
474  * a context switch should be requested before the interrupt is exited.\r
475  *\r
476  * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.\r
477  *\r
478  * Example usage:\r
479  <pre>\r
480  #define LONG_TIME 0xffff\r
481  #define TICKS_TO_WAIT  10\r
482  xSemaphoreHandle xSemaphore = NULL;\r
483 \r
484  // Repetitive task.\r
485  void vATask( void * pvParameters )\r
486  {\r
487     for( ;; )\r
488     {\r
489         // We want this task to run every 10 ticks of a timer.  The semaphore \r
490         // was created before this task was started.\r
491 \r
492         // Block waiting for the semaphore to become available.\r
493         if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )\r
494         {\r
495             // It is time to execute.\r
496 \r
497             // ...\r
498 \r
499             // We have finished our task.  Return to the top of the loop where\r
500             // we will block on the semaphore until it is time to execute \r
501             // again.  Note when using the semaphore for synchronisation with an\r
502                         // ISR in this manner there is no need to 'give' the semaphore back.\r
503         }\r
504     }\r
505  }\r
506 \r
507  // Timer ISR\r
508  void vTimerISR( void * pvParameters )\r
509  {\r
510  static unsigned portCHAR ucLocalTickCount = 0;\r
511  static portBASE_TYPE xHigherPriorityTaskWoken;\r
512 \r
513     // A timer tick has occurred.\r
514 \r
515     // ... Do other time functions.\r
516 \r
517     // Is it time for vATask () to run?\r
518         xHigherPriorityTaskWoken = pdFALSE;\r
519     ucLocalTickCount++;\r
520     if( ucLocalTickCount >= TICKS_TO_WAIT )\r
521     {\r
522         // Unblock the task by releasing the semaphore.\r
523         xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );\r
524 \r
525         // Reset the count so we release the semaphore again in 10 ticks time.\r
526         ucLocalTickCount = 0;\r
527     }\r
528 \r
529     if( xHigherPriorityTaskWoken != pdFALSE )\r
530     {\r
531         // We can force a context switch here.  Context switching from an\r
532         // ISR uses port specific syntax.  Check the demo task for your port\r
533         // to find the syntax required.\r
534     }\r
535  }\r
536  </pre>\r
537  * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR\r
538  * \ingroup Semaphores\r
539  */\r
540 #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )                  xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )\r
541 \r
542 /**\r
543  * semphr. h\r
544  * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>\r
545  *\r
546  * <i>Macro</i> that implements a mutex semaphore by using the existing queue \r
547  * mechanism.\r
548  *\r
549  * Mutexes created using this macro can be accessed using the xSemaphoreTake()\r
550  * and xSemaphoreGive() macros.  The xSemaphoreTakeRecursive() and \r
551  * xSemaphoreGiveRecursive() macros should not be used.\r
552  * \r
553  * This type of semaphore uses a priority inheritance mechanism so a task \r
554  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the \r
555  * semaphore it is no longer required.  \r
556  *\r
557  * Mutex type semaphores cannot be used from within interrupt service routines.  \r
558  *\r
559  * See vSemaphoreCreateBinary() for an alternative implementation that can be \r
560  * used for pure synchronisation (where one task or interrupt always 'gives' the \r
561  * semaphore and another always 'takes' the semaphore) and from within interrupt \r
562  * service routines.\r
563  *\r
564  * @return xSemaphore Handle to the created mutex semaphore.  Should be of type \r
565  *              xSemaphoreHandle.\r
566  *\r
567  * Example usage:\r
568  <pre>\r
569  xSemaphoreHandle xSemaphore;\r
570 \r
571  void vATask( void * pvParameters )\r
572  {\r
573     // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
574     // This is a macro so pass the variable in directly.\r
575     xSemaphore = xSemaphoreCreateMutex();\r
576 \r
577     if( xSemaphore != NULL )\r
578     {\r
579         // The semaphore was created successfully.\r
580         // The semaphore can now be used.  \r
581     }\r
582  }\r
583  </pre>\r
584  * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
585  * \ingroup Semaphores\r
586  */\r
587 #define xSemaphoreCreateMutex() xQueueCreateMutex()\r
588 \r
589 \r
590 /**\r
591  * semphr. h\r
592  * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>\r
593  *\r
594  * <i>Macro</i> that implements a recursive mutex by using the existing queue \r
595  * mechanism.\r
596  *\r
597  * Mutexes created using this macro can be accessed using the \r
598  * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros.  The \r
599  * xSemaphoreTake() and xSemaphoreGive() macros should not be used.\r
600  *\r
601  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
602  * doesn't become available again until the owner has called \r
603  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example, \r
604  * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
605  * not be available to any other task until it has also  'given' the mutex back\r
606  * exactly five times.\r
607  * \r
608  * This type of semaphore uses a priority inheritance mechanism so a task \r
609  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the \r
610  * semaphore it is no longer required.  \r
611  *\r
612  * Mutex type semaphores cannot be used from within interrupt service routines.  \r
613  *\r
614  * See vSemaphoreCreateBinary() for an alternative implementation that can be \r
615  * used for pure synchronisation (where one task or interrupt always 'gives' the \r
616  * semaphore and another always 'takes' the semaphore) and from within interrupt \r
617  * service routines.\r
618  *\r
619  * @return xSemaphore Handle to the created mutex semaphore.  Should be of type \r
620  *              xSemaphoreHandle.\r
621  *\r
622  * Example usage:\r
623  <pre>\r
624  xSemaphoreHandle xSemaphore;\r
625 \r
626  void vATask( void * pvParameters )\r
627  {\r
628     // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
629     // This is a macro so pass the variable in directly.\r
630     xSemaphore = xSemaphoreCreateRecursiveMutex();\r
631 \r
632     if( xSemaphore != NULL )\r
633     {\r
634         // The semaphore was created successfully.\r
635         // The semaphore can now be used.  \r
636     }\r
637  }\r
638  </pre>\r
639  * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
640  * \ingroup Semaphores\r
641  */\r
642 #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()\r
643 \r
644 /**\r
645  * semphr. h\r
646  * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>\r
647  *\r
648  * <i>Macro</i> that creates a counting semaphore by using the existing \r
649  * queue mechanism.  \r
650  *\r
651  * Counting semaphores are typically used for two things:\r
652  *\r
653  * 1) Counting events.  \r
654  *\r
655  *    In this usage scenario an event handler will 'give' a semaphore each time\r
656  *    an event occurs (incrementing the semaphore count value), and a handler \r
657  *    task will 'take' a semaphore each time it processes an event \r
658  *    (decrementing the semaphore count value).  The count value is therefore \r
659  *    the difference between the number of events that have occurred and the \r
660  *    number that have been processed.  In this case it is desirable for the \r
661  *    initial count value to be zero.\r
662  *\r
663  * 2) Resource management.\r
664  *\r
665  *    In this usage scenario the count value indicates the number of resources\r
666  *    available.  To obtain control of a resource a task must first obtain a \r
667  *    semaphore - decrementing the semaphore count value.  When the count value\r
668  *    reaches zero there are no free resources.  When a task finishes with the\r
669  *    resource it 'gives' the semaphore back - incrementing the semaphore count\r
670  *    value.  In this case it is desirable for the initial count value to be\r
671  *    equal to the maximum count value, indicating that all resources are free.\r
672  *\r
673  * @param uxMaxCount The maximum count value that can be reached.  When the \r
674  *        semaphore reaches this value it can no longer be 'given'.\r
675  *\r
676  * @param uxInitialCount The count value assigned to the semaphore when it is\r
677  *        created.\r
678  *\r
679  * @return Handle to the created semaphore.  Null if the semaphore could not be\r
680  *         created.\r
681  * \r
682  * Example usage:\r
683  <pre>\r
684  xSemaphoreHandle xSemaphore;\r
685 \r
686  void vATask( void * pvParameters )\r
687  {\r
688  xSemaphoreHandle xSemaphore = NULL;\r
689 \r
690     // Semaphore cannot be used before a call to xSemaphoreCreateCounting().\r
691     // The max value to which the semaphore can count should be 10, and the\r
692     // initial value assigned to the count should be 0.\r
693     xSemaphore = xSemaphoreCreateCounting( 10, 0 );\r
694 \r
695     if( xSemaphore != NULL )\r
696     {\r
697         // The semaphore was created successfully.\r
698         // The semaphore can now be used.  \r
699     }\r
700  }\r
701  </pre>\r
702  * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting\r
703  * \ingroup Semaphores\r
704  */\r
705 #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )\r
706 \r
707 \r
708 #endif /* SEMAPHORE_H */\r
709 \r
710 \r