]> git.sur5r.net Git - freertos/blob - Source/include/semphr.h
Ensure the first task starts with interrupts enabled.
[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!  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                           portSHORT sTaskPreviouslyWoken \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 sTaskPreviouslyWoken This is included so an ISR can make multiple calls\r
464  * to xSemaphoreGiveFromISR () from a single interrupt.  The first call\r
465  * should always pass in pdFALSE.  Subsequent calls should pass in\r
466  * the value returned from the previous call.  See the file serial .c in the\r
467  * PC port for a good example of using xSemaphoreGiveFromISR ().\r
468  *\r
469  * @return pdTRUE if a task was woken by releasing the semaphore.  This is \r
470  * used by the ISR to determine if a context switch may be required following\r
471  * the ISR.\r
472  *\r
473  * Example usage:\r
474  <pre>\r
475  #define LONG_TIME 0xffff\r
476  #define TICKS_TO_WAIT  10\r
477  xSemaphoreHandle xSemaphore = NULL;\r
478 \r
479  // Repetitive task.\r
480  void vATask( void * pvParameters )\r
481  {\r
482     for( ;; )\r
483     {\r
484         // We want this task to run every 10 ticks of a timer.  The semaphore \r
485         // was created before this task was started.\r
486 \r
487         // Block waiting for the semaphore to become available.\r
488         if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )\r
489         {\r
490             // It is time to execute.\r
491 \r
492             // ...\r
493 \r
494             // We have finished our task.  Return to the top of the loop where\r
495             // we will block on the semaphore until it is time to execute \r
496             // again.  Note when using the semaphore for synchronisation with an\r
497                         // ISR in this manner there is no need to 'give' the semaphore back.\r
498         }\r
499     }\r
500  }\r
501 \r
502  // Timer ISR\r
503  void vTimerISR( void * pvParameters )\r
504  {\r
505  static unsigned portCHAR ucLocalTickCount = 0;\r
506  static portBASE_TYPE xTaskWoken;\r
507 \r
508     // A timer tick has occurred.\r
509 \r
510     // ... Do other time functions.\r
511 \r
512     // Is it time for vATask () to run?\r
513         xTaskWoken = pdFALSE;\r
514     ucLocalTickCount++;\r
515     if( ucLocalTickCount >= TICKS_TO_WAIT )\r
516     {\r
517         // Unblock the task by releasing the semaphore.\r
518         xTaskWoken = xSemaphoreGiveFromISR( xSemaphore, xTaskWoken );\r
519 \r
520         // Reset the count so we release the semaphore again in 10 ticks time.\r
521         ucLocalTickCount = 0;\r
522     }\r
523 \r
524     if( xTaskWoken != pdFALSE )\r
525     {\r
526         // We can force a context switch here.  Context switching from an\r
527         // ISR uses port specific syntax.  Check the demo task for your port\r
528         // to find the syntax required.\r
529     }\r
530  }\r
531  </pre>\r
532  * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR\r
533  * \ingroup Semaphores\r
534  */\r
535 #define xSemaphoreGiveFromISR( xSemaphore, xTaskPreviouslyWoken )                       xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, xTaskPreviouslyWoken, queueSEND_TO_BACK )\r
536 \r
537 /**\r
538  * semphr. h\r
539  * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>\r
540  *\r
541  * <i>Macro</i> that implements a mutex semaphore by using the existing queue \r
542  * mechanism.\r
543  *\r
544  * Mutexes created using this macro can be accessed using the xSemaphoreTake()\r
545  * and xSemaphoreGive() macros.  The xSemaphoreTakeRecursive() and \r
546  * xSemaphoreGiveRecursive() macros should not be used.\r
547  * \r
548  * This type of semaphore uses a priority inheritance mechanism so a task \r
549  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the \r
550  * semaphore it is no longer required.  \r
551  *\r
552  * Mutex type semaphores cannot be used from within interrupt service routines.  \r
553  *\r
554  * See xSemaphoreCreateBinary() for an alternative implementation that can be \r
555  * used for pure synchronisation (where one task or interrupt always 'gives' the \r
556  * semaphore and another always 'takes' the semaphore) and from within interrupt \r
557  * service routines.\r
558  *\r
559  * @return xSemaphore Handle to the created mutex semaphore.  Should be of type \r
560  *              xSemaphoreHandle.\r
561  *\r
562  * Example usage:\r
563  <pre>\r
564  xSemaphoreHandle xSemaphore;\r
565 \r
566  void vATask( void * pvParameters )\r
567  {\r
568     // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
569     // This is a macro so pass the variable in directly.\r
570     xSemaphore = xSemaphoreCreateMutex();\r
571 \r
572     if( xSemaphore != NULL )\r
573     {\r
574         // The semaphore was created successfully.\r
575         // The semaphore can now be used.  \r
576     }\r
577  }\r
578  </pre>\r
579  * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
580  * \ingroup Semaphores\r
581  */\r
582 #define xSemaphoreCreateMutex() xQueueCreateMutex()\r
583 \r
584 \r
585 /**\r
586  * semphr. h\r
587  * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>\r
588  *\r
589  * <i>Macro</i> that implements a recursive mutex by using the existing queue \r
590  * mechanism.\r
591  *\r
592  * Mutexes created using this macro can be accessed using the \r
593  * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros.  The \r
594  * xSemaphoreTake() and xSemaphoreGive() macros should not be used.\r
595  *\r
596  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
597  * doesn't become available again until the owner has called \r
598  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example, \r
599  * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
600  * not be available to any other task until it has also  'given' the mutex back\r
601  * exactly five times.\r
602  * \r
603  * This type of semaphore uses a priority inheritance mechanism so a task \r
604  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the \r
605  * semaphore it is no longer required.  \r
606  *\r
607  * Mutex type semaphores cannot be used from within interrupt service routines.  \r
608  *\r
609  * See xSemaphoreCreateBinary() for an alternative implementation that can be \r
610  * used for pure synchronisation (where one task or interrupt always 'gives' the \r
611  * semaphore and another always 'takes' the semaphore) and from within interrupt \r
612  * service routines.\r
613  *\r
614  * @return xSemaphore Handle to the created mutex semaphore.  Should be of type \r
615  *              xSemaphoreHandle.\r
616  *\r
617  * Example usage:\r
618  <pre>\r
619  xSemaphoreHandle xSemaphore;\r
620 \r
621  void vATask( void * pvParameters )\r
622  {\r
623     // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
624     // This is a macro so pass the variable in directly.\r
625     xSemaphore = xSemaphoreCreateRecursiveMutex();\r
626 \r
627     if( xSemaphore != NULL )\r
628     {\r
629         // The semaphore was created successfully.\r
630         // The semaphore can now be used.  \r
631     }\r
632  }\r
633  </pre>\r
634  * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
635  * \ingroup Semaphores\r
636  */\r
637 #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()\r
638 \r
639 /**\r
640  * semphr. h\r
641  * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>\r
642  *\r
643  * <i>Macro</i> that creates a counting semaphore by using the existing \r
644  * queue mechanism.  \r
645  *\r
646  * Counting semaphores are typically used for two things:\r
647  *\r
648  * 1) Counting events.  \r
649  *\r
650  *    In this usage scenario an event handler will 'give' a semaphore each time\r
651  *    an event occurs (incrementing the semaphore count value), and a handler \r
652  *    task will 'take' a semaphore each time it processes an event \r
653  *    (decrementing the semaphore count value).  The count value is therefore \r
654  *    the difference between the number of events that have occurred and the \r
655  *    number that have been processed.  In this case it is desirable for the \r
656  *    initial count value to be zero.\r
657  *\r
658  * 2) Resource management.\r
659  *\r
660  *    In this usage scenario the count value indicates the number of resources\r
661  *    available.  To obtain control of a resource a task must first obtain a \r
662  *    semaphore - decrementing the semaphore count value.  When the count value\r
663  *    reaches zero there are no free resources.  When a task finishes with the\r
664  *    resource it 'gives' the semaphore back - incrementing the semaphore count\r
665  *    value.  In this case it is desirable for the initial count value to be\r
666  *    equal to the maximum count value, indicating that all resources are free.\r
667  *\r
668  * @param uxMaxCount The maximum count value that can be reached.  When the \r
669  *        semaphore reaches this value it can no longer be 'given'.\r
670  *\r
671  * @param uxInitialCount The count value assigned to the semaphore when it is\r
672  *        created.\r
673  *\r
674  * @return Handle to the created semaphore.  Null if the semaphore could not be\r
675  *         created.\r
676  * \r
677  * Example usage:\r
678  <pre>\r
679  xSemaphoreHandle xSemaphore;\r
680 \r
681  void vATask( void * pvParameters )\r
682  {\r
683  xSemaphoreHandle xSemaphore = NULL;\r
684 \r
685     // Semaphore cannot be used before a call to xSemaphoreCreateCounting().\r
686     // The max value to which the semaphore can count should be 10, and the\r
687     // initial value assigned to the count should be 0.\r
688     xSemaphore = xSemaphoreCreateCounting( 10, 0 );\r
689 \r
690     if( xSemaphore != NULL )\r
691     {\r
692         // The semaphore was created successfully.\r
693         // The semaphore can now be used.  \r
694     }\r
695  }\r
696  </pre>\r
697  * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting\r
698  * \ingroup Semaphores\r
699  */\r
700 #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )\r
701 \r
702 \r
703 #endif /* SEMAPHORE_H */\r
704 \r
705 \r