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