事件组和事件标志位 API 函数
- xEventGroupCreate
- xEventGroupCreateStatic
- xEventGroupWaitBits
- xEventGroupSetBits
- xEventGroupSetBitsFromISR
- xEventGroupClearBits
- xEventGroupClearBitsFromISR
- xEventGroupGetBits
- xEventGroupGetBitsFromISR
- xEventGroupSync
- vEventGroupDelete
1-xEventGroupCreate()
提示: 在许多情况下,“任务通知”可以提供替代事件组的轻量级方案
event_groups.h
EventGroupHandle_t xEventGroupCreate( void );
创建一个新的 RTOS 事件组,并返回 可以引用新创建的事件组的句柄。
要使此 RTOS API 函数可用:
configSUPPORT_DYNAMIC_ALLOCATION 必须在 FreeRTOSConfig.h 中设置为 1,或保留未定义状态(此时 默认为 1)。
RTOS 源文件 FreeRTOS/source/event_groups.c 必须 包含在构建中。
每个事件组都需要非常少量 RAM 来保存 事件组的状态。 如果使用 xEventGroupCreate() 创建事件组, 则会从 RAM 堆FreeRTOS中自动分配所需的 。 如果使用 xEventGroupCreateStatic() 创建事件组 则 RAM 由应用程序编写者提供,这需要用到一个附加参数, 但允许在编译时静态分配 RAM 。
事件组存储在 EventBits_t 类型的变量中。 如 果 configUSE_16_bit_TICKS 设置为 1,则事件组内实现的位(或标志)数为 8; 如果 configUSE_16_bit_TICKS 设置为 0,则为 24。 依赖于 configUSE_16_BIT_TICKS 的值 取决于 RTOS 任务内部实现中用于线程本地存储的数据类型。
参数:
无
Returns:
如果创建了事件组, 则返回事件组的句柄。 如果没有足够的 FreeRTOS 堆可用于创建事件组, 则返回 NULL。
用法示例:
/* 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. */
}
2-xEventGroupCreateStatic
提示: 在许多情况下,“任务通知”可以提供替代事件组的轻量级方案
event_groups.h
EventGroupHandle_t xEventGroupCreateStatic(
StaticEventGroup_t *pxEventGroupBuffer );
创建一个新的 RTOS 事件组,并返回 可以引用新创建的事件组的句柄。 configSUPPORT_STATIC_ALLOCATION 必须在 FreeRTOSConfig.h 中设置为 1,并且 RTOS 源文件 FreeRTOS/source/event_groups.c 必须 包含在构建中,xEventGroupCreateStatic() 函数才可用。
每个事件组都需要[非常]少量 RAM 来保存 事件组的状态。 如果使用 xEventGroupCreate() 创建事件组, 则会从 RAM 堆FreeRTOS中自动分配所需的 。 如果使用 xEventGroupCreateStatic() 创建事件组, 则 RAM 由应用程序编写者提供,这需要用到一个附加参数, 但允许在编译时静态分配 RAM 。
事件组存储在 EventBits_t 类型的变量中。 如 果 configUSE_16_bit_TICKS 设置为 1,则事件组内实现的位(或标志)数为 8; 如果 configUSE_16_bit_TICKS 设置为 0,则为 24。 依赖于 configUSE_16_BIT_TICKS 的值 取决于 RTOS 任务内部实现中用于线程本地存储的数据类型。
参数:
pxEventGroupBuffer 必须指向 StaticEventGroup_t 类型的变量, 该变量用于存储事件组数据结构体。
Returns:
如果成功创建了事件组, 则返回事件组的句柄。 如果 pxEventGroupBuffer 为 NULL,则返回 NULL。
用法示例:
/* Declare a variable to hold the handle of the created event group. */
EventGroupHandle_t xEventGroupHandle;
/* Declare a variable to hold the data associated with the created
event group. */
StaticEventGroup_t xCreatedEventGroup;
/* Attempt to create the event group. */
xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup );
/* pxEventGroupBuffer was not null so expect the event group to have
been created? */
configASSERT( xEventGroupHandle );
3-vEventGroupDelete()
event_groups.h
void vEventGroupDelete( EventGroupHandle_t xEventGroup );
删除先前的事件组, 该事件组通过调用 xEventGroupCreate() 创建。
在被删除的事件组上阻塞的任务将被取消阻塞,并且 报告事件组值为 0。
要使 vEventGroupDelete() 函数可用,RTOS 源文件 FreeRTOS/source/event_groups.c 必须 包含在构建中。
无法从中断调用此函数。
参数:
xEventGroup 要删除的事件组。
Returns:
无。
4-xEventGroupWaitBits()
event_groups.h
EventBits_t xEventGroupWaitBits(
const EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait );
读取 RTOS 事件组中的位,选择性地进入“已阻塞”状态(已设置 超时值)以等待设置单个位或一组位。
无法从中断调用此函数。
要使 xEventGroupWaitBits() 函数可用,RTOS 源文件 FreeRTOS/source/event_groups.c 必须 包含在构建中。
参数:
xEventGroup 正在测试位的事件组。 此前 必须已通过 xEventGroupCreate() 创建好事件组。
uxBitsToWaitFor 指定事件组中要测试的一个或多个事件位 的按位值。 例如,要等待第 0 位和/或第 2 位, 请将 uxBitsToWaitFor 设置为 0x05。 要等待第 0 位和/或第 1 位和/或第 2 位, 请设置 uxBitsToWaitFor 为 0x07, 以此类推。
uxBitsToWaitFor 不得设置为 0。
xClearOnExit 如果 xClearOnExit 设置为 pdTRUE, 那么在作为 uxBitsToWaitFor 参数传递的值中设置的任何位 会在 xEventGroupWaitBits() 返回某个值之前在事件组中清除掉, 前提是 xEventGroupWaitBits() 因超时以外的原因而返回值 。 超时值由 xTicksToWait 参数设置。
如果 xClearOnExit 设置为 pdFALSE, 那么当调用 xEventGroupWaitBits() 返回时,事件组中设置的位不会改变。
xWaitForAllBits xWaitForAllBits 用于创建逻辑与测试 (必须设置所有位)或逻辑或测试(必须设置一个 或多个位),如下所示:
如果 xWaitForAllBits 设置为 pdTRUE, 那么当在作为 uxBitsToWaitFor 参数传递的值中设置的所有位 均已在事件组中设置好,或指定的阻塞时间已过期,则 xEventGroupWaitBits() 会返回相应值。
如果 xWaitForAllBits 设置为 pdFALSE,那么当在作为 uxBitsToWaitFor 参数传递的值中设置的任何位已在事件组中设置好, 或指定的阻塞时间已过期,则 xEventGroupWaitBits() 会返回相应值。
xTicksToWait 等待 uxBitsToWaitFor 指定的一个/所有(取决于 xWaitForAllBits 的值)位完成设置的最大时间 (单位:tick)。
Returns:
事件位等待完成设置或阻塞时间过期时 的事件组值。 如果 高优先级任务或中断在调用任务解除“已阻塞”状态和退出 xEventGroupWaitBits() 函数之间更改了事件位的值, 则事件组中事件位的当前值将与返回值不同 。
测试返回值以确定 哪些位已完成设置。 如果 xEventGroupWaitBits() 因为超时值过期而返回, 则并非在等待的所有位都会进行设置。 如果 xEventGroupWaitBits() 因为它所等待的位均已完成设置而返回相应值, 则返回值是自动清除 (原因是 xClearOnExit 参数设置为 pdTRUE)任何位之前的事件组值。
用法示例:
#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 & 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. */
}
}
5- xEventGroupSetBits()x
event_groups.h
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet );
在 RTOS 事件组中设置位(标志)。 无法从中断调用此函数。 xEventGroupSetBitsFromISR() 是可从中断调用的版本。
在事件组中设置位将自动解除 所有等待位的任务的阻塞态。
RTOS 源文件 FreeRTOS/source/event_groups.c 必须 包含在构建中,xEventGroupSetBits() 函数才可用。
参数:
xEventGroup 要设置位的事件组。 该 必须已通过 通过调用 xEventGroupCreate() 创建。
uxBitsToSet 指定要在事件组中设置的一个或多个位的按位值。 例如,将 uxBitsToSet 设置为 0x08,可仅设置位 3。 将 uxBitsToSet 设置 为 0x09,可设置位 3 和位 0。
Returns:
调用 xEventGroupSetBits() 返回时事件组的值。
返回值可能会 清除 uxBitsToSet 参数指定的位,有如下两个原因:
如果设置某个位导致正在等待该位的任务 解除阻塞态, 则可能该位 已被自动清除(请参阅 xEventGroupWaitBits() 的 xClearBitOnExit 参数)。
将执行任何处于阻塞态(或就绪态)且优先级 高于调用 xEventGroupSetBits() 的任务, 并可能在调用 xEventGroupSetBits() 返回之前 更改事件组值。
用法示例:
#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. */
}
}
6- xEventGroupSetBitsFromISR()
event_groups.h
BaseType_t xEventGroupSetBitsFromISR(
EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t *pxHigherPriorityTaskWoken );
在RTOS 事件组中设置位(标志)。 可以从中断服务程序 (ISR) 调用的 xEventGroupSetBits() 版本 。
在事件组中设置位将自动解除 所有等待位的任务的阻塞状态。
在事件组中设置位不是确定性操作,因为 可能有未知数量的任务正在等待设置一个 或多个位。 FreeRTOS 不允许在中断或临界区 中执行不确定的操作。 因此, xEventGroupSetBitFromISR() 会向 RTOS 守护进程任务发送一条消息, 从而在守护进程任务的上下文中执行设置操作,其中使用的是调度器锁 而非临界区。
注意: 如上文所述,从中断服务程序中设置位 会将设置操作推迟到 RTOS 守护进程任务(也叫定时器服务任务) 。 RTOS守护进程任务 与其他RTOS任务一样, 都是根据优先级进行调度的。 因此,如果置位操作必须立即完成 (在应用程序创建的任务执行之前), 那么RTOS守护进程任务的优先级必须要高于 其他使用事件组的任务。 RTOS守护进程任务的优先级由 configTIMER_TASK_PRIORITY 在FreeRTOSConfig.h中定义。
INCLUDE_xEventGroupSetBitFromISR, configUSE_TIMERS 和INCLUDE_xTimerPendFunctionCall 必须在FreeRTOSConfig.h中全部设置为1,才能使用xEventGroupSetBitsFromISR() 函数。
RTOS源文件 FreeRTOS/source/event_groups.c 必须 包含在构建中,才能使用xEventGroupSetBitsFromISR()函数。
参数:
xEventGroup 要设置位的事件组。 该 必须已通过 通过调用 xEventGroupCreate() 创建。
uxBitsToSet 指定要设置的一个或多个位的按位值。 例如,要设置位3,便将uxBitsToSet设置为0x08。 将 uxBitsToSet 设置 位3和位0,便将uxBitsToSet设置为0x09。
pxHigherPriorityTaskWoken 如上所述,调用此函数 将意味着给RTOS守护进程任务发送一条消息。 如果 守护进程任务的优先级高于 当前正在运行的任务(中断中断的任务), 那么xEventGroupSetBitsFromISR()会将*pxHigherPriorityTaskWoken设置为pdTRUE, 指示应在中断退出之前 请求上下文切换。 因此 必须将 *pxHigherPriorityTaskWoken 初始化为 pdFALSE。
Returns:
如果消息已发送到RTOS守护进程任务,则返回pdPASS, 否则将返回pdFAIL。 如果 计时器服务队列已满,则将返回pdFAIL 。
用法示例:
#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 != pdFAIL )
{
/* 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 );
}
}
7-xEventGroupClearBits()
event_groups.h
EventBits_t xEventGroupClearBits(
EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear );
清除 RTOS 事件组中的位(标志)。 无法从中断调用此函数 。 有关可从中断调用的版本,请参阅 xEventGroupClearBitsFromISR() 。
RTOS 源文件 FreeRTOS/source/event_groups.c 必须 包含在 xEventGroupClearBits() 函数可用的构建中。
参数:
xEventGroup 要在其中清除位的事件组。 此事件组 必须已通过 调用 xEventGroupCreate() 事先创建。
uxBitsToClear 表示要在事件组中清除一个或多个位的 按位值。 例如,将 uxBitsToClear 设置为 0x08 以仅清除位 3。 将 uxBitsToClear 设置为 0x09 以清除位 3 和位 0。
Returns:
清除指定位之前的事件组的值。
用法示例:
#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. */
}
}
8-xEventGroupClearBitsFromISR()
[事件组 API]
event_groups.h
BaseType_t xEventGroupClearBitsFromISR(
EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear );
可以从中断调用的 xEventGroupClearBits() 版本 。 清除操作被延迟为 RTOS 守护进程任务,也称为定时器服务任务。 守护进程任务的 优先级由 configTIMER_TASK_PRIORITY FreeRTOSConfig.h 中的设置来设定。
要使 xEventGroupClearBitsFromISR() 函数可用,RTOS 源文件 FreeRTOS/source/event_groups.c 必须 包含在构建中。
参数:
xEventGroup 要在其中清除位的事件组。 此事件组 必须已通过 调用 xEventGroupCreate() 事先创建。
uxBitsToClear 表示要在事件组中清除一个或多个位的 按位值。 例如,将 uxBitsToClear 设置为 0x08 以仅清除位 3。 将 uxBitsToClear 设置为 0x09 以清除位 3 和位 0。
Returns:
如果操作已成功延迟为 RTOS 守护进程任务,则返回 pdPASS。 否则返回 pdFALSE。 只有当定时器命令队列已满时,才会返回 pdFALSE。
用法示例:
#define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 )
/* This code assumes the event group referenced by the
xEventGroup variable has already been created using a call to
xEventGroupCreate(). */
void anInterruptHandler( void )
{
BaseType_t xSuccess;
/* Clear bit 0 and bit 4 in xEventGroup. */
xSuccess = xEventGroupClearBitsFromISR(
xEventGroup, /* The event group being updated. */
BIT_0 | BIT_4 );/* The bits being cleared. */
if( xSuccess == pdPASS )
{
/* The command was sent to the daemon task. */
}
else
{
/* The clear bits command was not sent to the daemon task. */
}
}
9-xEventGroupGetBits()
event_groups.h
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
返回RTOS 事件组中事件位(事件标志)的当前值。 不能从中断使用此函数。
RTOS源文件 FreeRTOS/source/event_groups.c 必须 包含在构建中,才能使用xEventGroupGetBits()函数。
参数:
xEventGroup 正在查询的事件组。 该 必须已通过 xEventGroupCreate()创建的。
Returns:
调用xEventGroupGetBits()时,事件组中的 事件组中事件位的值。
10-xEventGroupGetBitsFromISR()
event_groups.h
EventBits_t xEventGroupGetBitsFromISR(
EventGroupHandle_t xEventGroup );
可从中断调用的 xEventGroupGetBits() 的 版本。
RTOS 源文件 FreeRTOS/source/event_groups.c 必须 包含在构建中,xEventGroupGetBitsFrom() 函数才可使用。
参数:
xEventGroup 正在查询的事件组。 该 必须已通过 通过调用 xEventGroupCreate() 创建。
Returns:
调用 XEventGroupGetBitsFromISR() 时, 事件组中事件位的值。