/* | |
* FreeRTOS Kernel V10.3.1 | |
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy of | |
* this software and associated documentation files (the "Software"), to deal in | |
* the Software without restriction, including without limitation the rights to | |
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | |
* the Software, and to permit persons to whom the Software is furnished to do so, | |
* subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in all | |
* copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | |
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
* | |
* http://www.FreeRTOS.org | |
* http://aws.amazon.com/freertos | |
* | |
* 1 tab == 4 spaces! | |
*/ | |
#ifndef EVENT_GROUPS_H | |
#define EVENT_GROUPS_H | |
#ifndef INC_FREERTOS_H | |
#error "include FreeRTOS.h" must appear in source files before "include event_groups.h" | |
#endif | |
/* FreeRTOS includes. */ | |
#include "timers.h" | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
/** | |
* An event group is a collection of bits to which an application can assign a | |
* meaning. For example, an application may create an event group to convey | |
* the status of various CAN bus related events in which bit 0 might mean "A CAN | |
* message has been received and is ready for processing", bit 1 might mean "The | |
* application has queued a message that is ready for sending onto the CAN | |
* network", and bit 2 might mean "It is time to send a SYNC message onto the | |
* CAN network" etc. A task can then test the bit values to see which events | |
* are active, and optionally enter the Blocked state to wait for a specified | |
* bit or a group of specified bits to be active. To continue the CAN bus | |
* example, a CAN controlling task can enter the Blocked state (and therefore | |
* not consume any processing time) until either bit 0, bit 1 or bit 2 are | |
* active, at which time the bit that was actually active would inform the task | |
* which action it had to take (process a received message, send a message, or | |
* send a SYNC). | |
* | |
* The event groups implementation contains intelligence to avoid race | |
* conditions that would otherwise occur were an application to use a simple | |
* variable for the same purpose. This is particularly important with respect | |
* to when a bit within an event group is to be cleared, and when bits have to | |
* be set and then tested atomically - as is the case where event groups are | |
* used to create a synchronisation point between multiple tasks (a | |
* 'rendezvous'). | |
* | |
* \defgroup EventGroup | |
*/ | |
/** | |
* event_groups.h | |
* | |
* Type by which event groups are referenced. For example, a call to | |
* xEventGroupCreate() returns an EventGroupHandle_t variable that can then | |
* be used as a parameter to other event group functions. | |
* | |
* \defgroup EventGroupHandle_t EventGroupHandle_t | |
* \ingroup EventGroup | |
*/ | |
struct EventGroupDef_t; | |
typedef struct EventGroupDef_t * EventGroupHandle_t; | |
/* | |
* The type that holds event bits always matches TickType_t - therefore the | |
* number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, | |
* 32 bits if set to 0. | |
* | |
* \defgroup EventBits_t EventBits_t | |
* \ingroup EventGroup | |
*/ | |
typedef TickType_t EventBits_t; | |
/** | |
* event_groups.h | |
*<pre> | |
EventGroupHandle_t xEventGroupCreate( void ); | |
</pre> | |
* | |
* Create a new event group. | |
* | |
* Internally, within the FreeRTOS implementation, event groups use a [small] | |
* block of memory, in which the event group's structure is stored. If an event | |
* groups is created using xEventGropuCreate() then the required memory is | |
* automatically dynamically allocated inside the xEventGroupCreate() function. | |
* (see http://www.freertos.org/a00111.html). If an event group is created | |
* using xEventGropuCreateStatic() then the application writer must instead | |
* provide the memory that will get used by the event group. | |
* xEventGroupCreateStatic() therefore allows an event group to be created | |
* without using any dynamic memory allocation. | |
* | |
* Although event groups are not related to ticks, for internal implementation | |
* reasons the number of bits available for use in an event group is dependent | |
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If | |
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit | |
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has | |
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store | |
* event bits within an event group. | |
* | |
* @return If the event group was created then a handle to the event group is | |
* returned. If there was insufficient FreeRTOS heap available to create the | |
* event group then NULL is returned. See http://www.freertos.org/a00111.html | |
* | |
* Example usage: | |
<pre> | |
// Declare a variable to hold the created event group. | |
EventGroupHandle_t xCreatedEventGroup; | |
// Attempt to create the event group. | |
xCreatedEventGroup = xEventGroupCreate(); | |
// Was the event group created successfully? | |
if( xCreatedEventGroup == NULL ) | |
{ | |
// The event group was not created because there was insufficient | |
// FreeRTOS heap available. | |
} | |
else | |
{ | |
// The event group was created. | |
} | |
</pre> | |
* \defgroup xEventGroupCreate xEventGroupCreate | |
* \ingroup EventGroup | |
*/ | |
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) | |
EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; | |
#endif | |
/** | |
* event_groups.h | |
*<pre> | |
EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer ); | |
</pre> | |
* | |
* Create a new event group. | |
* | |
* Internally, within the FreeRTOS implementation, event groups use a [small] | |
* block of memory, in which the event group's structure is stored. If an event | |
* groups is created using xEventGropuCreate() then the required memory is | |
* automatically dynamically allocated inside the xEventGroupCreate() function. | |
* (see http://www.freertos.org/a00111.html). If an event group is created | |
* using xEventGropuCreateStatic() then the application writer must instead | |
* provide the memory that will get used by the event group. | |
* xEventGroupCreateStatic() therefore allows an event group to be created | |
* without using any dynamic memory allocation. | |
* | |
* Although event groups are not related to ticks, for internal implementation | |
* reasons the number of bits available for use in an event group is dependent | |
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If | |
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit | |
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has | |
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store | |
* event bits within an event group. | |
* | |
* @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type | |
* StaticEventGroup_t, which will be then be used to hold the event group's data | |
* structures, removing the need for the memory to be allocated dynamically. | |
* | |
* @return If the event group was created then a handle to the event group is | |
* returned. If pxEventGroupBuffer was NULL then NULL is returned. | |
* | |
* Example usage: | |
<pre> | |
// StaticEventGroup_t is a publicly accessible structure that has the same | |
// size and alignment requirements as the real event group structure. It is | |
// provided as a mechanism for applications to know the size of the event | |
// group (which is dependent on the architecture and configuration file | |
// settings) without breaking the strict data hiding policy by exposing the | |
// real event group internals. This StaticEventGroup_t variable is passed | |
// into the xSemaphoreCreateEventGroupStatic() function and is used to store | |
// the event group's data structures | |
StaticEventGroup_t xEventGroupBuffer; | |
// Create the event group without dynamically allocating any memory. | |
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); | |
</pre> | |
*/ | |
#if( configSUPPORT_STATIC_ALLOCATION == 1 ) | |
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION; | |
#endif | |
/** | |
* event_groups.h | |
*<pre> | |
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, | |
const EventBits_t uxBitsToWaitFor, | |
const BaseType_t xClearOnExit, | |
const BaseType_t xWaitForAllBits, | |
const TickType_t xTicksToWait ); | |
</pre> | |
* | |
* [Potentially] block to wait for one or more bits to be set within a | |
* previously created event group. | |
* | |
* This function cannot be called from an interrupt. | |
* | |
* @param xEventGroup The event group in which the bits are being tested. The | |
* event group must have previously been created using a call to | |
* xEventGroupCreate(). | |
* | |
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test | |
* inside the event group. For example, to wait for bit 0 and/or bit 2 set | |
* uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set | |
* uxBitsToWaitFor to 0x07. Etc. | |
* | |
* @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within | |
* uxBitsToWaitFor that are set within the event group will be cleared before | |
* xEventGroupWaitBits() returns if the wait condition was met (if the function | |
* returns for a reason other than a timeout). If xClearOnExit is set to | |
* pdFALSE then the bits set in the event group are not altered when the call to | |
* xEventGroupWaitBits() returns. | |
* | |
* @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then | |
* xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor | |
* are set or the specified block time expires. If xWaitForAllBits is set to | |
* pdFALSE then xEventGroupWaitBits() will return when any one of the bits set | |
* in uxBitsToWaitFor is set or the specified block time expires. The block | |
* time is specified by the xTicksToWait parameter. | |
* | |
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait | |
* for one/all (depending on the xWaitForAllBits value) of the bits specified by | |
* uxBitsToWaitFor to become set. | |
* | |
* @return The value of the event group at the time either the bits being waited | |
* for became set, or the block time expired. Test the return value to know | |
* which bits were set. If xEventGroupWaitBits() returned because its timeout | |
* expired then not all the bits being waited for will be set. If | |
* xEventGroupWaitBits() returned because the bits it was waiting for were set | |
* then the returned value is the event group value before any bits were | |
* automatically cleared in the case that xClearOnExit parameter was set to | |
* pdTRUE. | |
* | |
* Example usage: | |
<pre> | |
#define BIT_0 ( 1 << 0 ) | |
#define BIT_4 ( 1 << 4 ) | |
void aFunction( EventGroupHandle_t xEventGroup ) | |
{ | |
EventBits_t uxBits; | |
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; | |
// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within | |
// the event group. Clear the bits before exiting. | |
uxBits = xEventGroupWaitBits( | |
xEventGroup, // The event group being tested. | |
BIT_0 | BIT_4, // The bits within the event group to wait for. | |
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning. | |
pdFALSE, // Don't wait for both bits, either bit will do. | |
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set. | |
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) | |
{ | |
// xEventGroupWaitBits() returned because both bits were set. | |
} | |
else if( ( uxBits & BIT_0 ) != 0 ) | |
{ | |
// xEventGroupWaitBits() returned because just BIT_0 was set. | |
} | |
else if( ( uxBits & BIT_4 ) != 0 ) | |
{ | |
// xEventGroupWaitBits() returned because just BIT_4 was set. | |
} | |
else | |
{ | |
// xEventGroupWaitBits() returned because xTicksToWait ticks passed | |
// without either BIT_0 or BIT_4 becoming set. | |
} | |
} | |
</pre> | |
* \defgroup xEventGroupWaitBits xEventGroupWaitBits | |
* \ingroup EventGroup | |
*/ | |
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; | |
/** | |
* event_groups.h | |
*<pre> | |
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); | |
</pre> | |
* | |
* Clear bits within an event group. This function cannot be called from an | |
* interrupt. | |
* | |
* @param xEventGroup The event group in which the bits are to be cleared. | |
* | |
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear | |
* in the event group. For example, to clear bit 3 only, set uxBitsToClear to | |
* 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. | |
* | |
* @return The value of the event group before the specified bits were cleared. | |
* | |
* Example usage: | |
<pre> | |
#define BIT_0 ( 1 << 0 ) | |
#define BIT_4 ( 1 << 4 ) | |
void aFunction( EventGroupHandle_t xEventGroup ) | |
{ | |
EventBits_t uxBits; | |
// Clear bit 0 and bit 4 in xEventGroup. | |
uxBits = xEventGroupClearBits( | |
xEventGroup, // The event group being updated. | |
BIT_0 | BIT_4 );// The bits being cleared. | |
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) | |
{ | |
// Both bit 0 and bit 4 were set before xEventGroupClearBits() was | |
// called. Both will now be clear (not set). | |
} | |
else if( ( uxBits & BIT_0 ) != 0 ) | |
{ | |
// Bit 0 was set before xEventGroupClearBits() was called. It will | |
// now be clear. | |
} | |
else if( ( uxBits & BIT_4 ) != 0 ) | |
{ | |
// Bit 4 was set before xEventGroupClearBits() was called. It will | |
// now be clear. | |
} | |
else | |
{ | |
// Neither bit 0 nor bit 4 were set in the first place. | |
} | |
} | |
</pre> | |
* \defgroup xEventGroupClearBits xEventGroupClearBits | |
* \ingroup EventGroup | |
*/ | |
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; | |
/** | |
* event_groups.h | |
*<pre> | |
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); | |
</pre> | |
* | |
* A version of xEventGroupClearBits() that can be called from an interrupt. | |
* | |
* Setting bits in an event group is not a deterministic operation because there | |
* are an unknown number of tasks that may be waiting for the bit or bits being | |
* set. FreeRTOS does not allow nondeterministic operations to be performed | |
* while interrupts are disabled, so protects event groups that are accessed | |
* from tasks by suspending the scheduler rather than disabling interrupts. As | |
* a result event groups cannot be accessed directly from an interrupt service | |
* routine. Therefore xEventGroupClearBitsFromISR() sends a message to the | |
* timer task to have the clear operation performed in the context of the timer | |
* task. | |
* | |
* @param xEventGroup The event group in which the bits are to be cleared. | |
* | |
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. | |
* For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 | |
* and bit 0 set uxBitsToClear to 0x09. | |
* | |
* @return If the request to execute the function was posted successfully then | |
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned | |
* if the timer service queue was full. | |
* | |
* Example usage: | |
<pre> | |
#define BIT_0 ( 1 << 0 ) | |
#define BIT_4 ( 1 << 4 ) | |
// An event group which it is assumed has already been created by a call to | |
// xEventGroupCreate(). | |
EventGroupHandle_t xEventGroup; | |
void anInterruptHandler( void ) | |
{ | |
// Clear bit 0 and bit 4 in xEventGroup. | |
xResult = xEventGroupClearBitsFromISR( | |
xEventGroup, // The event group being updated. | |
BIT_0 | BIT_4 ); // The bits being set. | |
if( xResult == pdPASS ) | |
{ | |
// The message was posted successfully. | |
} | |
} | |
</pre> | |
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR | |
* \ingroup EventGroup | |
*/ | |
#if( configUSE_TRACE_FACILITY == 1 ) | |
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; | |
#else | |
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) | |
#endif | |
/** | |
* event_groups.h | |
*<pre> | |
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); | |
</pre> | |
* | |
* Set bits within an event group. | |
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() | |
* is a version that can be called from an interrupt. | |
* | |
* Setting bits in an event group will automatically unblock tasks that are | |
* blocked waiting for the bits. | |
* | |
* @param xEventGroup The event group in which the bits are to be set. | |
* | |
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set. | |
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 | |
* and bit 0 set uxBitsToSet to 0x09. | |
* | |
* @return The value of the event group at the time the call to | |
* xEventGroupSetBits() returns. There are two reasons why the returned value | |
* might have the bits specified by the uxBitsToSet parameter cleared. First, | |
* if setting a bit results in a task that was waiting for the bit leaving the | |
* blocked state then it is possible the bit will be cleared automatically | |
* (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any | |
* unblocked (or otherwise Ready state) task that has a priority above that of | |
* the task that called xEventGroupSetBits() will execute and may change the | |
* event group value before the call to xEventGroupSetBits() returns. | |
* | |
* Example usage: | |
<pre> | |
#define BIT_0 ( 1 << 0 ) | |
#define BIT_4 ( 1 << 4 ) | |
void aFunction( EventGroupHandle_t xEventGroup ) | |
{ | |
EventBits_t uxBits; | |
// Set bit 0 and bit 4 in xEventGroup. | |
uxBits = xEventGroupSetBits( | |
xEventGroup, // The event group being updated. | |
BIT_0 | BIT_4 );// The bits being set. | |
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) | |
{ | |
// Both bit 0 and bit 4 remained set when the function returned. | |
} | |
else if( ( uxBits & BIT_0 ) != 0 ) | |
{ | |
// Bit 0 remained set when the function returned, but bit 4 was | |
// cleared. It might be that bit 4 was cleared automatically as a | |
// task that was waiting for bit 4 was removed from the Blocked | |
// state. | |
} | |
else if( ( uxBits & BIT_4 ) != 0 ) | |
{ | |
// Bit 4 remained set when the function returned, but bit 0 was | |
// cleared. It might be that bit 0 was cleared automatically as a | |
// task that was waiting for bit 0 was removed from the Blocked | |
// state. | |
} | |
else | |
{ | |
// Neither bit 0 nor bit 4 remained set. It might be that a task | |
// was waiting for both of the bits to be set, and the bits were | |
// cleared as the task left the Blocked state. | |
} | |
} | |
</pre> | |
* \defgroup xEventGroupSetBits xEventGroupSetBits | |
* \ingroup EventGroup | |
*/ | |
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; | |
/** | |
* event_groups.h | |
*<pre> | |
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); | |
</pre> | |
* | |
* A version of xEventGroupSetBits() that can be called from an interrupt. | |
* | |
* Setting bits in an event group is not a deterministic operation because there | |
* are an unknown number of tasks that may be waiting for the bit or bits being | |
* set. FreeRTOS does not allow nondeterministic operations to be performed in | |
* interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() | |
* sends a message to the timer task to have the set operation performed in the | |
* context of the timer task - where a scheduler lock is used in place of a | |
* critical section. | |
* | |
* @param xEventGroup The event group in which the bits are to be set. | |
* | |
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set. | |
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 | |
* and bit 0 set uxBitsToSet to 0x09. | |
* | |
* @param pxHigherPriorityTaskWoken As mentioned above, calling this function | |
* will result in a message being sent to the timer daemon task. If the | |
* priority of the timer daemon task is higher than the priority of the | |
* currently running task (the task the interrupt interrupted) then | |
* *pxHigherPriorityTaskWoken will be set to pdTRUE by | |
* xEventGroupSetBitsFromISR(), indicating that a context switch should be | |
* requested before the interrupt exits. For that reason | |
* *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the | |
* example code below. | |
* | |
* @return If the request to execute the function was posted successfully then | |
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned | |
* if the timer service queue was full. | |
* | |
* Example usage: | |
<pre> | |
#define BIT_0 ( 1 << 0 ) | |
#define BIT_4 ( 1 << 4 ) | |
// An event group which it is assumed has already been created by a call to | |
// xEventGroupCreate(). | |
EventGroupHandle_t xEventGroup; | |
void anInterruptHandler( void ) | |
{ | |
BaseType_t xHigherPriorityTaskWoken, xResult; | |
// xHigherPriorityTaskWoken must be initialised to pdFALSE. | |
xHigherPriorityTaskWoken = pdFALSE; | |
// Set bit 0 and bit 4 in xEventGroup. | |
xResult = xEventGroupSetBitsFromISR( | |
xEventGroup, // The event group being updated. | |
BIT_0 | BIT_4 // The bits being set. | |
&xHigherPriorityTaskWoken ); | |
// Was the message posted successfully? | |
if( xResult == pdPASS ) | |
{ | |
// If xHigherPriorityTaskWoken is now set to pdTRUE then a context | |
// switch should be requested. The macro used is port specific and | |
// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - | |
// refer to the documentation page for the port being used. | |
portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); | |
} | |
} | |
</pre> | |
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR | |
* \ingroup EventGroup | |
*/ | |
#if( configUSE_TRACE_FACILITY == 1 ) | |
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; | |
#else | |
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) | |
#endif | |
/** | |
* event_groups.h | |
*<pre> | |
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, | |
const EventBits_t uxBitsToSet, | |
const EventBits_t uxBitsToWaitFor, | |
TickType_t xTicksToWait ); | |
</pre> | |
* | |
* Atomically set bits within an event group, then wait for a combination of | |
* bits to be set within the same event group. This functionality is typically | |
* used to synchronise multiple tasks, where each task has to wait for the other | |
* tasks to reach a synchronisation point before proceeding. | |
* | |
* This function cannot be used from an interrupt. | |
* | |
* The function will return before its block time expires if the bits specified | |
* by the uxBitsToWait parameter are set, or become set within that time. In | |
* this case all the bits specified by uxBitsToWait will be automatically | |
* cleared before the function returns. | |
* | |
* @param xEventGroup The event group in which the bits are being tested. The | |
* event group must have previously been created using a call to | |
* xEventGroupCreate(). | |
* | |
* @param uxBitsToSet The bits to set in the event group before determining | |
* if, and possibly waiting for, all the bits specified by the uxBitsToWait | |
* parameter are set. | |
* | |
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test | |
* inside the event group. For example, to wait for bit 0 and bit 2 set | |
* uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set | |
* uxBitsToWaitFor to 0x07. Etc. | |
* | |
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait | |
* for all of the bits specified by uxBitsToWaitFor to become set. | |
* | |
* @return The value of the event group at the time either the bits being waited | |
* for became set, or the block time expired. Test the return value to know | |
* which bits were set. If xEventGroupSync() returned because its timeout | |
* expired then not all the bits being waited for will be set. If | |
* xEventGroupSync() returned because all the bits it was waiting for were | |
* set then the returned value is the event group value before any bits were | |
* automatically cleared. | |
* | |
* Example usage: | |
<pre> | |
// Bits used by the three tasks. | |
#define TASK_0_BIT ( 1 << 0 ) | |
#define TASK_1_BIT ( 1 << 1 ) | |
#define TASK_2_BIT ( 1 << 2 ) | |
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT ) | |
// Use an event group to synchronise three tasks. It is assumed this event | |
// group has already been created elsewhere. | |
EventGroupHandle_t xEventBits; | |
void vTask0( void *pvParameters ) | |
{ | |
EventBits_t uxReturn; | |
TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; | |
for( ;; ) | |
{ | |
// Perform task functionality here. | |
// Set bit 0 in the event flag to note this task has reached the | |
// sync point. The other two tasks will set the other two bits defined | |
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation | |
// point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms | |
// for this to happen. | |
uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait ); | |
if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS ) | |
{ | |
// All three tasks reached the synchronisation point before the call | |
// to xEventGroupSync() timed out. | |
} | |
} | |
} | |
void vTask1( void *pvParameters ) | |
{ | |
for( ;; ) | |
{ | |
// Perform task functionality here. | |
// Set bit 1 in the event flag to note this task has reached the | |
// synchronisation point. The other two tasks will set the other two | |
// bits defined by ALL_SYNC_BITS. All three tasks have reached the | |
// synchronisation point when all the ALL_SYNC_BITS are set. Wait | |
// indefinitely for this to happen. | |
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY ); | |
// xEventGroupSync() was called with an indefinite block time, so | |
// this task will only reach here if the syncrhonisation was made by all | |
// three tasks, so there is no need to test the return value. | |
} | |
} | |
void vTask2( void *pvParameters ) | |
{ | |
for( ;; ) | |
{ | |
// Perform task functionality here. | |
// Set bit 2 in the event flag to note this task has reached the | |
// synchronisation point. The other two tasks will set the other two | |
// bits defined by ALL_SYNC_BITS. All three tasks have reached the | |
// synchronisation point when all the ALL_SYNC_BITS are set. Wait | |
// indefinitely for this to happen. | |
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY ); | |
// xEventGroupSync() was called with an indefinite block time, so | |
// this task will only reach here if the syncrhonisation was made by all | |
// three tasks, so there is no need to test the return value. | |
} | |
} | |
</pre> | |
* \defgroup xEventGroupSync xEventGroupSync | |
* \ingroup EventGroup | |
*/ | |
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; | |
/** | |
* event_groups.h | |
*<pre> | |
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); | |
</pre> | |
* | |
* Returns the current value of the bits in an event group. This function | |
* cannot be used from an interrupt. | |
* | |
* @param xEventGroup The event group being queried. | |
* | |
* @return The event group bits at the time xEventGroupGetBits() was called. | |
* | |
* \defgroup xEventGroupGetBits xEventGroupGetBits | |
* \ingroup EventGroup | |
*/ | |
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) | |
/** | |
* event_groups.h | |
*<pre> | |
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); | |
</pre> | |
* | |
* A version of xEventGroupGetBits() that can be called from an ISR. | |
* | |
* @param xEventGroup The event group being queried. | |
* | |
* @return The event group bits at the time xEventGroupGetBitsFromISR() was called. | |
* | |
* \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR | |
* \ingroup EventGroup | |
*/ | |
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; | |
/** | |
* event_groups.h | |
*<pre> | |
void xEventGroupDelete( EventGroupHandle_t xEventGroup ); | |
</pre> | |
* | |
* Delete an event group that was previously created by a call to | |
* xEventGroupCreate(). Tasks that are blocked on the event group will be | |
* unblocked and obtain 0 as the event group's value. | |
* | |
* @param xEventGroup The event group being deleted. | |
*/ | |
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; | |
/* For internal use only. */ | |
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; | |
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; | |
#if (configUSE_TRACE_FACILITY == 1) | |
UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION; | |
void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; | |
#endif | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif /* EVENT_GROUPS_H */ | |