root/Examples_CP-JR_ARM7_LPC2368/FreeRTOS_Book/Source-Code-For-Examples/FreeRTOS_Source/include/semphr.h

Revision 36, 26.7 kB (checked in by phil, 15 years ago)

added purchased FreeRTOS book

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