www.freertos.org

Dependents:   Nucleo freertos_test FreeRTOS_test freertos_bluetooth ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers semphr.h Source File

semphr.h

00001 /*
00002     FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
00003     All rights reserved
00004 
00005     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
00006 
00007     ***************************************************************************
00008      *                                                                       *
00009      *    FreeRTOS provides completely free yet professionally developed,    *
00010      *    robust, strictly quality controlled, supported, and cross          *
00011      *    platform software that has become a de facto standard.             *
00012      *                                                                       *
00013      *    Help yourself get started quickly and support the FreeRTOS         *
00014      *    project by purchasing a FreeRTOS tutorial book, reference          *
00015      *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
00016      *                                                                       *
00017      *    Thank you!                                                         *
00018      *                                                                       *
00019     ***************************************************************************
00020 
00021     This file is part of the FreeRTOS distribution.
00022 
00023     FreeRTOS is free software; you can redistribute it and/or modify it under
00024     the terms of the GNU General Public License (version 2) as published by the
00025     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
00026 
00027     >>! NOTE: The modification to the GPL is included to allow you to distribute
00028     >>! a combined work that includes FreeRTOS without being obliged to provide
00029     >>! the source code for proprietary components outside of the FreeRTOS
00030     >>! kernel.
00031 
00032     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
00033     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00034     FOR A PARTICULAR PURPOSE.  Full license text is available from the following
00035     link: http://www.freertos.org/a00114.html
00036 
00037     1 tab == 4 spaces!
00038 
00039     ***************************************************************************
00040      *                                                                       *
00041      *    Having a problem?  Start by reading the FAQ "My application does   *
00042      *    not run, what could be wrong?"                                     *
00043      *                                                                       *
00044      *    http://www.FreeRTOS.org/FAQHelp.html                               *
00045      *                                                                       *
00046     ***************************************************************************
00047 
00048     http://www.FreeRTOS.org - Documentation, books, training, latest versions,
00049     license and Real Time Engineers Ltd. contact details.
00050 
00051     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
00052     including FreeRTOS+Trace - an indispensable productivity tool, a DOS
00053     compatible FAT file system, and our tiny thread aware UDP/IP stack.
00054 
00055     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
00056     Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
00057     licenses offer ticketed support, indemnification and middleware.
00058 
00059     http://www.SafeRTOS.com - High Integrity Systems also provide a safety
00060     engineered and independently SIL3 certified version for use in safety and
00061     mission critical applications that require provable dependability.
00062 
00063     1 tab == 4 spaces!
00064 */
00065 
00066 #ifndef SEMAPHORE_H
00067 #define SEMAPHORE_H
00068 
00069 #ifndef INC_FREERTOS_H
00070     #error "include FreeRTOS.h" must appear in source files before "include semphr.h"
00071 #endif
00072 
00073 #include "queue.h"
00074 
00075 typedef xQueueHandle xSemaphoreHandle;
00076 
00077 #define semBINARY_SEMAPHORE_QUEUE_LENGTH    ( ( unsigned char ) 1U )
00078 #define semSEMAPHORE_QUEUE_ITEM_LENGTH      ( ( unsigned char ) 0U )
00079 #define semGIVE_BLOCK_TIME                  ( ( portTickType ) 0U )
00080 
00081 
00082 /**
00083  * semphr. h
00084  * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
00085  *
00086  * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the
00087  * xSemaphoreCreateBinary() function.  Note that binary semaphores created using
00088  * the vSemaphoreCreateBinary() macro are created in a state such that the
00089  * first call to 'take' the semaphore would pass, whereas binary semaphores
00090  * created using xSemaphoreCreateBinary() are created in a state such that the
00091  * the semaphore must first be 'given' before it can be 'taken'.
00092  *
00093  * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
00094  * The queue length is 1 as this is a binary semaphore.  The data size is 0
00095  * as we don't want to actually store any data - we just want to know if the
00096  * queue is empty or full.
00097  *
00098  * This type of semaphore can be used for pure synchronisation between tasks or
00099  * between an interrupt and a task.  The semaphore need not be given back once
00100  * obtained, so one task/interrupt can continuously 'give' the semaphore while
00101  * another continuously 'takes' the semaphore.  For this reason this type of
00102  * semaphore does not use a priority inheritance mechanism.  For an alternative
00103  * that does use priority inheritance see xSemaphoreCreateMutex().
00104  *
00105  * @param xSemaphore Handle to the created semaphore.  Should be of type xSemaphoreHandle.
00106  *
00107  * Example usage:
00108  <pre>
00109  xSemaphoreHandle xSemaphore = NULL;
00110 
00111  void vATask( void * pvParameters )
00112  {
00113     // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
00114     // This is a macro so pass the variable in directly.
00115     vSemaphoreCreateBinary( xSemaphore );
00116 
00117     if( xSemaphore != NULL )
00118     {
00119         // The semaphore was created successfully.
00120         // The semaphore can now be used.
00121     }
00122  }
00123  </pre>
00124  * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
00125  * \ingroup Semaphores
00126  */
00127 #define vSemaphoreCreateBinary( xSemaphore )                                                                                                    \
00128     {                                                                                                                                           \
00129         ( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
00130         if( ( xSemaphore ) != NULL )                                                                                                            \
00131         {                                                                                                                                       \
00132             ( void ) xSemaphoreGive( ( xSemaphore ) );                                                                                          \
00133         }                                                                                                                                       \
00134     }
00135 
00136 /**
00137  * semphr. h
00138  * <pre>xSemaphoreHandle xSemaphoreCreateBinary( void )</pre>
00139  *
00140  * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this
00141  * xSemaphoreCreateBinary() function.  Note that binary semaphores created using
00142  * the vSemaphoreCreateBinary() macro are created in a state such that the
00143  * first call to 'take' the semaphore would pass, whereas binary semaphores
00144  * created using xSemaphoreCreateBinary() are created in a state such that the
00145  * the semaphore must first be 'given' before it can be 'taken'.
00146  *
00147  * Function that creates a semaphore by using the existing queue mechanism.
00148  * The queue length is 1 as this is a binary semaphore.  The data size is 0
00149  * as nothing is actually stored - all that is important is whether the queue is
00150  * empty or full (the binary semaphore is available or not).
00151  *
00152  * This type of semaphore can be used for pure synchronisation between tasks or
00153  * between an interrupt and a task.  The semaphore need not be given back once
00154  * obtained, so one task/interrupt can continuously 'give' the semaphore while
00155  * another continuously 'takes' the semaphore.  For this reason this type of
00156  * semaphore does not use a priority inheritance mechanism.  For an alternative
00157  * that does use priority inheritance see xSemaphoreCreateMutex().
00158  *
00159  * @return Handle to the created semaphore.
00160  *
00161  * Example usage:
00162  <pre>
00163  xSemaphoreHandle xSemaphore = NULL;
00164 
00165  void vATask( void * pvParameters )
00166  {
00167     // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
00168     // This is a macro so pass the variable in directly.
00169     xSemaphore = xSemaphoreCreateBinary();
00170 
00171     if( xSemaphore != NULL )
00172     {
00173         // The semaphore was created successfully.
00174         // The semaphore can now be used.
00175     }
00176  }
00177  </pre>
00178  * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
00179  * \ingroup Semaphores
00180  */
00181 #define xSemaphoreCreateBinary() xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
00182 
00183 /**
00184  * semphr. h
00185  * <pre>xSemaphoreTake(
00186  *                   xSemaphoreHandle xSemaphore,
00187  *                   portTickType xBlockTime
00188  *               )</pre>
00189  *
00190  * <i>Macro</i> to obtain a semaphore.  The semaphore must have previously been
00191  * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
00192  * xSemaphoreCreateCounting().
00193  *
00194  * @param xSemaphore A handle to the semaphore being taken - obtained when
00195  * the semaphore was created.
00196  *
00197  * @param xBlockTime The time in ticks to wait for the semaphore to become
00198  * available.  The macro portTICK_RATE_MS can be used to convert this to a
00199  * real time.  A block time of zero can be used to poll the semaphore.  A block
00200  * time of portMAX_DELAY can be used to block indefinitely (provided
00201  * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
00202  *
00203  * @return pdTRUE if the semaphore was obtained.  pdFALSE
00204  * if xBlockTime expired without the semaphore becoming available.
00205  *
00206  * Example usage:
00207  <pre>
00208  xSemaphoreHandle xSemaphore = NULL;
00209 
00210  // A task that creates a semaphore.
00211  void vATask( void * pvParameters )
00212  {
00213     // Create the semaphore to guard a shared resource.
00214     vSemaphoreCreateBinary( xSemaphore );
00215  }
00216 
00217  // A task that uses the semaphore.
00218  void vAnotherTask( void * pvParameters )
00219  {
00220     // ... Do other things.
00221 
00222     if( xSemaphore != NULL )
00223     {
00224         // See if we can obtain the semaphore.  If the semaphore is not available
00225         // wait 10 ticks to see if it becomes free.
00226         if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
00227         {
00228             // We were able to obtain the semaphore and can now access the
00229             // shared resource.
00230 
00231             // ...
00232 
00233             // We have finished accessing the shared resource.  Release the
00234             // semaphore.
00235             xSemaphoreGive( xSemaphore );
00236         }
00237         else
00238         {
00239             // We could not obtain the semaphore and can therefore not access
00240             // the shared resource safely.
00241         }
00242     }
00243  }
00244  </pre>
00245  * \defgroup xSemaphoreTake xSemaphoreTake
00246  * \ingroup Semaphores
00247  */
00248 #define xSemaphoreTake( xSemaphore, xBlockTime )        xQueueGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
00249 
00250 /**
00251  * semphr. h
00252  * xSemaphoreTakeRecursive(
00253  *                          xSemaphoreHandle xMutex,
00254  *                          portTickType xBlockTime
00255  *                        )
00256  *
00257  * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
00258  * The mutex must have previously been created using a call to
00259  * xSemaphoreCreateRecursiveMutex();
00260  *
00261  * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
00262  * macro to be available.
00263  *
00264  * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
00265  *
00266  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
00267  * doesn't become available again until the owner has called
00268  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,
00269  * if a task successfully 'takes' the same mutex 5 times then the mutex will
00270  * not be available to any other task until it has also  'given' the mutex back
00271  * exactly five times.
00272  *
00273  * @param xMutex A handle to the mutex being obtained.  This is the
00274  * handle returned by xSemaphoreCreateRecursiveMutex();
00275  *
00276  * @param xBlockTime The time in ticks to wait for the semaphore to become
00277  * available.  The macro portTICK_RATE_MS can be used to convert this to a
00278  * real time.  A block time of zero can be used to poll the semaphore.  If
00279  * the task already owns the semaphore then xSemaphoreTakeRecursive() will
00280  * return immediately no matter what the value of xBlockTime.
00281  *
00282  * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime
00283  * expired without the semaphore becoming available.
00284  *
00285  * Example usage:
00286  <pre>
00287  xSemaphoreHandle xMutex = NULL;
00288 
00289  // A task that creates a mutex.
00290  void vATask( void * pvParameters )
00291  {
00292     // Create the mutex to guard a shared resource.
00293     xMutex = xSemaphoreCreateRecursiveMutex();
00294  }
00295 
00296  // A task that uses the mutex.
00297  void vAnotherTask( void * pvParameters )
00298  {
00299     // ... Do other things.
00300 
00301     if( xMutex != NULL )
00302     {
00303         // See if we can obtain the mutex.  If the mutex is not available
00304         // wait 10 ticks to see if it becomes free.
00305         if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
00306         {
00307             // We were able to obtain the mutex and can now access the
00308             // shared resource.
00309 
00310             // ...
00311             // For some reason due to the nature of the code further calls to
00312             // xSemaphoreTakeRecursive() are made on the same mutex.  In real
00313             // code these would not be just sequential calls as this would make
00314             // no sense.  Instead the calls are likely to be buried inside
00315             // a more complex call structure.
00316             xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
00317             xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
00318 
00319             // The mutex has now been 'taken' three times, so will not be
00320             // available to another task until it has also been given back
00321             // three times.  Again it is unlikely that real code would have
00322             // these calls sequentially, but instead buried in a more complex
00323             // call structure.  This is just for illustrative purposes.
00324             xSemaphoreGiveRecursive( xMutex );
00325             xSemaphoreGiveRecursive( xMutex );
00326             xSemaphoreGiveRecursive( xMutex );
00327 
00328             // Now the mutex can be taken by other tasks.
00329         }
00330         else
00331         {
00332             // We could not obtain the mutex and can therefore not access
00333             // the shared resource safely.
00334         }
00335     }
00336  }
00337  </pre>
00338  * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
00339  * \ingroup Semaphores
00340  */
00341 #define xSemaphoreTakeRecursive( xMutex, xBlockTime )   xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
00342 
00343 
00344 /*
00345  * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
00346  *
00347  * The source code that implements the alternative (Alt) API is much
00348  * simpler  because it executes everything from within a critical section.
00349  * This is  the approach taken by many other RTOSes, but FreeRTOS.org has the
00350  * preferred fully featured API too.  The fully featured API has more
00351  * complex  code that takes longer to execute, but makes much less use of
00352  * critical sections.  Therefore the alternative API sacrifices interrupt
00353  * responsiveness to gain execution speed, whereas the fully featured API
00354  * sacrifices execution speed to ensure better interrupt responsiveness.
00355  */
00356 #define xSemaphoreAltTake( xSemaphore, xBlockTime )     xQueueAltGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
00357 
00358 /**
00359  * semphr. h
00360  * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
00361  *
00362  * <i>Macro</i> to release a semaphore.  The semaphore must have previously been
00363  * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
00364  * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
00365  *
00366  * This macro must not be used from an ISR.  See xSemaphoreGiveFromISR () for
00367  * an alternative which can be used from an ISR.
00368  *
00369  * This macro must also not be used on semaphores created using
00370  * xSemaphoreCreateRecursiveMutex().
00371  *
00372  * @param xSemaphore A handle to the semaphore being released.  This is the
00373  * handle returned when the semaphore was created.
00374  *
00375  * @return pdTRUE if the semaphore was released.  pdFALSE if an error occurred.
00376  * Semaphores are implemented using queues.  An error can occur if there is
00377  * no space on the queue to post a message - indicating that the
00378  * semaphore was not first obtained correctly.
00379  *
00380  * Example usage:
00381  <pre>
00382  xSemaphoreHandle xSemaphore = NULL;
00383 
00384  void vATask( void * pvParameters )
00385  {
00386     // Create the semaphore to guard a shared resource.
00387     vSemaphoreCreateBinary( xSemaphore );
00388 
00389     if( xSemaphore != NULL )
00390     {
00391         if( xSemaphoreGive( xSemaphore ) != pdTRUE )
00392         {
00393             // We would expect this call to fail because we cannot give
00394             // a semaphore without first "taking" it!
00395         }
00396 
00397         // Obtain the semaphore - don't block if the semaphore is not
00398         // immediately available.
00399         if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
00400         {
00401             // We now have the semaphore and can access the shared resource.
00402 
00403             // ...
00404 
00405             // We have finished accessing the shared resource so can free the
00406             // semaphore.
00407             if( xSemaphoreGive( xSemaphore ) != pdTRUE )
00408             {
00409                 // We would not expect this call to fail because we must have
00410                 // obtained the semaphore to get here.
00411             }
00412         }
00413     }
00414  }
00415  </pre>
00416  * \defgroup xSemaphoreGive xSemaphoreGive
00417  * \ingroup Semaphores
00418  */
00419 #define xSemaphoreGive( xSemaphore )        xQueueGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
00420 
00421 /**
00422  * semphr. h
00423  * <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
00424  *
00425  * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
00426  * The mutex must have previously been created using a call to
00427  * xSemaphoreCreateRecursiveMutex();
00428  *
00429  * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
00430  * macro to be available.
00431  *
00432  * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
00433  *
00434  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
00435  * doesn't become available again until the owner has called
00436  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,
00437  * if a task successfully 'takes' the same mutex 5 times then the mutex will
00438  * not be available to any other task until it has also  'given' the mutex back
00439  * exactly five times.
00440  *
00441  * @param xMutex A handle to the mutex being released, or 'given'.  This is the
00442  * handle returned by xSemaphoreCreateMutex();
00443  *
00444  * @return pdTRUE if the semaphore was given.
00445  *
00446  * Example usage:
00447  <pre>
00448  xSemaphoreHandle xMutex = NULL;
00449 
00450  // A task that creates a mutex.
00451  void vATask( void * pvParameters )
00452  {
00453     // Create the mutex to guard a shared resource.
00454     xMutex = xSemaphoreCreateRecursiveMutex();
00455  }
00456 
00457  // A task that uses the mutex.
00458  void vAnotherTask( void * pvParameters )
00459  {
00460     // ... Do other things.
00461 
00462     if( xMutex != NULL )
00463     {
00464         // See if we can obtain the mutex.  If the mutex is not available
00465         // wait 10 ticks to see if it becomes free.
00466         if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
00467         {
00468             // We were able to obtain the mutex and can now access the
00469             // shared resource.
00470 
00471             // ...
00472             // For some reason due to the nature of the code further calls to
00473             // xSemaphoreTakeRecursive() are made on the same mutex.  In real
00474             // code these would not be just sequential calls as this would make
00475             // no sense.  Instead the calls are likely to be buried inside
00476             // a more complex call structure.
00477             xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
00478             xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
00479 
00480             // The mutex has now been 'taken' three times, so will not be
00481             // available to another task until it has also been given back
00482             // three times.  Again it is unlikely that real code would have
00483             // these calls sequentially, it would be more likely that the calls
00484             // to xSemaphoreGiveRecursive() would be called as a call stack
00485             // unwound.  This is just for demonstrative purposes.
00486             xSemaphoreGiveRecursive( xMutex );
00487             xSemaphoreGiveRecursive( xMutex );
00488             xSemaphoreGiveRecursive( xMutex );
00489 
00490             // Now the mutex can be taken by other tasks.
00491         }
00492         else
00493         {
00494             // We could not obtain the mutex and can therefore not access
00495             // the shared resource safely.
00496         }
00497     }
00498  }
00499  </pre>
00500  * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
00501  * \ingroup Semaphores
00502  */
00503 #define xSemaphoreGiveRecursive( xMutex )   xQueueGiveMutexRecursive( ( xMutex ) )
00504 
00505 /*
00506  * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
00507  *
00508  * The source code that implements the alternative (Alt) API is much
00509  * simpler  because it executes everything from within a critical section.
00510  * This is  the approach taken by many other RTOSes, but FreeRTOS.org has the
00511  * preferred fully featured API too.  The fully featured API has more
00512  * complex  code that takes longer to execute, but makes much less use of
00513  * critical sections.  Therefore the alternative API sacrifices interrupt
00514  * responsiveness to gain execution speed, whereas the fully featured API
00515  * sacrifices execution speed to ensure better interrupt responsiveness.
00516  */
00517 #define xSemaphoreAltGive( xSemaphore )     xQueueAltGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
00518 
00519 /**
00520  * semphr. h
00521  * <pre>
00522  xSemaphoreGiveFromISR(
00523                           xSemaphoreHandle xSemaphore,
00524                           signed portBASE_TYPE *pxHigherPriorityTaskWoken
00525                       )</pre>
00526  *
00527  * <i>Macro</i> to  release a semaphore.  The semaphore must have previously been
00528  * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
00529  *
00530  * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
00531  * must not be used with this macro.
00532  *
00533  * This macro can be used from an ISR.
00534  *
00535  * @param xSemaphore A handle to the semaphore being released.  This is the
00536  * handle returned when the semaphore was created.
00537  *
00538  * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
00539  * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
00540  * to unblock, and the unblocked task has a priority higher than the currently
00541  * running task.  If xSemaphoreGiveFromISR() sets this value to pdTRUE then
00542  * a context switch should be requested before the interrupt is exited.
00543  *
00544  * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
00545  *
00546  * Example usage:
00547  <pre>
00548  \#define LONG_TIME 0xffff
00549  \#define TICKS_TO_WAIT 10
00550  xSemaphoreHandle xSemaphore = NULL;
00551 
00552  // Repetitive task.
00553  void vATask( void * pvParameters )
00554  {
00555     for( ;; )
00556     {
00557         // We want this task to run every 10 ticks of a timer.  The semaphore
00558         // was created before this task was started.
00559 
00560         // Block waiting for the semaphore to become available.
00561         if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
00562         {
00563             // It is time to execute.
00564 
00565             // ...
00566 
00567             // We have finished our task.  Return to the top of the loop where
00568             // we will block on the semaphore until it is time to execute
00569             // again.  Note when using the semaphore for synchronisation with an
00570             // ISR in this manner there is no need to 'give' the semaphore back.
00571         }
00572     }
00573  }
00574 
00575  // Timer ISR
00576  void vTimerISR( void * pvParameters )
00577  {
00578  static unsigned char ucLocalTickCount = 0;
00579  static signed portBASE_TYPE xHigherPriorityTaskWoken;
00580 
00581     // A timer tick has occurred.
00582 
00583     // ... Do other time functions.
00584 
00585     // Is it time for vATask () to run?
00586     xHigherPriorityTaskWoken = pdFALSE;
00587     ucLocalTickCount++;
00588     if( ucLocalTickCount >= TICKS_TO_WAIT )
00589     {
00590         // Unblock the task by releasing the semaphore.
00591         xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
00592 
00593         // Reset the count so we release the semaphore again in 10 ticks time.
00594         ucLocalTickCount = 0;
00595     }
00596 
00597     if( xHigherPriorityTaskWoken != pdFALSE )
00598     {
00599         // We can force a context switch here.  Context switching from an
00600         // ISR uses port specific syntax.  Check the demo task for your port
00601         // to find the syntax required.
00602     }
00603  }
00604  </pre>
00605  * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
00606  * \ingroup Semaphores
00607  */
00608 #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )          xQueueGenericSendFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
00609 
00610 /**
00611  * semphr. h
00612  * <pre>
00613  xSemaphoreTakeFromISR(
00614                           xSemaphoreHandle xSemaphore,
00615                           signed portBASE_TYPE *pxHigherPriorityTaskWoken
00616                       )</pre>
00617  *
00618  * <i>Macro</i> to  take a semaphore from an ISR.  The semaphore must have
00619  * previously been created with a call to vSemaphoreCreateBinary() or
00620  * xSemaphoreCreateCounting().
00621  *
00622  * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
00623  * must not be used with this macro.
00624  *
00625  * This macro can be used from an ISR, however taking a semaphore from an ISR
00626  * is not a common operation.  It is likely to only be useful when taking a
00627  * counting semaphore when an interrupt is obtaining an object from a resource
00628  * pool (when the semaphore count indicates the number of resources available).
00629  *
00630  * @param xSemaphore A handle to the semaphore being taken.  This is the
00631  * handle returned when the semaphore was created.
00632  *
00633  * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set
00634  * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task
00635  * to unblock, and the unblocked task has a priority higher than the currently
00636  * running task.  If xSemaphoreTakeFromISR() sets this value to pdTRUE then
00637  * a context switch should be requested before the interrupt is exited.
00638  *
00639  * @return pdTRUE if the semaphore was successfully taken, otherwise
00640  * pdFALSE
00641  */
00642 #define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )          xQueueReceiveFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )
00643 
00644 /**
00645  * semphr. h
00646  * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
00647  *
00648  * <i>Macro</i> that implements a mutex semaphore by using the existing queue
00649  * mechanism.
00650  *
00651  * Mutexes created using this macro can be accessed using the xSemaphoreTake()
00652  * and xSemaphoreGive() macros.  The xSemaphoreTakeRecursive() and
00653  * xSemaphoreGiveRecursive() macros should not be used.
00654  *
00655  * This type of semaphore uses a priority inheritance mechanism so a task
00656  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
00657  * semaphore it is no longer required.
00658  *
00659  * Mutex type semaphores cannot be used from within interrupt service routines.
00660  *
00661  * See vSemaphoreCreateBinary() for an alternative implementation that can be
00662  * used for pure synchronisation (where one task or interrupt always 'gives' the
00663  * semaphore and another always 'takes' the semaphore) and from within interrupt
00664  * service routines.
00665  *
00666  * @return xSemaphore Handle to the created mutex semaphore.  Should be of type
00667  *      xSemaphoreHandle.
00668  *
00669  * Example usage:
00670  <pre>
00671  xSemaphoreHandle xSemaphore;
00672 
00673  void vATask( void * pvParameters )
00674  {
00675     // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
00676     // This is a macro so pass the variable in directly.
00677     xSemaphore = xSemaphoreCreateMutex();
00678 
00679     if( xSemaphore != NULL )
00680     {
00681         // The semaphore was created successfully.
00682         // The semaphore can now be used.
00683     }
00684  }
00685  </pre>
00686  * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
00687  * \ingroup Semaphores
00688  */
00689 #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
00690 
00691 
00692 /**
00693  * semphr. h
00694  * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
00695  *
00696  * <i>Macro</i> that implements a recursive mutex by using the existing queue
00697  * mechanism.
00698  *
00699  * Mutexes created using this macro can be accessed using the
00700  * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros.  The
00701  * xSemaphoreTake() and xSemaphoreGive() macros should not be used.
00702  *
00703  * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
00704  * doesn't become available again until the owner has called
00705  * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,
00706  * if a task successfully 'takes' the same mutex 5 times then the mutex will
00707  * not be available to any other task until it has also  'given' the mutex back
00708  * exactly five times.
00709  *
00710  * This type of semaphore uses a priority inheritance mechanism so a task
00711  * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
00712  * semaphore it is no longer required.
00713  *
00714  * Mutex type semaphores cannot be used from within interrupt service routines.
00715  *
00716  * See vSemaphoreCreateBinary() for an alternative implementation that can be
00717  * used for pure synchronisation (where one task or interrupt always 'gives' the
00718  * semaphore and another always 'takes' the semaphore) and from within interrupt
00719  * service routines.
00720  *
00721  * @return xSemaphore Handle to the created mutex semaphore.  Should be of type
00722  *      xSemaphoreHandle.
00723  *
00724  * Example usage:
00725  <pre>
00726  xSemaphoreHandle xSemaphore;
00727 
00728  void vATask( void * pvParameters )
00729  {
00730     // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
00731     // This is a macro so pass the variable in directly.
00732     xSemaphore = xSemaphoreCreateRecursiveMutex();
00733 
00734     if( xSemaphore != NULL )
00735     {
00736         // The semaphore was created successfully.
00737         // The semaphore can now be used.
00738     }
00739  }
00740  </pre>
00741  * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
00742  * \ingroup Semaphores
00743  */
00744 #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
00745 
00746 /**
00747  * semphr. h
00748  * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
00749  *
00750  * <i>Macro</i> that creates a counting semaphore by using the existing
00751  * queue mechanism.
00752  *
00753  * Counting semaphores are typically used for two things:
00754  *
00755  * 1) Counting events.
00756  *
00757  *    In this usage scenario an event handler will 'give' a semaphore each time
00758  *    an event occurs (incrementing the semaphore count value), and a handler
00759  *    task will 'take' a semaphore each time it processes an event
00760  *    (decrementing the semaphore count value).  The count value is therefore
00761  *    the difference between the number of events that have occurred and the
00762  *    number that have been processed.  In this case it is desirable for the
00763  *    initial count value to be zero.
00764  *
00765  * 2) Resource management.
00766  *
00767  *    In this usage scenario the count value indicates the number of resources
00768  *    available.  To obtain control of a resource a task must first obtain a
00769  *    semaphore - decrementing the semaphore count value.  When the count value
00770  *    reaches zero there are no free resources.  When a task finishes with the
00771  *    resource it 'gives' the semaphore back - incrementing the semaphore count
00772  *    value.  In this case it is desirable for the initial count value to be
00773  *    equal to the maximum count value, indicating that all resources are free.
00774  *
00775  * @param uxMaxCount The maximum count value that can be reached.  When the
00776  *        semaphore reaches this value it can no longer be 'given'.
00777  *
00778  * @param uxInitialCount The count value assigned to the semaphore when it is
00779  *        created.
00780  *
00781  * @return Handle to the created semaphore.  Null if the semaphore could not be
00782  *         created.
00783  *
00784  * Example usage:
00785  <pre>
00786  xSemaphoreHandle xSemaphore;
00787 
00788  void vATask( void * pvParameters )
00789  {
00790  xSemaphoreHandle xSemaphore = NULL;
00791 
00792     // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
00793     // The max value to which the semaphore can count should be 10, and the
00794     // initial value assigned to the count should be 0.
00795     xSemaphore = xSemaphoreCreateCounting( 10, 0 );
00796 
00797     if( xSemaphore != NULL )
00798     {
00799         // The semaphore was created successfully.
00800         // The semaphore can now be used.
00801     }
00802  }
00803  </pre>
00804  * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
00805  * \ingroup Semaphores
00806  */
00807 #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
00808 
00809 /**
00810  * semphr. h
00811  * <pre>void vSemaphoreDelete( xSemaphoreHandle xSemaphore );</pre>
00812  *
00813  * Delete a semaphore.  This function must be used with care.  For example,
00814  * do not delete a mutex type semaphore if the mutex is held by a task.
00815  *
00816  * @param xSemaphore A handle to the semaphore to be deleted.
00817  *
00818  * \defgroup vSemaphoreDelete vSemaphoreDelete
00819  * \ingroup Semaphores
00820  */
00821 #define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) ( xSemaphore ) )
00822 
00823 /**
00824  * semphr.h
00825  * <pre>xTaskHandle xSemaphoreGetMutexHolder( xSemaphoreHandle xMutex );</pre>
00826  *
00827  * If xMutex is indeed a mutex type semaphore, return the current mutex holder.
00828  * If xMutex is not a mutex type semaphore, or the mutex is available (not held
00829  * by a task), return NULL.
00830  *
00831  * Note: This Is is a good way of determining if the calling task is the mutex
00832  * holder, but not a good way of determining the identity of the mutex holder as
00833  * the holder may change between the function exiting and the returned value
00834  * being tested.
00835  */
00836 #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
00837 
00838 #endif /* SEMAPHORE_H */
00839 
00840