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