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