summaryrefslogtreecommitdiff
path: root/freertos/Source/include/semphr.h
diff options
context:
space:
mode:
Diffstat (limited to 'freertos/Source/include/semphr.h')
-rw-r--r--freertos/Source/include/semphr.h505
1 files changed, 416 insertions, 89 deletions
diff --git a/freertos/Source/include/semphr.h b/freertos/Source/include/semphr.h
index 9f76072..a674b02 100644
--- a/freertos/Source/include/semphr.h
+++ b/freertos/Source/include/semphr.h
@@ -1,5 +1,5 @@
/*
- FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
+ FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
@@ -87,6 +87,10 @@ typedef QueueHandle_t SemaphoreHandle_t;
* semphr. h
* <pre>vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )</pre>
*
+ * In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a binary semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
* This old vSemaphoreCreateBinary() macro is now deprecated in favour of the
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
* the vSemaphoreCreateBinary() macro are created in a state such that the
@@ -128,19 +132,37 @@ typedef QueueHandle_t SemaphoreHandle_t;
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
* \ingroup Semaphores
*/
-#define vSemaphoreCreateBinary( xSemaphore ) \
- { \
- ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
- if( ( xSemaphore ) != NULL ) \
- { \
- ( void ) xSemaphoreGive( ( xSemaphore ) ); \
- } \
- }
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+ #define vSemaphoreCreateBinary( xSemaphore ) \
+ { \
+ ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
+ if( ( xSemaphore ) != NULL ) \
+ { \
+ ( void ) xSemaphoreGive( ( xSemaphore ) ); \
+ } \
+ }
+#endif
/**
* semphr. h
* <pre>SemaphoreHandle_t xSemaphoreCreateBinary( void )</pre>
*
+ * Creates a new binary semaphore instance, and returns a handle by which the
+ * new semaphore can be referenced.
+ *
+ * In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a binary semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
+ * Internally, within the FreeRTOS implementation, binary semaphores use a block
+ * of memory, in which the semaphore structure is stored. If a binary semaphore
+ * is created using xSemaphoreCreateBinary() then the required memory is
+ * automatically dynamically allocated inside the xSemaphoreCreateBinary()
+ * function. (see http://www.freertos.org/a00111.html). If a binary semaphore
+ * is created using xSemaphoreCreateBinaryStatic() then the application writer
+ * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a
+ * binary semaphore to be created without using any dynamic memory allocation.
+ *
* The old vSemaphoreCreateBinary() macro is now deprecated in favour of this
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
* the vSemaphoreCreateBinary() macro are created in a state such that the
@@ -148,11 +170,6 @@ typedef QueueHandle_t SemaphoreHandle_t;
* created using xSemaphoreCreateBinary() are created in a state such that the
* the semaphore must first be 'given' before it can be 'taken'.
*
- * Function that creates a semaphore by using the existing queue mechanism.
- * The queue length is 1 as this is a binary semaphore. The data size is 0
- * as nothing is actually stored - all that is important is whether the queue is
- * empty or full (the binary semaphore is available or not).
- *
* This type of semaphore can be used for pure synchronisation between tasks or
* between an interrupt and a task. The semaphore need not be given back once
* obtained, so one task/interrupt can continuously 'give' the semaphore while
@@ -160,7 +177,8 @@ typedef QueueHandle_t SemaphoreHandle_t;
* semaphore does not use a priority inheritance mechanism. For an alternative
* that does use priority inheritance see xSemaphoreCreateMutex().
*
- * @return Handle to the created semaphore.
+ * @return Handle to the created semaphore, or NULL if the memory required to
+ * hold the semaphore's data structures could not be allocated.
*
* Example usage:
<pre>
@@ -168,7 +186,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
void vATask( void * pvParameters )
{
- // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+ // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
// This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateBinary();
@@ -179,10 +197,71 @@ typedef QueueHandle_t SemaphoreHandle_t;
}
}
</pre>
- * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
+ * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+ #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
+#endif
+
+/**
+ * semphr. h
+ * <pre>SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )</pre>
+ *
+ * Creates a new binary semaphore instance, and returns a handle by which the
+ * new semaphore can be referenced.
+ *
+ * NOTE: In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a binary semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
+ * Internally, within the FreeRTOS implementation, binary semaphores use a block
+ * of memory, in which the semaphore structure is stored. If a binary semaphore
+ * is created using xSemaphoreCreateBinary() then the required memory is
+ * automatically dynamically allocated inside the xSemaphoreCreateBinary()
+ * function. (see http://www.freertos.org/a00111.html). If a binary semaphore
+ * is created using xSemaphoreCreateBinaryStatic() then the application writer
+ * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a
+ * binary semaphore to be created without using any dynamic memory allocation.
+ *
+ * This type of semaphore can be used for pure synchronisation between tasks or
+ * between an interrupt and a task. The semaphore need not be given back once
+ * obtained, so one task/interrupt can continuously 'give' the semaphore while
+ * another continuously 'takes' the semaphore. For this reason this type of
+ * semaphore does not use a priority inheritance mechanism. For an alternative
+ * that does use priority inheritance see xSemaphoreCreateMutex().
+ *
+ * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,
+ * which will then be used to hold the semaphore's data structure, removing the
+ * need for the memory to be allocated dynamically.
+ *
+ * @return If the semaphore is created then a handle to the created semaphore is
+ * returned. If pxSemaphoreBuffer is NULL then NULL is returned.
+ *
+ * Example usage:
+ <pre>
+ SemaphoreHandle_t xSemaphore = NULL;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+ // The semaphore's data structures will be placed in the xSemaphoreBuffer
+ // variable, the address of which is passed into the function. The
+ // function's parameter is not NULL, so the function will not attempt any
+ // dynamic memory allocation, and therefore the function will not return
+ // return NULL.
+ xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
+
+ // Rest of task code goes here.
+ }
+ </pre>
+ * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic
* \ingroup Semaphores
*/
-#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+ #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
/**
* semphr. h
@@ -192,7 +271,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
* )</pre>
*
* <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
- * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
+ * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
* xSemaphoreCreateCounting().
*
* @param xSemaphore A handle to the semaphore being taken - obtained when
@@ -215,7 +294,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
void vATask( void * pvParameters )
{
// Create the semaphore to guard a shared resource.
- vSemaphoreCreateBinary( xSemaphore );
+ xSemaphore = xSemaphoreCreateBinary();
}
// A task that uses the semaphore.
@@ -270,8 +349,8 @@ typedef QueueHandle_t SemaphoreHandle_t;
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
- * if a task successfully 'takes' the same mutex 5 times then the mutex
- * is not available to any other task until it has also 'given' the mutex back
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will
+ * not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* @param xMutex A handle to the mutex being obtained. This is the
@@ -280,8 +359,8 @@ typedef QueueHandle_t SemaphoreHandle_t;
* @param xBlockTime The time in ticks to wait for the semaphore to become
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
* real time. A block time of zero can be used to poll the semaphore. If
- * the task already owns the semaphore then xSemaphoreTakeRecursive()
- * returns immediately no matter what the value of xBlockTime.
+ * the task already owns the semaphore then xSemaphoreTakeRecursive() will
+ * return immediately no matter what the value of xBlockTime.
*
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
* expired without the semaphore becoming available.
@@ -320,7 +399,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
- // The mutex has now been 'taken' three times, so is not
+ // The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back
// three times. Again it is unlikely that real code would have
// these calls sequentially, but instead buried in a more complex
@@ -342,29 +421,16 @@ typedef QueueHandle_t SemaphoreHandle_t;
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
* \ingroup Semaphores
*/
-#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
-
-
-/*
- * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
- *
- * The source code that implements the alternative (Alt) API is much
- * simpler because it executes everything from within a critical section.
- * This is the approach taken by many other RTOSes, but FreeRTOS.org has the
- * preferred fully featured API too. The fully featured API has more
- * complex code that takes longer to execute, but makes much less use of
- * critical sections. Therefore the alternative API sacrifices interrupt
- * responsiveness to gain execution speed, whereas the fully featured API
- * sacrifices execution speed to ensure better interrupt responsiveness.
- */
-#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
+#if( configUSE_RECURSIVE_MUTEXES == 1 )
+ #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
+#endif
/**
* semphr. h
* <pre>xSemaphoreGive( SemaphoreHandle_t xSemaphore )</pre>
*
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
- * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
+ * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
* xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
*
* This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
@@ -388,7 +454,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
void vATask( void * pvParameters )
{
// Create the semaphore to guard a shared resource.
- vSemaphoreCreateBinary( xSemaphore );
+ xSemaphore = vSemaphoreCreateBinary();
if( xSemaphore != NULL )
{
@@ -438,8 +504,8 @@ typedef QueueHandle_t SemaphoreHandle_t;
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
- * if a task successfully 'takes' the same mutex 5 times then the mutex is
- * not available to any other task until it has also 'given' the mutex back
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will
+ * not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* @param xMutex A handle to the mutex being released, or 'given'. This is the
@@ -481,7 +547,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
- // The mutex has now been 'taken' three times, so is not
+ // The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back
// three times. Again it is unlikely that real code would have
// these calls sequentially, it would be more likely that the calls
@@ -504,21 +570,9 @@ typedef QueueHandle_t SemaphoreHandle_t;
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
* \ingroup Semaphores
*/
-#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
-
-/*
- * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
- *
- * The source code that implements the alternative (Alt) API is much
- * simpler because it executes everything from within a critical section.
- * This is the approach taken by many other RTOSes, but FreeRTOS.org has the
- * preferred fully featured API too. The fully featured API has more
- * complex code that takes longer to execute, but makes much less use of
- * critical sections. Therefore the alternative API sacrifices interrupt
- * responsiveness to gain execution speed, whereas the fully featured API
- * sacrifices execution speed to ensure better interrupt responsiveness.
- */
-#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
+#if( configUSE_RECURSIVE_MUTEXES == 1 )
+ #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
+#endif
/**
* semphr. h
@@ -529,7 +583,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
)</pre>
*
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
- * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
+ * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting().
*
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
* must not be used with this macro.
@@ -539,7 +593,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
* @param xSemaphore A handle to the semaphore being released. This is the
* handle returned when the semaphore was created.
*
- * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() sets
+ * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
* *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
* to unblock, and the unblocked task has a priority higher than the currently
* running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then
@@ -569,7 +623,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
// ...
// We have finished our task. Return to the top of the loop where
- // we block on the semaphore until it is time to execute
+ // we will block on the semaphore until it is time to execute
// again. Note when using the semaphore for synchronisation with an
// ISR in this manner there is no need to 'give' the semaphore back.
}
@@ -620,7 +674,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
)</pre>
*
* <i>Macro</i> to take a semaphore from an ISR. The semaphore must have
- * previously been created with a call to vSemaphoreCreateBinary() or
+ * previously been created with a call to xSemaphoreCreateBinary() or
* xSemaphoreCreateCounting().
*
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
@@ -634,7 +688,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
* @param xSemaphore A handle to the semaphore being taken. This is the
* handle returned when the semaphore was created.
*
- * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() set
+ * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set
* *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task
* to unblock, and the unblocked task has a priority higher than the currently
* running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then
@@ -649,12 +703,21 @@ typedef QueueHandle_t SemaphoreHandle_t;
* semphr. h
* <pre>SemaphoreHandle_t xSemaphoreCreateMutex( void )</pre>
*
- * <i>Macro</i> that implements a mutex semaphore by using the existing queue
- * mechanism.
+ * Creates a new mutex type semaphore instance, and returns a handle by which
+ * the new mutex can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, mutex semaphores use a block
+ * of memory, in which the mutex structure is stored. If a mutex is created
+ * using xSemaphoreCreateMutex() then the required memory is automatically
+ * dynamically allocated inside the xSemaphoreCreateMutex() function. (see
+ * http://www.freertos.org/a00111.html). If a mutex is created using
+ * xSemaphoreCreateMutexStatic() then the application writer must provided the
+ * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created
+ * without using any dynamic memory allocation.
*
- * Mutexes created using this macro can be accessed using the xSemaphoreTake()
+ * Mutexes created using this function can be accessed using the xSemaphoreTake()
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
- * xSemaphoreGiveRecursive() macros should not be used.
+ * xSemaphoreGiveRecursive() macros must not be used.
*
* This type of semaphore uses a priority inheritance mechanism so a task
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
@@ -662,13 +725,14 @@ typedef QueueHandle_t SemaphoreHandle_t;
*
* Mutex type semaphores cannot be used from within interrupt service routines.
*
- * See vSemaphoreCreateBinary() for an alternative implementation that can be
+ * See xSemaphoreCreateBinary() for an alternative implementation that can be
* used for pure synchronisation (where one task or interrupt always 'gives' the
* semaphore and another always 'takes' the semaphore) and from within interrupt
* service routines.
*
- * @return xSemaphore Handle to the created mutex semaphore. Should be of type
- * SemaphoreHandle_t.
+ * @return If the mutex was successfully created then a handle to the created
+ * semaphore is returned. If there was not enough heap to allocate the mutex
+ * data structures then NULL is returned.
*
* Example usage:
<pre>
@@ -687,28 +751,102 @@ typedef QueueHandle_t SemaphoreHandle_t;
}
}
</pre>
- * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
+ * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+ #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
+#endif
+
+/**
+ * semphr. h
+ * <pre>SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )</pre>
+ *
+ * Creates a new mutex type semaphore instance, and returns a handle by which
+ * the new mutex can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, mutex semaphores use a block
+ * of memory, in which the mutex structure is stored. If a mutex is created
+ * using xSemaphoreCreateMutex() then the required memory is automatically
+ * dynamically allocated inside the xSemaphoreCreateMutex() function. (see
+ * http://www.freertos.org/a00111.html). If a mutex is created using
+ * xSemaphoreCreateMutexStatic() then the application writer must provided the
+ * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created
+ * without using any dynamic memory allocation.
+ *
+ * Mutexes created using this function can be accessed using the xSemaphoreTake()
+ * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
+ * xSemaphoreGiveRecursive() macros must not be used.
+ *
+ * This type of semaphore uses a priority inheritance mechanism so a task
+ * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
+ * semaphore it is no longer required.
+ *
+ * Mutex type semaphores cannot be used from within interrupt service routines.
+ *
+ * See xSemaphoreCreateBinary() for an alternative implementation that can be
+ * used for pure synchronisation (where one task or interrupt always 'gives' the
+ * semaphore and another always 'takes' the semaphore) and from within interrupt
+ * service routines.
+ *
+ * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,
+ * which will be used to hold the mutex's data structure, removing the need for
+ * the memory to be allocated dynamically.
+ *
+ * @return If the mutex was successfully created then a handle to the created
+ * mutex is returned. If pxMutexBuffer was NULL then NULL is returned.
+ *
+ * Example usage:
+ <pre>
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ // A mutex cannot be used before it has been created. xMutexBuffer is
+ // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
+ // attempted.
+ xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
+
+ // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+ // so there is no need to check it.
+ }
+ </pre>
+ * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic
* \ingroup Semaphores
*/
-#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
+ #if( configSUPPORT_STATIC_ALLOCATION == 1 )
+ #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
/**
* semphr. h
* <pre>SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )</pre>
*
- * <i>Macro</i> that implements a recursive mutex by using the existing queue
- * mechanism.
+ * Creates a new recursive mutex type semaphore instance, and returns a handle
+ * by which the new recursive mutex can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, recursive mutexs use a block
+ * of memory, in which the mutex structure is stored. If a recursive mutex is
+ * created using xSemaphoreCreateRecursiveMutex() then the required memory is
+ * automatically dynamically allocated inside the
+ * xSemaphoreCreateRecursiveMutex() function. (see
+ * http://www.freertos.org/a00111.html). If a recursive mutex is created using
+ * xSemaphoreCreateRecursiveMutexStatic() then the application writer must
+ * provide the memory that will get used by the mutex.
+ * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to
+ * be created without using any dynamic memory allocation.
*
* Mutexes created using this macro can be accessed using the
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
- * xSemaphoreTake() and xSemaphoreGive() macros should not be used.
+ * xSemaphoreTake() and xSemaphoreGive() macros must not be used.
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
- * if a task successfully 'takes' the same mutex 5 times then the mutex is
- * not available to any other task until it has also 'given' the mutex back
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will
+ * not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* This type of semaphore uses a priority inheritance mechanism so a task
@@ -717,13 +855,13 @@ typedef QueueHandle_t SemaphoreHandle_t;
*
* Mutex type semaphores cannot be used from within interrupt service routines.
*
- * See vSemaphoreCreateBinary() for an alternative implementation that can be
+ * See xSemaphoreCreateBinary() for an alternative implementation that can be
* used for pure synchronisation (where one task or interrupt always 'gives' the
* semaphore and another always 'takes' the semaphore) and from within interrupt
* service routines.
*
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
- * SemaphoreHandle_t.
+ * SemaphoreHandle_t.
*
* Example usage:
<pre>
@@ -742,25 +880,115 @@ typedef QueueHandle_t SemaphoreHandle_t;
}
}
</pre>
- * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
+ * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex
* \ingroup Semaphores
*/
-#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
+#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
+ #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
+#endif
+
+/**
+ * semphr. h
+ * <pre>SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )</pre>
+ *
+ * Creates a new recursive mutex type semaphore instance, and returns a handle
+ * by which the new recursive mutex can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, recursive mutexs use a block
+ * of memory, in which the mutex structure is stored. If a recursive mutex is
+ * created using xSemaphoreCreateRecursiveMutex() then the required memory is
+ * automatically dynamically allocated inside the
+ * xSemaphoreCreateRecursiveMutex() function. (see
+ * http://www.freertos.org/a00111.html). If a recursive mutex is created using
+ * xSemaphoreCreateRecursiveMutexStatic() then the application writer must
+ * provide the memory that will get used by the mutex.
+ * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to
+ * be created without using any dynamic memory allocation.
+ *
+ * Mutexes created using this macro can be accessed using the
+ * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
+ * xSemaphoreTake() and xSemaphoreGive() macros must not be used.
+ *
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
+ * doesn't become available again until the owner has called
+ * xSemaphoreGiveRecursive() for each successful 'take' request. For example,
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will
+ * not be available to any other task until it has also 'given' the mutex back
+ * exactly five times.
+ *
+ * This type of semaphore uses a priority inheritance mechanism so a task
+ * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
+ * semaphore it is no longer required.
+ *
+ * Mutex type semaphores cannot be used from within interrupt service routines.
+ *
+ * See xSemaphoreCreateBinary() for an alternative implementation that can be
+ * used for pure synchronisation (where one task or interrupt always 'gives' the
+ * semaphore and another always 'takes' the semaphore) and from within interrupt
+ * service routines.
+ *
+ * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,
+ * which will then be used to hold the recursive mutex's data structure,
+ * removing the need for the memory to be allocated dynamically.
+ *
+ * @return If the recursive mutex was successfully created then a handle to the
+ * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is
+ * returned.
+ *
+ * Example usage:
+ <pre>
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ // A recursive semaphore cannot be used before it is created. Here a
+ // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
+ // The address of xMutexBuffer is passed into the function, and will hold
+ // the mutexes data structures - so no dynamic memory allocation will be
+ // attempted.
+ xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
+
+ // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+ // so there is no need to check it.
+ }
+ </pre>
+ * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic
+ * \ingroup Semaphores
+ */
+#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
+ #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
/**
* semphr. h
* <pre>SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )</pre>
*
- * <i>Macro</i> that creates a counting semaphore by using the existing
- * queue mechanism.
+ * Creates a new counting semaphore instance, and returns a handle by which the
+ * new counting semaphore can be referenced.
+ *
+ * In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a counting semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
+ * Internally, within the FreeRTOS implementation, counting semaphores use a
+ * block of memory, in which the counting semaphore structure is stored. If a
+ * counting semaphore is created using xSemaphoreCreateCounting() then the
+ * required memory is automatically dynamically allocated inside the
+ * xSemaphoreCreateCounting() function. (see
+ * http://www.freertos.org/a00111.html). If a counting semaphore is created
+ * using xSemaphoreCreateCountingStatic() then the application writer can
+ * instead optionally provide the memory that will get used by the counting
+ * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting
+ * semaphore to be created without using any dynamic memory allocation.
*
* Counting semaphores are typically used for two things:
*
* 1) Counting events.
*
- * In this usage scenario an event handler 'gives' a semaphore each time
+ * In this usage scenario an event handler will 'give' a semaphore each time
* an event occurs (incrementing the semaphore count value), and a handler
- * task 'takes' a semaphore each time it processes an event
+ * task will 'take' a semaphore each time it processes an event
* (decrementing the semaphore count value). The count value is therefore
* the difference between the number of events that have occurred and the
* number that have been processed. In this case it is desirable for the
@@ -808,7 +1036,94 @@ typedef QueueHandle_t SemaphoreHandle_t;
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
* \ingroup Semaphores
*/
-#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+ #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
+#endif
+
+/**
+ * semphr. h
+ * <pre>SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )</pre>
+ *
+ * Creates a new counting semaphore instance, and returns a handle by which the
+ * new counting semaphore can be referenced.
+ *
+ * In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a counting semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
+ * Internally, within the FreeRTOS implementation, counting semaphores use a
+ * block of memory, in which the counting semaphore structure is stored. If a
+ * counting semaphore is created using xSemaphoreCreateCounting() then the
+ * required memory is automatically dynamically allocated inside the
+ * xSemaphoreCreateCounting() function. (see
+ * http://www.freertos.org/a00111.html). If a counting semaphore is created
+ * using xSemaphoreCreateCountingStatic() then the application writer must
+ * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a
+ * counting semaphore to be created without using any dynamic memory allocation.
+ *
+ * Counting semaphores are typically used for two things:
+ *
+ * 1) Counting events.
+ *
+ * In this usage scenario an event handler will 'give' a semaphore each time
+ * an event occurs (incrementing the semaphore count value), and a handler
+ * task will 'take' a semaphore each time it processes an event
+ * (decrementing the semaphore count value). The count value is therefore
+ * the difference between the number of events that have occurred and the
+ * number that have been processed. In this case it is desirable for the
+ * initial count value to be zero.
+ *
+ * 2) Resource management.
+ *
+ * In this usage scenario the count value indicates the number of resources
+ * available. To obtain control of a resource a task must first obtain a
+ * semaphore - decrementing the semaphore count value. When the count value
+ * reaches zero there are no free resources. When a task finishes with the
+ * resource it 'gives' the semaphore back - incrementing the semaphore count
+ * value. In this case it is desirable for the initial count value to be
+ * equal to the maximum count value, indicating that all resources are free.
+ *
+ * @param uxMaxCount The maximum count value that can be reached. When the
+ * semaphore reaches this value it can no longer be 'given'.
+ *
+ * @param uxInitialCount The count value assigned to the semaphore when it is
+ * created.
+ *
+ * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,
+ * which will then be used to hold the semaphore's data structure, removing the
+ * need for the memory to be allocated dynamically.
+ *
+ * @return If the counting semaphore was successfully created then a handle to
+ * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL
+ * then NULL is returned.
+ *
+ * Example usage:
+ <pre>
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // Counting semaphore cannot be used before they have been created. Create
+ // a counting semaphore using xSemaphoreCreateCountingStatic(). The max
+ // value to which the semaphore can count is 10, and the initial value
+ // assigned to the count will be 0. The address of xSemaphoreBuffer is
+ // passed in and will be used to hold the semaphore structure, so no dynamic
+ // memory allocation will be used.
+ xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
+
+ // No memory allocation was attempted so xSemaphore cannot be NULL, so there
+ // is no need to check its value.
+ }
+ </pre>
+ * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+ #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
/**
* semphr. h
@@ -839,6 +1154,18 @@ typedef QueueHandle_t SemaphoreHandle_t;
*/
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
+/**
+ * semphr.h
+ * <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre>
+ *
+ * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns
+ * its current count value. If the semaphore is a binary semaphore then
+ * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the
+ * semaphore is not available.
+ *
+ */
+#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
+
#endif /* SEMAPHORE_H */