]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/include/semphr.h
Update version number in readiness for V10.3.0 release. Sync SVN with reviewed releas...
[freertos] / FreeRTOS / Source / include / semphr.h
1 /*\r
2  * FreeRTOS Kernel V10.3.0\r
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 #ifndef SEMAPHORE_H\r
29 #define SEMAPHORE_H\r
30 \r
31 #ifndef INC_FREERTOS_H\r
32         #error "include FreeRTOS.h" must appear in source files before "include semphr.h"\r
33 #endif\r
34 \r
35 #include "queue.h"\r
36 \r
37 typedef QueueHandle_t SemaphoreHandle_t;\r
38 \r
39 #define semBINARY_SEMAPHORE_QUEUE_LENGTH        ( ( uint8_t ) 1U )\r
40 #define semSEMAPHORE_QUEUE_ITEM_LENGTH          ( ( uint8_t ) 0U )\r
41 #define semGIVE_BLOCK_TIME                                      ( ( TickType_t ) 0U )\r
42 \r
43 \r
44 /**\r
45  * semphr. h\r
46  * <pre>vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )</pre>\r
47  *\r
48  * In many usage scenarios it is faster and more memory efficient to use a\r
49  * direct to task notification in place of a binary semaphore!\r
50  * http://www.freertos.org/RTOS-task-notifications.html\r
51  *\r
52  * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the\r
53  * xSemaphoreCreateBinary() function.  Note that binary semaphores created using\r
54  * the vSemaphoreCreateBinary() macro are created in a state such that the\r
55  * first call to 'take' the semaphore would pass, whereas binary semaphores\r
56  * created using xSemaphoreCreateBinary() are created in a state such that the\r
57  * the semaphore must first be 'given' before it can be 'taken'.\r
58  *\r
59  * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.\r
60  * The queue length is 1 as this is a binary semaphore.  The data size is 0\r
61  * as we don't want to actually store any data - we just want to know if the\r
62  * queue is empty or full.\r
63  *\r
64  * This type of semaphore can be used for pure synchronisation between tasks or\r
65  * between an interrupt and a task.  The semaphore need not be given back once\r
66  * obtained, so one task/interrupt can continuously 'give' the semaphore while\r
67  * another continuously 'takes' the semaphore.  For this reason this type of\r
68  * semaphore does not use a priority inheritance mechanism.  For an alternative\r
69  * that does use priority inheritance see xSemaphoreCreateMutex().\r
70  *\r
71  * @param xSemaphore Handle to the created semaphore.  Should be of type SemaphoreHandle_t.\r
72  *\r
73  * Example usage:\r
74  <pre>\r
75  SemaphoreHandle_t xSemaphore = NULL;\r
76 \r
77  void vATask( void * pvParameters )\r
78  {\r
79     // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().\r
80     // This is a macro so pass the variable in directly.\r
81     vSemaphoreCreateBinary( xSemaphore );\r
82 \r
83     if( xSemaphore != NULL )\r
84     {\r
85         // The semaphore was created successfully.\r
86         // The semaphore can now be used.\r
87     }\r
88  }\r
89  </pre>\r
90  * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary\r
91  * \ingroup Semaphores\r
92  */\r
93 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
94         #define vSemaphoreCreateBinary( xSemaphore )                                                                                                                                                                                    \\r
95                 {                                                                                                                                                                                                                                                                       \\r
96                         ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE );    \\r
97                         if( ( xSemaphore ) != NULL )                                                                                                                                                                                                    \\r
98                         {                                                                                                                                                                                                                                                               \\r
99                                 ( void ) xSemaphoreGive( ( xSemaphore ) );                                                                                                                                                                      \\r
100                         }                                                                                                                                                                                                                                                               \\r
101                 }\r
102 #endif\r
103 \r
104 /**\r
105  * semphr. h\r
106  * <pre>SemaphoreHandle_t xSemaphoreCreateBinary( void )</pre>\r
107  *\r
108  * Creates a new binary semaphore instance, and returns a handle by which the\r
109  * new semaphore can be referenced.\r
110  *\r
111  * In many usage scenarios it is faster and more memory efficient to use a\r
112  * direct to task notification in place of a binary semaphore!\r
113  * http://www.freertos.org/RTOS-task-notifications.html\r
114  *\r
115  * Internally, within the FreeRTOS implementation, binary semaphores use a block\r
116  * of memory, in which the semaphore structure is stored.  If a binary semaphore\r
117  * is created using xSemaphoreCreateBinary() then the required memory is\r
118  * automatically dynamically allocated inside the xSemaphoreCreateBinary()\r
119  * function.  (see http://www.freertos.org/a00111.html).  If a binary semaphore\r
120  * is created using xSemaphoreCreateBinaryStatic() then the application writer\r
121  * must provide the memory.  xSemaphoreCreateBinaryStatic() therefore allows a\r
122  * binary semaphore to be created without using any dynamic memory allocation.\r
123  *\r
124  * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this\r
125  * xSemaphoreCreateBinary() function.  Note that binary semaphores created using\r
126  * the vSemaphoreCreateBinary() macro are created in a state such that the\r
127  * first call to 'take' the semaphore would pass, whereas binary semaphores\r
128  * created using xSemaphoreCreateBinary() are created in a state such that the\r
129  * the semaphore must first be 'given' before it can be 'taken'.\r
130  *\r
131  * This type of semaphore can be used for pure synchronisation between tasks or\r
132  * between an interrupt and a task.  The semaphore need not be given back once\r
133  * obtained, so one task/interrupt can continuously 'give' the semaphore while\r
134  * another continuously 'takes' the semaphore.  For this reason this type of\r
135  * semaphore does not use a priority inheritance mechanism.  For an alternative\r
136  * that does use priority inheritance see xSemaphoreCreateMutex().\r
137  *\r
138  * @return Handle to the created semaphore, or NULL if the memory required to\r
139  * hold the semaphore's data structures could not be allocated.\r
140  *\r
141  * Example usage:\r
142  <pre>\r
143  SemaphoreHandle_t xSemaphore = NULL;\r
144 \r
145  void vATask( void * pvParameters )\r
146  {\r
147     // Semaphore cannot be used before a call to xSemaphoreCreateBinary().\r
148     // This is a macro so pass the variable in directly.\r
149     xSemaphore = xSemaphoreCreateBinary();\r
150 \r
151     if( xSemaphore != NULL )\r
152     {\r
153         // The semaphore was created successfully.\r
154         // The semaphore can now be used.\r
155     }\r
156  }\r
157  </pre>\r
158  * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary\r
159  * \ingroup Semaphores\r
160  */\r
161 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
162         #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )\r
163 #endif\r
164 \r
165 /**\r
166  * semphr. h\r
167  * <pre>SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )</pre>\r
168  *\r
169  * Creates a new binary semaphore instance, and returns a handle by which the\r
170  * new semaphore can be referenced.\r
171  *\r
172  * NOTE: In many usage scenarios it is faster and more memory efficient to use a\r
173  * direct to task notification in place of a binary semaphore!\r
174  * http://www.freertos.org/RTOS-task-notifications.html\r
175  *\r
176  * Internally, within the FreeRTOS implementation, binary semaphores use a block\r
177  * of memory, in which the semaphore structure is stored.  If a binary semaphore\r
178  * is created using xSemaphoreCreateBinary() then the required memory is\r
179  * automatically dynamically allocated inside the xSemaphoreCreateBinary()\r
180  * function.  (see http://www.freertos.org/a00111.html).  If a binary semaphore\r
181  * is created using xSemaphoreCreateBinaryStatic() then the application writer\r
182  * must provide the memory.  xSemaphoreCreateBinaryStatic() therefore allows a\r
183  * binary semaphore to be created without using any dynamic memory allocation.\r
184  *\r
185  * This type of semaphore can be used for pure synchronisation between tasks or\r
186  * between an interrupt and a task.  The semaphore need not be given back once\r
187  * obtained, so one task/interrupt can continuously 'give' the semaphore while\r
188  * another continuously 'takes' the semaphore.  For this reason this type of\r
189  * semaphore does not use a priority inheritance mechanism.  For an alternative\r
190  * that does use priority inheritance see xSemaphoreCreateMutex().\r
191  *\r
192  * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,\r
193  * which will then be used to hold the semaphore's data structure, removing the\r
194  * need for the memory to be allocated dynamically.\r
195  *\r
196  * @return If the semaphore is created then a handle to the created semaphore is\r
197  * returned.  If pxSemaphoreBuffer is NULL then NULL is returned.\r
198  *\r
199  * Example usage:\r
200  <pre>\r
201  SemaphoreHandle_t xSemaphore = NULL;\r
202  StaticSemaphore_t xSemaphoreBuffer;\r
203 \r
204  void vATask( void * pvParameters )\r
205  {\r
206     // Semaphore cannot be used before a call to xSemaphoreCreateBinary().\r
207     // The semaphore's data structures will be placed in the xSemaphoreBuffer\r
208     // variable, the address of which is passed into the function.  The\r
209     // function's parameter is not NULL, so the function will not attempt any\r
210     // dynamic memory allocation, and therefore the function will not return\r
211     // return NULL.\r
212     xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );\r
213 \r
214     // Rest of task code goes here.\r
215  }\r
216  </pre>\r
217  * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic\r
218  * \ingroup Semaphores\r
219  */\r
220 #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
221         #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE )\r
222 #endif /* configSUPPORT_STATIC_ALLOCATION */\r
223 \r
224 /**\r
225  * semphr. h\r
226  * <pre>xSemaphoreTake(\r
227  *                   SemaphoreHandle_t xSemaphore,\r
228  *                   TickType_t xBlockTime\r
229  *               )</pre>\r
230  *\r
231  * <i>Macro</i> to obtain a semaphore.  The semaphore must have previously been\r
232  * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
233  * xSemaphoreCreateCounting().\r
234  *\r
235  * @param xSemaphore A handle to the semaphore being taken - obtained when\r
236  * the semaphore was created.\r
237  *\r
238  * @param xBlockTime The time in ticks to wait for the semaphore to become\r
239  * available.  The macro portTICK_PERIOD_MS can be used to convert this to a\r
240  * real time.  A block time of zero can be used to poll the semaphore.  A block\r
241  * time of portMAX_DELAY can be used to block indefinitely (provided\r
242  * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).\r
243  *\r
244  * @return pdTRUE if the semaphore was obtained.  pdFALSE\r
245  * if xBlockTime expired without the semaphore becoming available.\r
246  *\r
247  * Example usage:\r
248  <pre>\r
249  SemaphoreHandle_t xSemaphore = NULL;\r
250 \r
251  // A task that creates a semaphore.\r
252  void vATask( void * pvParameters )\r
253  {\r
254     // Create the semaphore to guard a shared resource.\r
255     xSemaphore = xSemaphoreCreateBinary();\r
256  }\r
257 \r
258  // A task that uses the semaphore.\r
259  void vAnotherTask( void * pvParameters )\r
260  {\r
261     // ... Do other things.\r
262 \r
263     if( xSemaphore != NULL )\r
264     {\r
265         // See if we can obtain the semaphore.  If the semaphore is not available\r
266         // wait 10 ticks to see if it becomes free.\r
267         if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )\r
268         {\r
269             // We were able to obtain the semaphore and can now access the\r
270             // shared resource.\r
271 \r
272             // ...\r
273 \r
274             // We have finished accessing the shared resource.  Release the\r
275             // semaphore.\r
276             xSemaphoreGive( xSemaphore );\r
277         }\r
278         else\r
279         {\r
280             // We could not obtain the semaphore and can therefore not access\r
281             // the shared resource safely.\r
282         }\r
283     }\r
284  }\r
285  </pre>\r
286  * \defgroup xSemaphoreTake xSemaphoreTake\r
287  * \ingroup Semaphores\r
288  */\r
289 #define xSemaphoreTake( xSemaphore, xBlockTime )                xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )\r
290 \r
291 /**\r
292  * semphr. h\r
293  * xSemaphoreTakeRecursive(\r
294  *                          SemaphoreHandle_t xMutex,\r
295  *                          TickType_t xBlockTime\r
296  *                        )\r
297  *\r
298  * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.\r
299  * The mutex must have previously been created using a call to\r
300  * xSemaphoreCreateRecursiveMutex();\r
301  *\r
302  * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
303  * macro to be available.\r
304  *\r
305  * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
306  *\r
307  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex\r
308  * doesn't become available again until the owner has called\r
309  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,\r
310  * if a task successfully 'takes' the same mutex 5 times then the mutex will\r
311  * not be available to any other task until it has also  'given' the mutex back\r
312  * exactly five times.\r
313  *\r
314  * @param xMutex A handle to the mutex being obtained.  This is the\r
315  * handle returned by xSemaphoreCreateRecursiveMutex();\r
316  *\r
317  * @param xBlockTime The time in ticks to wait for the semaphore to become\r
318  * available.  The macro portTICK_PERIOD_MS can be used to convert this to a\r
319  * real time.  A block time of zero can be used to poll the semaphore.  If\r
320  * the task already owns the semaphore then xSemaphoreTakeRecursive() will\r
321  * return immediately no matter what the value of xBlockTime.\r
322  *\r
323  * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime\r
324  * expired without the semaphore becoming available.\r
325  *\r
326  * Example usage:\r
327  <pre>\r
328  SemaphoreHandle_t xMutex = NULL;\r
329 \r
330  // A task that creates a mutex.\r
331  void vATask( void * pvParameters )\r
332  {\r
333     // Create the mutex to guard a shared resource.\r
334     xMutex = xSemaphoreCreateRecursiveMutex();\r
335  }\r
336 \r
337  // A task that uses the mutex.\r
338  void vAnotherTask( void * pvParameters )\r
339  {\r
340     // ... Do other things.\r
341 \r
342     if( xMutex != NULL )\r
343     {\r
344         // See if we can obtain the mutex.  If the mutex is not available\r
345         // wait 10 ticks to see if it becomes free.\r
346         if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )\r
347         {\r
348             // We were able to obtain the mutex and can now access the\r
349             // shared resource.\r
350 \r
351             // ...\r
352             // For some reason due to the nature of the code further calls to\r
353             // xSemaphoreTakeRecursive() are made on the same mutex.  In real\r
354             // code these would not be just sequential calls as this would make\r
355             // no sense.  Instead the calls are likely to be buried inside\r
356             // a more complex call structure.\r
357             xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );\r
358             xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );\r
359 \r
360             // The mutex has now been 'taken' three times, so will not be\r
361             // available to another task until it has also been given back\r
362             // three times.  Again it is unlikely that real code would have\r
363             // these calls sequentially, but instead buried in a more complex\r
364             // call structure.  This is just for illustrative purposes.\r
365             xSemaphoreGiveRecursive( xMutex );\r
366             xSemaphoreGiveRecursive( xMutex );\r
367             xSemaphoreGiveRecursive( xMutex );\r
368 \r
369             // Now the mutex can be taken by other tasks.\r
370         }\r
371         else\r
372         {\r
373             // We could not obtain the mutex and can therefore not access\r
374             // the shared resource safely.\r
375         }\r
376     }\r
377  }\r
378  </pre>\r
379  * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive\r
380  * \ingroup Semaphores\r
381  */\r
382 #if( configUSE_RECURSIVE_MUTEXES == 1 )\r
383         #define xSemaphoreTakeRecursive( xMutex, xBlockTime )   xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )\r
384 #endif\r
385 \r
386 /**\r
387  * semphr. h\r
388  * <pre>xSemaphoreGive( SemaphoreHandle_t xSemaphore )</pre>\r
389  *\r
390  * <i>Macro</i> to release a semaphore.  The semaphore must have previously been\r
391  * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
392  * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().\r
393  *\r
394  * This macro must not be used from an ISR.  See xSemaphoreGiveFromISR () for\r
395  * an alternative which can be used from an ISR.\r
396  *\r
397  * This macro must also not be used on semaphores created using\r
398  * xSemaphoreCreateRecursiveMutex().\r
399  *\r
400  * @param xSemaphore A handle to the semaphore being released.  This is the\r
401  * handle returned when the semaphore was created.\r
402  *\r
403  * @return pdTRUE if the semaphore was released.  pdFALSE if an error occurred.\r
404  * Semaphores are implemented using queues.  An error can occur if there is\r
405  * no space on the queue to post a message - indicating that the\r
406  * semaphore was not first obtained correctly.\r
407  *\r
408  * Example usage:\r
409  <pre>\r
410  SemaphoreHandle_t xSemaphore = NULL;\r
411 \r
412  void vATask( void * pvParameters )\r
413  {\r
414     // Create the semaphore to guard a shared resource.\r
415     xSemaphore = vSemaphoreCreateBinary();\r
416 \r
417     if( xSemaphore != NULL )\r
418     {\r
419         if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
420         {\r
421             // We would expect this call to fail because we cannot give\r
422             // a semaphore without first "taking" it!\r
423         }\r
424 \r
425         // Obtain the semaphore - don't block if the semaphore is not\r
426         // immediately available.\r
427         if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )\r
428         {\r
429             // We now have the semaphore and can access the shared resource.\r
430 \r
431             // ...\r
432 \r
433             // We have finished accessing the shared resource so can free the\r
434             // semaphore.\r
435             if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
436             {\r
437                 // We would not expect this call to fail because we must have\r
438                 // obtained the semaphore to get here.\r
439             }\r
440         }\r
441     }\r
442  }\r
443  </pre>\r
444  * \defgroup xSemaphoreGive xSemaphoreGive\r
445  * \ingroup Semaphores\r
446  */\r
447 #define xSemaphoreGive( xSemaphore )            xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
448 \r
449 /**\r
450  * semphr. h\r
451  * <pre>xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )</pre>\r
452  *\r
453  * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.\r
454  * The mutex must have previously been created using a call to\r
455  * xSemaphoreCreateRecursiveMutex();\r
456  *\r
457  * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
458  * macro to be available.\r
459  *\r
460  * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
461  *\r
462  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex\r
463  * doesn't become available again until the owner has called\r
464  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,\r
465  * if a task successfully 'takes' the same mutex 5 times then the mutex will\r
466  * not be available to any other task until it has also  'given' the mutex back\r
467  * exactly five times.\r
468  *\r
469  * @param xMutex A handle to the mutex being released, or 'given'.  This is the\r
470  * handle returned by xSemaphoreCreateMutex();\r
471  *\r
472  * @return pdTRUE if the semaphore was given.\r
473  *\r
474  * Example usage:\r
475  <pre>\r
476  SemaphoreHandle_t xMutex = NULL;\r
477 \r
478  // A task that creates a mutex.\r
479  void vATask( void * pvParameters )\r
480  {\r
481     // Create the mutex to guard a shared resource.\r
482     xMutex = xSemaphoreCreateRecursiveMutex();\r
483  }\r
484 \r
485  // A task that uses the mutex.\r
486  void vAnotherTask( void * pvParameters )\r
487  {\r
488     // ... Do other things.\r
489 \r
490     if( xMutex != NULL )\r
491     {\r
492         // See if we can obtain the mutex.  If the mutex is not available\r
493         // wait 10 ticks to see if it becomes free.\r
494         if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )\r
495         {\r
496             // We were able to obtain the mutex and can now access the\r
497             // shared resource.\r
498 \r
499             // ...\r
500             // For some reason due to the nature of the code further calls to\r
501                         // xSemaphoreTakeRecursive() are made on the same mutex.  In real\r
502                         // code these would not be just sequential calls as this would make\r
503                         // no sense.  Instead the calls are likely to be buried inside\r
504                         // a more complex call structure.\r
505             xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );\r
506             xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );\r
507 \r
508             // The mutex has now been 'taken' three times, so will not be\r
509                         // available to another task until it has also been given back\r
510                         // three times.  Again it is unlikely that real code would have\r
511                         // these calls sequentially, it would be more likely that the calls\r
512                         // to xSemaphoreGiveRecursive() would be called as a call stack\r
513                         // unwound.  This is just for demonstrative purposes.\r
514             xSemaphoreGiveRecursive( xMutex );\r
515                         xSemaphoreGiveRecursive( xMutex );\r
516                         xSemaphoreGiveRecursive( xMutex );\r
517 \r
518                         // Now the mutex can be taken by other tasks.\r
519         }\r
520         else\r
521         {\r
522             // We could not obtain the mutex and can therefore not access\r
523             // the shared resource safely.\r
524         }\r
525     }\r
526  }\r
527  </pre>\r
528  * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive\r
529  * \ingroup Semaphores\r
530  */\r
531 #if( configUSE_RECURSIVE_MUTEXES == 1 )\r
532         #define xSemaphoreGiveRecursive( xMutex )       xQueueGiveMutexRecursive( ( xMutex ) )\r
533 #endif\r
534 \r
535 /**\r
536  * semphr. h\r
537  * <pre>\r
538  xSemaphoreGiveFromISR(\r
539                           SemaphoreHandle_t xSemaphore,\r
540                           BaseType_t *pxHigherPriorityTaskWoken\r
541                       )</pre>\r
542  *\r
543  * <i>Macro</i> to  release a semaphore.  The semaphore must have previously been\r
544  * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting().\r
545  *\r
546  * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())\r
547  * must not be used with this macro.\r
548  *\r
549  * This macro can be used from an ISR.\r
550  *\r
551  * @param xSemaphore A handle to the semaphore being released.  This is the\r
552  * handle returned when the semaphore was created.\r
553  *\r
554  * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set\r
555  * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task\r
556  * to unblock, and the unblocked task has a priority higher than the currently\r
557  * running task.  If xSemaphoreGiveFromISR() sets this value to pdTRUE then\r
558  * a context switch should be requested before the interrupt is exited.\r
559  *\r
560  * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.\r
561  *\r
562  * Example usage:\r
563  <pre>\r
564  \#define LONG_TIME 0xffff\r
565  \#define TICKS_TO_WAIT 10\r
566  SemaphoreHandle_t xSemaphore = NULL;\r
567 \r
568  // Repetitive task.\r
569  void vATask( void * pvParameters )\r
570  {\r
571     for( ;; )\r
572     {\r
573         // We want this task to run every 10 ticks of a timer.  The semaphore\r
574         // was created before this task was started.\r
575 \r
576         // Block waiting for the semaphore to become available.\r
577         if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )\r
578         {\r
579             // It is time to execute.\r
580 \r
581             // ...\r
582 \r
583             // We have finished our task.  Return to the top of the loop where\r
584             // we will block on the semaphore until it is time to execute\r
585             // again.  Note when using the semaphore for synchronisation with an\r
586                         // ISR in this manner there is no need to 'give' the semaphore back.\r
587         }\r
588     }\r
589  }\r
590 \r
591  // Timer ISR\r
592  void vTimerISR( void * pvParameters )\r
593  {\r
594  static uint8_t ucLocalTickCount = 0;\r
595  static BaseType_t xHigherPriorityTaskWoken;\r
596 \r
597     // A timer tick has occurred.\r
598 \r
599     // ... Do other time functions.\r
600 \r
601     // Is it time for vATask () to run?\r
602         xHigherPriorityTaskWoken = pdFALSE;\r
603     ucLocalTickCount++;\r
604     if( ucLocalTickCount >= TICKS_TO_WAIT )\r
605     {\r
606         // Unblock the task by releasing the semaphore.\r
607         xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );\r
608 \r
609         // Reset the count so we release the semaphore again in 10 ticks time.\r
610         ucLocalTickCount = 0;\r
611     }\r
612 \r
613     if( xHigherPriorityTaskWoken != pdFALSE )\r
614     {\r
615         // We can force a context switch here.  Context switching from an\r
616         // ISR uses port specific syntax.  Check the demo task for your port\r
617         // to find the syntax required.\r
618     }\r
619  }\r
620  </pre>\r
621  * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR\r
622  * \ingroup Semaphores\r
623  */\r
624 #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )  xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )\r
625 \r
626 /**\r
627  * semphr. h\r
628  * <pre>\r
629  xSemaphoreTakeFromISR(\r
630                           SemaphoreHandle_t xSemaphore,\r
631                           BaseType_t *pxHigherPriorityTaskWoken\r
632                       )</pre>\r
633  *\r
634  * <i>Macro</i> to  take a semaphore from an ISR.  The semaphore must have\r
635  * previously been created with a call to xSemaphoreCreateBinary() or\r
636  * xSemaphoreCreateCounting().\r
637  *\r
638  * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())\r
639  * must not be used with this macro.\r
640  *\r
641  * This macro can be used from an ISR, however taking a semaphore from an ISR\r
642  * is not a common operation.  It is likely to only be useful when taking a\r
643  * counting semaphore when an interrupt is obtaining an object from a resource\r
644  * pool (when the semaphore count indicates the number of resources available).\r
645  *\r
646  * @param xSemaphore A handle to the semaphore being taken.  This is the\r
647  * handle returned when the semaphore was created.\r
648  *\r
649  * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set\r
650  * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task\r
651  * to unblock, and the unblocked task has a priority higher than the currently\r
652  * running task.  If xSemaphoreTakeFromISR() sets this value to pdTRUE then\r
653  * a context switch should be requested before the interrupt is exited.\r
654  *\r
655  * @return pdTRUE if the semaphore was successfully taken, otherwise\r
656  * pdFALSE\r
657  */\r
658 #define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )  xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )\r
659 \r
660 /**\r
661  * semphr. h\r
662  * <pre>SemaphoreHandle_t xSemaphoreCreateMutex( void )</pre>\r
663  *\r
664  * Creates a new mutex type semaphore instance, and returns a handle by which\r
665  * the new mutex can be referenced.\r
666  *\r
667  * Internally, within the FreeRTOS implementation, mutex semaphores use a block\r
668  * of memory, in which the mutex structure is stored.  If a mutex is created\r
669  * using xSemaphoreCreateMutex() then the required memory is automatically\r
670  * dynamically allocated inside the xSemaphoreCreateMutex() function.  (see\r
671  * http://www.freertos.org/a00111.html).  If a mutex is created using\r
672  * xSemaphoreCreateMutexStatic() then the application writer must provided the\r
673  * memory.  xSemaphoreCreateMutexStatic() therefore allows a mutex to be created\r
674  * without using any dynamic memory allocation.\r
675  *\r
676  * Mutexes created using this function can be accessed using the xSemaphoreTake()\r
677  * and xSemaphoreGive() macros.  The xSemaphoreTakeRecursive() and\r
678  * xSemaphoreGiveRecursive() macros must not be used.\r
679  *\r
680  * This type of semaphore uses a priority inheritance mechanism so a task\r
681  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the\r
682  * semaphore it is no longer required.\r
683  *\r
684  * Mutex type semaphores cannot be used from within interrupt service routines.\r
685  *\r
686  * See xSemaphoreCreateBinary() for an alternative implementation that can be\r
687  * used for pure synchronisation (where one task or interrupt always 'gives' the\r
688  * semaphore and another always 'takes' the semaphore) and from within interrupt\r
689  * service routines.\r
690  *\r
691  * @return If the mutex was successfully created then a handle to the created\r
692  * semaphore is returned.  If there was not enough heap to allocate the mutex\r
693  * data structures then NULL is returned.\r
694  *\r
695  * Example usage:\r
696  <pre>\r
697  SemaphoreHandle_t xSemaphore;\r
698 \r
699  void vATask( void * pvParameters )\r
700  {\r
701     // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
702     // This is a macro so pass the variable in directly.\r
703     xSemaphore = xSemaphoreCreateMutex();\r
704 \r
705     if( xSemaphore != NULL )\r
706     {\r
707         // The semaphore was created successfully.\r
708         // The semaphore can now be used.\r
709     }\r
710  }\r
711  </pre>\r
712  * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex\r
713  * \ingroup Semaphores\r
714  */\r
715 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
716         #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )\r
717 #endif\r
718 \r
719 /**\r
720  * semphr. h\r
721  * <pre>SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )</pre>\r
722  *\r
723  * Creates a new mutex type semaphore instance, and returns a handle by which\r
724  * the new mutex can be referenced.\r
725  *\r
726  * Internally, within the FreeRTOS implementation, mutex semaphores use a block\r
727  * of memory, in which the mutex structure is stored.  If a mutex is created\r
728  * using xSemaphoreCreateMutex() then the required memory is automatically\r
729  * dynamically allocated inside the xSemaphoreCreateMutex() function.  (see\r
730  * http://www.freertos.org/a00111.html).  If a mutex is created using\r
731  * xSemaphoreCreateMutexStatic() then the application writer must provided the\r
732  * memory.  xSemaphoreCreateMutexStatic() therefore allows a mutex to be created\r
733  * without using any dynamic memory allocation.\r
734  *\r
735  * Mutexes created using this function can be accessed using the xSemaphoreTake()\r
736  * and xSemaphoreGive() macros.  The xSemaphoreTakeRecursive() and\r
737  * xSemaphoreGiveRecursive() macros must not be used.\r
738  *\r
739  * This type of semaphore uses a priority inheritance mechanism so a task\r
740  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the\r
741  * semaphore it is no longer required.\r
742  *\r
743  * Mutex type semaphores cannot be used from within interrupt service routines.\r
744  *\r
745  * See xSemaphoreCreateBinary() for an alternative implementation that can be\r
746  * used for pure synchronisation (where one task or interrupt always 'gives' the\r
747  * semaphore and another always 'takes' the semaphore) and from within interrupt\r
748  * service routines.\r
749  *\r
750  * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,\r
751  * which will be used to hold the mutex's data structure, removing the need for\r
752  * the memory to be allocated dynamically.\r
753  *\r
754  * @return If the mutex was successfully created then a handle to the created\r
755  * mutex is returned.  If pxMutexBuffer was NULL then NULL is returned.\r
756  *\r
757  * Example usage:\r
758  <pre>\r
759  SemaphoreHandle_t xSemaphore;\r
760  StaticSemaphore_t xMutexBuffer;\r
761 \r
762  void vATask( void * pvParameters )\r
763  {\r
764     // A mutex cannot be used before it has been created.  xMutexBuffer is\r
765     // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is\r
766     // attempted.\r
767     xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );\r
768 \r
769     // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,\r
770     // so there is no need to check it.\r
771  }\r
772  </pre>\r
773  * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic\r
774  * \ingroup Semaphores\r
775  */\r
776  #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
777         #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) )\r
778 #endif /* configSUPPORT_STATIC_ALLOCATION */\r
779 \r
780 \r
781 /**\r
782  * semphr. h\r
783  * <pre>SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )</pre>\r
784  *\r
785  * Creates a new recursive mutex type semaphore instance, and returns a handle\r
786  * by which the new recursive mutex can be referenced.\r
787  *\r
788  * Internally, within the FreeRTOS implementation, recursive mutexs use a block\r
789  * of memory, in which the mutex structure is stored.  If a recursive mutex is\r
790  * created using xSemaphoreCreateRecursiveMutex() then the required memory is\r
791  * automatically dynamically allocated inside the\r
792  * xSemaphoreCreateRecursiveMutex() function.  (see\r
793  * http://www.freertos.org/a00111.html).  If a recursive mutex is created using\r
794  * xSemaphoreCreateRecursiveMutexStatic() then the application writer must\r
795  * provide the memory that will get used by the mutex.\r
796  * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to\r
797  * be created without using any dynamic memory allocation.\r
798  *\r
799  * Mutexes created using this macro can be accessed using the\r
800  * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros.  The\r
801  * xSemaphoreTake() and xSemaphoreGive() macros must not be used.\r
802  *\r
803  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex\r
804  * doesn't become available again until the owner has called\r
805  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,\r
806  * if a task successfully 'takes' the same mutex 5 times then the mutex will\r
807  * not be available to any other task until it has also  'given' the mutex back\r
808  * exactly five times.\r
809  *\r
810  * This type of semaphore uses a priority inheritance mechanism so a task\r
811  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the\r
812  * semaphore it is no longer required.\r
813  *\r
814  * Mutex type semaphores cannot be used from within interrupt service routines.\r
815  *\r
816  * See xSemaphoreCreateBinary() for an alternative implementation that can be\r
817  * used for pure synchronisation (where one task or interrupt always 'gives' the\r
818  * semaphore and another always 'takes' the semaphore) and from within interrupt\r
819  * service routines.\r
820  *\r
821  * @return xSemaphore Handle to the created mutex semaphore.  Should be of type\r
822  * SemaphoreHandle_t.\r
823  *\r
824  * Example usage:\r
825  <pre>\r
826  SemaphoreHandle_t xSemaphore;\r
827 \r
828  void vATask( void * pvParameters )\r
829  {\r
830     // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
831     // This is a macro so pass the variable in directly.\r
832     xSemaphore = xSemaphoreCreateRecursiveMutex();\r
833 \r
834     if( xSemaphore != NULL )\r
835     {\r
836         // The semaphore was created successfully.\r
837         // The semaphore can now be used.\r
838     }\r
839  }\r
840  </pre>\r
841  * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex\r
842  * \ingroup Semaphores\r
843  */\r
844 #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )\r
845         #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )\r
846 #endif\r
847 \r
848 /**\r
849  * semphr. h\r
850  * <pre>SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )</pre>\r
851  *\r
852  * Creates a new recursive mutex type semaphore instance, and returns a handle\r
853  * by which the new recursive mutex can be referenced.\r
854  *\r
855  * Internally, within the FreeRTOS implementation, recursive mutexs use a block\r
856  * of memory, in which the mutex structure is stored.  If a recursive mutex is\r
857  * created using xSemaphoreCreateRecursiveMutex() then the required memory is\r
858  * automatically dynamically allocated inside the\r
859  * xSemaphoreCreateRecursiveMutex() function.  (see\r
860  * http://www.freertos.org/a00111.html).  If a recursive mutex is created using\r
861  * xSemaphoreCreateRecursiveMutexStatic() then the application writer must\r
862  * provide the memory that will get used by the mutex.\r
863  * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to\r
864  * be created without using any dynamic memory allocation.\r
865  *\r
866  * Mutexes created using this macro can be accessed using the\r
867  * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros.  The\r
868  * xSemaphoreTake() and xSemaphoreGive() macros must not be used.\r
869  *\r
870  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex\r
871  * doesn't become available again until the owner has called\r
872  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,\r
873  * if a task successfully 'takes' the same mutex 5 times then the mutex will\r
874  * not be available to any other task until it has also  'given' the mutex back\r
875  * exactly five times.\r
876  *\r
877  * This type of semaphore uses a priority inheritance mechanism so a task\r
878  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the\r
879  * semaphore it is no longer required.\r
880  *\r
881  * Mutex type semaphores cannot be used from within interrupt service routines.\r
882  *\r
883  * See xSemaphoreCreateBinary() for an alternative implementation that can be\r
884  * used for pure synchronisation (where one task or interrupt always 'gives' the\r
885  * semaphore and another always 'takes' the semaphore) and from within interrupt\r
886  * service routines.\r
887  *\r
888  * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,\r
889  * which will then be used to hold the recursive mutex's data structure,\r
890  * removing the need for the memory to be allocated dynamically.\r
891  *\r
892  * @return If the recursive mutex was successfully created then a handle to the\r
893  * created recursive mutex is returned.  If pxMutexBuffer was NULL then NULL is\r
894  * returned.\r
895  *\r
896  * Example usage:\r
897  <pre>\r
898  SemaphoreHandle_t xSemaphore;\r
899  StaticSemaphore_t xMutexBuffer;\r
900 \r
901  void vATask( void * pvParameters )\r
902  {\r
903     // A recursive semaphore cannot be used before it is created.  Here a\r
904     // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().\r
905     // The address of xMutexBuffer is passed into the function, and will hold\r
906     // the mutexes data structures - so no dynamic memory allocation will be\r
907     // attempted.\r
908     xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );\r
909 \r
910     // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,\r
911     // so there is no need to check it.\r
912  }\r
913  </pre>\r
914  * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic\r
915  * \ingroup Semaphores\r
916  */\r
917 #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )\r
918         #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore )\r
919 #endif /* configSUPPORT_STATIC_ALLOCATION */\r
920 \r
921 /**\r
922  * semphr. h\r
923  * <pre>SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )</pre>\r
924  *\r
925  * Creates a new counting semaphore instance, and returns a handle by which the\r
926  * new counting semaphore can be referenced.\r
927  *\r
928  * In many usage scenarios it is faster and more memory efficient to use a\r
929  * direct to task notification in place of a counting semaphore!\r
930  * http://www.freertos.org/RTOS-task-notifications.html\r
931  *\r
932  * Internally, within the FreeRTOS implementation, counting semaphores use a\r
933  * block of memory, in which the counting semaphore structure is stored.  If a\r
934  * counting semaphore is created using xSemaphoreCreateCounting() then the\r
935  * required memory is automatically dynamically allocated inside the\r
936  * xSemaphoreCreateCounting() function.  (see\r
937  * http://www.freertos.org/a00111.html).  If a counting semaphore is created\r
938  * using xSemaphoreCreateCountingStatic() then the application writer can\r
939  * instead optionally provide the memory that will get used by the counting\r
940  * semaphore.  xSemaphoreCreateCountingStatic() therefore allows a counting\r
941  * semaphore to be created without using any dynamic memory allocation.\r
942  *\r
943  * Counting semaphores are typically used for two things:\r
944  *\r
945  * 1) Counting events.\r
946  *\r
947  *    In this usage scenario an event handler will 'give' a semaphore each time\r
948  *    an event occurs (incrementing the semaphore count value), and a handler\r
949  *    task will 'take' a semaphore each time it processes an event\r
950  *    (decrementing the semaphore count value).  The count value is therefore\r
951  *    the difference between the number of events that have occurred and the\r
952  *    number that have been processed.  In this case it is desirable for the\r
953  *    initial count value to be zero.\r
954  *\r
955  * 2) Resource management.\r
956  *\r
957  *    In this usage scenario the count value indicates the number of resources\r
958  *    available.  To obtain control of a resource a task must first obtain a\r
959  *    semaphore - decrementing the semaphore count value.  When the count value\r
960  *    reaches zero there are no free resources.  When a task finishes with the\r
961  *    resource it 'gives' the semaphore back - incrementing the semaphore count\r
962  *    value.  In this case it is desirable for the initial count value to be\r
963  *    equal to the maximum count value, indicating that all resources are free.\r
964  *\r
965  * @param uxMaxCount The maximum count value that can be reached.  When the\r
966  *        semaphore reaches this value it can no longer be 'given'.\r
967  *\r
968  * @param uxInitialCount The count value assigned to the semaphore when it is\r
969  *        created.\r
970  *\r
971  * @return Handle to the created semaphore.  Null if the semaphore could not be\r
972  *         created.\r
973  *\r
974  * Example usage:\r
975  <pre>\r
976  SemaphoreHandle_t xSemaphore;\r
977 \r
978  void vATask( void * pvParameters )\r
979  {\r
980  SemaphoreHandle_t xSemaphore = NULL;\r
981 \r
982     // Semaphore cannot be used before a call to xSemaphoreCreateCounting().\r
983     // The max value to which the semaphore can count should be 10, and the\r
984     // initial value assigned to the count should be 0.\r
985     xSemaphore = xSemaphoreCreateCounting( 10, 0 );\r
986 \r
987     if( xSemaphore != NULL )\r
988     {\r
989         // The semaphore was created successfully.\r
990         // The semaphore can now be used.\r
991     }\r
992  }\r
993  </pre>\r
994  * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting\r
995  * \ingroup Semaphores\r
996  */\r
997 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
998         #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )\r
999 #endif\r
1000 \r
1001 /**\r
1002  * semphr. h\r
1003  * <pre>SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )</pre>\r
1004  *\r
1005  * Creates a new counting semaphore instance, and returns a handle by which the\r
1006  * new counting semaphore can be referenced.\r
1007  *\r
1008  * In many usage scenarios it is faster and more memory efficient to use a\r
1009  * direct to task notification in place of a counting semaphore!\r
1010  * http://www.freertos.org/RTOS-task-notifications.html\r
1011  *\r
1012  * Internally, within the FreeRTOS implementation, counting semaphores use a\r
1013  * block of memory, in which the counting semaphore structure is stored.  If a\r
1014  * counting semaphore is created using xSemaphoreCreateCounting() then the\r
1015  * required memory is automatically dynamically allocated inside the\r
1016  * xSemaphoreCreateCounting() function.  (see\r
1017  * http://www.freertos.org/a00111.html).  If a counting semaphore is created\r
1018  * using xSemaphoreCreateCountingStatic() then the application writer must\r
1019  * provide the memory.  xSemaphoreCreateCountingStatic() therefore allows a\r
1020  * counting semaphore to be created without using any dynamic memory allocation.\r
1021  *\r
1022  * Counting semaphores are typically used for two things:\r
1023  *\r
1024  * 1) Counting events.\r
1025  *\r
1026  *    In this usage scenario an event handler will 'give' a semaphore each time\r
1027  *    an event occurs (incrementing the semaphore count value), and a handler\r
1028  *    task will 'take' a semaphore each time it processes an event\r
1029  *    (decrementing the semaphore count value).  The count value is therefore\r
1030  *    the difference between the number of events that have occurred and the\r
1031  *    number that have been processed.  In this case it is desirable for the\r
1032  *    initial count value to be zero.\r
1033  *\r
1034  * 2) Resource management.\r
1035  *\r
1036  *    In this usage scenario the count value indicates the number of resources\r
1037  *    available.  To obtain control of a resource a task must first obtain a\r
1038  *    semaphore - decrementing the semaphore count value.  When the count value\r
1039  *    reaches zero there are no free resources.  When a task finishes with the\r
1040  *    resource it 'gives' the semaphore back - incrementing the semaphore count\r
1041  *    value.  In this case it is desirable for the initial count value to be\r
1042  *    equal to the maximum count value, indicating that all resources are free.\r
1043  *\r
1044  * @param uxMaxCount The maximum count value that can be reached.  When the\r
1045  *        semaphore reaches this value it can no longer be 'given'.\r
1046  *\r
1047  * @param uxInitialCount The count value assigned to the semaphore when it is\r
1048  *        created.\r
1049  *\r
1050  * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,\r
1051  * which will then be used to hold the semaphore's data structure, removing the\r
1052  * need for the memory to be allocated dynamically.\r
1053  *\r
1054  * @return If the counting semaphore was successfully created then a handle to\r
1055  * the created counting semaphore is returned.  If pxSemaphoreBuffer was NULL\r
1056  * then NULL is returned.\r
1057  *\r
1058  * Example usage:\r
1059  <pre>\r
1060  SemaphoreHandle_t xSemaphore;\r
1061  StaticSemaphore_t xSemaphoreBuffer;\r
1062 \r
1063  void vATask( void * pvParameters )\r
1064  {\r
1065  SemaphoreHandle_t xSemaphore = NULL;\r
1066 \r
1067     // Counting semaphore cannot be used before they have been created.  Create\r
1068     // a counting semaphore using xSemaphoreCreateCountingStatic().  The max\r
1069     // value to which the semaphore can count is 10, and the initial value\r
1070     // assigned to the count will be 0.  The address of xSemaphoreBuffer is\r
1071     // passed in and will be used to hold the semaphore structure, so no dynamic\r
1072     // memory allocation will be used.\r
1073     xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );\r
1074 \r
1075     // No memory allocation was attempted so xSemaphore cannot be NULL, so there\r
1076     // is no need to check its value.\r
1077  }\r
1078  </pre>\r
1079  * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic\r
1080  * \ingroup Semaphores\r
1081  */\r
1082 #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
1083         #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) )\r
1084 #endif /* configSUPPORT_STATIC_ALLOCATION */\r
1085 \r
1086 /**\r
1087  * semphr. h\r
1088  * <pre>void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );</pre>\r
1089  *\r
1090  * Delete a semaphore.  This function must be used with care.  For example,\r
1091  * do not delete a mutex type semaphore if the mutex is held by a task.\r
1092  *\r
1093  * @param xSemaphore A handle to the semaphore to be deleted.\r
1094  *\r
1095  * \defgroup vSemaphoreDelete vSemaphoreDelete\r
1096  * \ingroup Semaphores\r
1097  */\r
1098 #define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )\r
1099 \r
1100 /**\r
1101  * semphr.h\r
1102  * <pre>TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );</pre>\r
1103  *\r
1104  * If xMutex is indeed a mutex type semaphore, return the current mutex holder.\r
1105  * If xMutex is not a mutex type semaphore, or the mutex is available (not held\r
1106  * by a task), return NULL.\r
1107  *\r
1108  * Note: This is a good way of determining if the calling task is the mutex\r
1109  * holder, but not a good way of determining the identity of the mutex holder as\r
1110  * the holder may change between the function exiting and the returned value\r
1111  * being tested.\r
1112  */\r
1113 #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )\r
1114 \r
1115 /**\r
1116  * semphr.h\r
1117  * <pre>TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );</pre>\r
1118  *\r
1119  * If xMutex is indeed a mutex type semaphore, return the current mutex holder.\r
1120  * If xMutex is not a mutex type semaphore, or the mutex is available (not held\r
1121  * by a task), return NULL.\r
1122  *\r
1123  */\r
1124 #define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) )\r
1125 \r
1126 /**\r
1127  * semphr.h\r
1128  * <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre>\r
1129  *\r
1130  * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns\r
1131  * its current count value.  If the semaphore is a binary semaphore then\r
1132  * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the\r
1133  * semaphore is not available.\r
1134  *\r
1135  */\r
1136 #define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )\r
1137 \r
1138 #endif /* SEMAPHORE_H */\r
1139 \r
1140 \r