FreeRTOS
[armadillo_firmware.git] / FreeRTOS / Source / include / semphr.h
blob28b2ab120e83ec55f98403efeeccdb868cd0f752
1 /*
2 FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
4 ***************************************************************************
5 * *
6 * If you are: *
7 * *
8 * + New to FreeRTOS, *
9 * + Wanting to learn FreeRTOS or multitasking in general quickly *
10 * + Looking for basic training, *
11 * + Wanting to improve your FreeRTOS skills and productivity *
12 * *
13 * then take a look at the FreeRTOS eBook *
14 * *
15 * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
16 * http://www.FreeRTOS.org/Documentation *
17 * *
18 * A pdf reference manual is also available. Both are usually delivered *
19 * to your inbox within 20 minutes to two hours when purchased between 8am *
20 * and 8pm GMT (although please allow up to 24 hours in case of *
21 * exceptional circumstances). Thank you for your support! *
22 * *
23 ***************************************************************************
25 This file is part of the FreeRTOS distribution.
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 exception to the GPL is included to allow you to distribute
31 a combined work that includes FreeRTOS without being obliged to provide the
32 source code for proprietary components outside of the FreeRTOS kernel.
33 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35 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.
42 1 tab == 4 spaces!
44 http://www.FreeRTOS.org - Documentation, latest information, license and
45 contact details.
47 http://www.SafeRTOS.com - A version that is certified for use in safety
48 critical systems.
50 http://www.OpenRTOS.com - Commercial support, development, porting,
51 licensing and training services.
54 #ifndef INC_FREERTOS_H
55 #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"
56 #endif
58 #ifndef SEMAPHORE_H
59 #define SEMAPHORE_H
61 #include "queue.h"
63 typedef xQueueHandle xSemaphoreHandle;
65 #define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1 )
66 #define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0 )
67 #define semGIVE_BLOCK_TIME ( ( portTickType ) 0 )
70 /**
71 * semphr. h
72 * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
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.
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().
86 * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.
88 * Example usage:
89 <pre>
90 xSemaphoreHandle xSemaphore;
92 void vATask( void * pvParameters )
94 // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
95 // This is a macro so pass the variable in directly.
96 vSemaphoreCreateBinary( xSemaphore );
98 if( xSemaphore != NULL )
100 // The semaphore was created successfully.
101 // The semaphore can now be used.
104 </pre>
105 * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
106 * \ingroup Semaphores
108 #define vSemaphoreCreateBinary( xSemaphore ) { \
109 xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
110 if( xSemaphore != NULL ) \
112 xSemaphoreGive( xSemaphore ); \
117 * semphr. h
118 * <pre>xSemaphoreTake(
119 * xSemaphoreHandle xSemaphore,
120 * portTickType xBlockTime
121 * )</pre>
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().
127 * @param xSemaphore A handle to the semaphore being taken - obtained when
128 * the semaphore was created.
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).
136 * @return pdTRUE if the semaphore was obtained. pdFALSE
137 * if xBlockTime expired without the semaphore becoming available.
139 * Example usage:
140 <pre>
141 xSemaphoreHandle xSemaphore = NULL;
143 // A task that creates a semaphore.
144 void vATask( void * pvParameters )
146 // Create the semaphore to guard a shared resource.
147 vSemaphoreCreateBinary( xSemaphore );
150 // A task that uses the semaphore.
151 void vAnotherTask( void * pvParameters )
153 // ... Do other things.
155 if( xSemaphore != NULL )
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 )
161 // We were able to obtain the semaphore and can now access the
162 // shared resource.
164 // ...
166 // We have finished accessing the shared resource. Release the
167 // semaphore.
168 xSemaphoreGive( xSemaphore );
170 else
172 // We could not obtain the semaphore and can therefore not access
173 // the shared resource safely.
177 </pre>
178 * \defgroup xSemaphoreTake xSemaphoreTake
179 * \ingroup Semaphores
181 #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
184 * semphr. h
185 * xSemaphoreTakeRecursive(
186 * xSemaphoreHandle xMutex,
187 * portTickType xBlockTime
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();
194 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
195 * macro to be available.
197 * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
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.
206 * @param xMutex A handle to the mutex being obtained. This is the
207 * handle returned by xSemaphoreCreateRecursiveMutex();
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.
215 * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
216 * expired without the semaphore becoming available.
218 * Example usage:
219 <pre>
220 xSemaphoreHandle xMutex = NULL;
222 // A task that creates a mutex.
223 void vATask( void * pvParameters )
225 // Create the mutex to guard a shared resource.
226 xMutex = xSemaphoreCreateRecursiveMutex();
229 // A task that uses the mutex.
230 void vAnotherTask( void * pvParameters )
232 // ... Do other things.
234 if( xMutex != NULL )
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 )
240 // We were able to obtain the mutex and can now access the
241 // shared resource.
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 );
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 );
261 // Now the mutex can be taken by other tasks.
263 else
265 // We could not obtain the mutex and can therefore not access
266 // the shared resource safely.
270 </pre>
271 * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
272 * \ingroup Semaphores
274 #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime )
278 * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
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.
289 #define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
292 * semphr. h
293 * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
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().
299 * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
300 * an alternative which can be used from an ISR.
302 * This macro must also not be used on semaphores created using
303 * xSemaphoreCreateRecursiveMutex().
305 * @param xSemaphore A handle to the semaphore being released. This is the
306 * handle returned when the semaphore was created.
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.
313 * Example usage:
314 <pre>
315 xSemaphoreHandle xSemaphore = NULL;
317 void vATask( void * pvParameters )
319 // Create the semaphore to guard a shared resource.
320 vSemaphoreCreateBinary( xSemaphore );
322 if( xSemaphore != NULL )
324 if( xSemaphoreGive( xSemaphore ) != pdTRUE )
326 // We would expect this call to fail because we cannot give
327 // a semaphore without first "taking" it!
330 // Obtain the semaphore - don't block if the semaphore is not
331 // immediately available.
332 if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
334 // We now have the semaphore and can access the shared resource.
336 // ...
338 // We have finished accessing the shared resource so can free the
339 // semaphore.
340 if( xSemaphoreGive( xSemaphore ) != pdTRUE )
342 // We would not expect this call to fail because we must have
343 // obtained the semaphore to get here.
348 </pre>
349 * \defgroup xSemaphoreGive xSemaphoreGive
350 * \ingroup Semaphores
352 #define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
355 * semphr. h
356 * <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
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();
362 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
363 * macro to be available.
365 * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
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.
374 * @param xMutex A handle to the mutex being released, or 'given'. This is the
375 * handle returned by xSemaphoreCreateMutex();
377 * @return pdTRUE if the semaphore was given.
379 * Example usage:
380 <pre>
381 xSemaphoreHandle xMutex = NULL;
383 // A task that creates a mutex.
384 void vATask( void * pvParameters )
386 // Create the mutex to guard a shared resource.
387 xMutex = xSemaphoreCreateRecursiveMutex();
390 // A task that uses the mutex.
391 void vAnotherTask( void * pvParameters )
393 // ... Do other things.
395 if( xMutex != NULL )
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 )
401 // We were able to obtain the mutex and can now access the
402 // shared resource.
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 );
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 );
423 // Now the mutex can be taken by other tasks.
425 else
427 // We could not obtain the mutex and can therefore not access
428 // the shared resource safely.
432 </pre>
433 * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
434 * \ingroup Semaphores
436 #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex )
439 * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
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.
450 #define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
453 * semphr. h
454 * <pre>
455 xSemaphoreGiveFromISR(
456 xSemaphoreHandle xSemaphore,
457 signed portBASE_TYPE *pxHigherPriorityTaskWoken
458 )</pre>
460 * <i>Macro</i> to release a semaphore. The semaphore must have previously been
461 * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
463 * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
464 * must not be used with this macro.
466 * This macro can be used from an ISR.
468 * @param xSemaphore A handle to the semaphore being released. This is the
469 * handle returned when the semaphore was created.
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.
477 * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
479 * Example usage:
480 <pre>
481 \#define LONG_TIME 0xffff
482 \#define TICKS_TO_WAIT 10
483 xSemaphoreHandle xSemaphore = NULL;
485 // Repetitive task.
486 void vATask( void * pvParameters )
488 for( ;; )
490 // We want this task to run every 10 ticks of a timer. The semaphore
491 // was created before this task was started.
493 // Block waiting for the semaphore to become available.
494 if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
496 // It is time to execute.
498 // ...
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.
508 // Timer ISR
509 void vTimerISR( void * pvParameters )
511 static unsigned char ucLocalTickCount = 0;
512 static signed portBASE_TYPE xHigherPriorityTaskWoken;
514 // A timer tick has occurred.
516 // ... Do other time functions.
518 // Is it time for vATask () to run?
519 xHigherPriorityTaskWoken = pdFALSE;
520 ucLocalTickCount++;
521 if( ucLocalTickCount >= TICKS_TO_WAIT )
523 // Unblock the task by releasing the semaphore.
524 xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
526 // Reset the count so we release the semaphore again in 10 ticks time.
527 ucLocalTickCount = 0;
530 if( xHigherPriorityTaskWoken != pdFALSE )
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.
537 </pre>
538 * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
539 * \ingroup Semaphores
541 #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
544 * semphr. h
545 * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
547 * <i>Macro</i> that implements a mutex semaphore by using the existing queue
548 * mechanism.
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.
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.
558 * Mutex type semaphores cannot be used from within interrupt service routines.
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.
565 * @return xSemaphore Handle to the created mutex semaphore. Should be of type
566 * xSemaphoreHandle.
568 * Example usage:
569 <pre>
570 xSemaphoreHandle xSemaphore;
572 void vATask( void * pvParameters )
574 // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
575 // This is a macro so pass the variable in directly.
576 xSemaphore = xSemaphoreCreateMutex();
578 if( xSemaphore != NULL )
580 // The semaphore was created successfully.
581 // The semaphore can now be used.
584 </pre>
585 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
586 * \ingroup Semaphores
588 #define xSemaphoreCreateMutex() xQueueCreateMutex()
592 * semphr. h
593 * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
595 * <i>Macro</i> that implements a recursive mutex by using the existing queue
596 * mechanism.
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.
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.
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.
613 * Mutex type semaphores cannot be used from within interrupt service routines.
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.
620 * @return xSemaphore Handle to the created mutex semaphore. Should be of type
621 * xSemaphoreHandle.
623 * Example usage:
624 <pre>
625 xSemaphoreHandle xSemaphore;
627 void vATask( void * pvParameters )
629 // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
630 // This is a macro so pass the variable in directly.
631 xSemaphore = xSemaphoreCreateRecursiveMutex();
633 if( xSemaphore != NULL )
635 // The semaphore was created successfully.
636 // The semaphore can now be used.
639 </pre>
640 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
641 * \ingroup Semaphores
643 #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
646 * semphr. h
647 * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
649 * <i>Macro</i> that creates a counting semaphore by using the existing
650 * queue mechanism.
652 * Counting semaphores are typically used for two things:
654 * 1) Counting events.
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.
664 * 2) Resource management.
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.
674 * @param uxMaxCount The maximum count value that can be reached. When the
675 * semaphore reaches this value it can no longer be 'given'.
677 * @param uxInitialCount The count value assigned to the semaphore when it is
678 * created.
680 * @return Handle to the created semaphore. Null if the semaphore could not be
681 * created.
683 * Example usage:
684 <pre>
685 xSemaphoreHandle xSemaphore;
687 void vATask( void * pvParameters )
689 xSemaphoreHandle xSemaphore = NULL;
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 );
696 if( xSemaphore != NULL )
698 // The semaphore was created successfully.
699 // The semaphore can now be used.
702 </pre>
703 * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
704 * \ingroup Semaphores
706 #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )
709 #endif /* SEMAPHORE_H */