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