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