目录

一.简介

1. 事件位与事件组

2. 事件标志组的数据类型

3. 事件标志组的作用与优势

二.API

1. 创建与删除

2.设置事件位

3.清除事件位

4.等待事件位

5.同步

6.获取当前事件位值

三.代码实现

1.句柄定义

2.创建

3.设置

4.获取

四.实验结果


一.简介

        事件标志组(Event Group)是 FreeRTOS 提供的一种同步机制,用于实现任务之间或任务与中断之间的事件标志位通信。它本质上是一个变量,每一位代表一个独立的事件,任务可以通过等待某些位被设置来实现对多个事件的同步控制。

1. 事件位与事件组

  • 事件位(事件标志):用来表明某个事件是否发生。例如,定义一个位为 1 时表示“已收到消息并准备好处理”,为 0 时表示“没有消息等待处理”。

  • 事件组:一组事件位的集合。事件组中的事件位通过位编号来引用,例如 bit0 表示“收到消息”,bit1 表示“有消息需要发送”。

2. 事件标志组的数据类型

  • 事件标志组由 EventGroupHandle_t 类型的变量引用。

  • 事件组中的所有事件位都存储在一个 EventBits_t 类型的无符号整型变量中。

  • 可用位数:当 configUSE_16_BIT_TICKS 设为 1 时,事件组可存储 8 个事件位;设为 0 时可存储 24 个事件位。高 8 位为系统保留位,不可用于用户事件标志。

3. 事件标志组的作用与优势

  • 多任务同步:一个任务可等待多个事件的“任意”或“全部”发生,避免轮询。

  • 相比全局变量:事件标志组让 RTOS 内核有效管理任务,提供超时机制,自动处理多任务访问冲突,并能有效解决中断服务程序和任务之间的同步问题。

  • 相比信号量:信号量只适合“单一事件/资源”的同步,而事件标志组可并行管理多个不同事件。

二.API

1. 创建与删除

函数原型功能描述形参返回值
EventGroupHandle_t xEventGroupCreate( void )动态创建一个事件标志组,所需内存从 FreeRTOS 堆中分配。EventGroupHandle_t
- 非 NULL:创建成功,返回事件组句柄。
- NULL:创建失败,堆内存不足。
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )使用静态内存创建事件标志组,内存由用户预先分配。pxEventGroupBuffer:指向 StaticEventGroup_t 类型变量的指针,用于存储事件组结构体。EventGroupHandle_t:创建成功,返回事件组句柄。
void vEventGroupDelete( EventGroupHandle_t xEventGroup )删除一个事件标志组,释放其占用的内存。xEventGroup:要删除的事件组句柄。

2.设置事件位

函数原型功能描述形参返回值
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )在任务中设置指定的事件位为 1。xEventGroup:事件组句柄。
uxBitsToSet:要设置的事件位掩码,例如 (1<<0) | (1<<2) 表示设置位 0 和位 2。
EventBits_t:函数返回时事件组中所有位的当前值。
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )在中断服务程序中设置事件位。实际通过向守护任务发送消息来执行,因此可在 ISR 中使用。xEventGroup:事件组句柄。
uxBitsToSet:要设置的事件位掩码。
pxHigherPriorityTaskWoken:可选指针,若设置为 pdTRUE,则应在 ISR 退出前执行上下文切换。
BaseType_t
pdPASS:设置成功。
pdFALSE:设置失败。

3.清除事件位

函数原型功能描述形参返回值
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )在任务中清除指定的事件位为 0。xEventGroup:事件组句柄。
uxBitsToClear:要清除的事件位掩码。
EventBits_t:执行清除操作前事件组中所有位的当前值。
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )在中断服务程序中清除事件位。同样通过守护任务实现。xEventGroup:事件组句柄。
uxBitsToClear:要清除的事件位掩码。
BaseType_t
pdPASS:清除成功。
pdFALSE:清除失败。

4.等待事件位

函数原型功能描述形参返回值
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )等待指定的事件位被设置。任务可进入阻塞状态,直到条件满足或超时。xEventGroup:事件组句柄。
uxBitsToWaitFor:等待的事件位掩码。
xClearOnExit:若为 pdTRUE,则在条件满足退出前自动清除这些事件位。
xWaitForAllBits:若为 pdTRUE,等待所有指定位均被设置;若为 pdFALSE,任意一位被设置即可。
xTicksToWait:最大阻塞时间(单位:系统时钟节拍)。portMAX_DELAY 表示无限等待。
EventBits_t:函数返回时事件组中所有位的当前值。可通过按位与 & 检查哪些等待位已被设置。

5.同步

函数原型功能描述形参返回值
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )原子操作:先设置自己位,再等待其他任务设置的位。常用于多任务同步点。xEventGroup:事件组句柄。
uxBitsToSet:要设置的事件位掩码。
uxBitsToWaitFor:要等待的事件位掩码。
xTicksToWait:最大阻塞时间。
EventBits_t:函数返回时事件组中所有位的当前值。若超时,返回值中可能不包含所有等待位。

6.获取当前事件位值

函数原型功能描述形参返回值
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup )获取事件标志组的当前位值(任务级)。xEventGroup:事件组句柄。EventBits_t:事件组当前所有位的值。
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )在中断中获取事件标志组的当前位值。xEventGroup:事件组句柄。EventBits_t:事件组当前所有位的值。

三.代码实现

在高优先级任务中(周期1S)设置标志位,在低优先级任务中(周期500ms)获取该标志位并清除。

1.句柄定义

2.创建

3.设置

4.获取

四.实验结果

从实验可以看到每隔1s该事件组的事件位被设置。

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐