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