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