root/webserver/example/freeRTOS/Source/include/semphr.h

Revision 14, 26.4 kB (checked in by phil, 15 years ago)

added unmodified FreeRTOS package V5.4.1 with only web srv demo source for LPC2368 for CrossWorks?

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