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