【FreeRTOS】事件标志组
文章目录
- 1 简介
- 1.1事件标志
- 1.2事件组
- 2事件标志组API
- 2.1创建
- 动态创建
- 静态创建
- 2.2 删除事件标志组
- 2.3 等待事件标志位
- 2.4 设置事件标志位
- 在任务中
- 在中断中
- 2.5 清除事件标志位
- 在任务中
- 在中断中
- 2.6 获取事件组中的事件标志位
- 在任务中
- 在中断中
- 2.7 函数xEventGroupSync
- 3 事件标志组使用
- 3.1 使用流程
- 3.2获取、等待标志组函数区别
1 简介
事件标志组与信号量一样,属于任务键的同步机制。但是信号量一般用于单事件同步,事件标志组用于多事件同步。
1.1事件标志
一个用于指示事件是否发生的布尔值,一个事件只有0和1两种状态,FreeRTOS将多个事假标志存储在一个EventBits_t
类型的变量中,这个变量就是事件标志组。
1.2事件组
一组事件标志的集合,一个事件组就包含了一个EventBits_t
数据类型的变量,变量类型定义如下:
typedef TickType_t EventBits_t;if ( configUSE_16_BIT_TICKS == 1 )typedef uint16_t TickType_t;
#else typedef uint32_t TickType_t;
#endif
从上面的代码中可以看出,EventBits_t
是一个16位或者32位的无符号类型。
当EventBits_t
为32位时,并不意味着可以存储32个事件标志,因为发数据类型被拆分成了两个部分,其中低24位[23:0]用于存储事件标志,高8位[31:24]用作存储事件标志组的控制信息。EventBits_t数据类型变量的位使用情况如下:
当某一位被置一时,就表示这一位对应的事件发生了。
2事件标志组API
事件标志组的API大概分为6类,分别为创建、删除、等待事件标志位、设置标志位、获取标志位、删除。
2.1创建
创建事件标志组有两种方式,动态和静态,两种方式的区别为:
静态创建时需要用户提供事件标志组所需要的内存空间,动态分配是FreeRTOS从FreeRTOS管理的堆中分配事件标志组所需的内存空间。函数原型如下;
动态创建
函数原型
EventGroupHandle_t xEventGroupCreat(void)
返回值
NULL:事假标志组创建失败,
其他值:事件标志组创建成功,返回其句柄
静态创建
函数原型
EventGroupHandle_t xEventGroupCreatStatic(StaticEventGroup_t *pxEventGroupBuffer);
形参
pxEventGroupBuffer:创建事件标志组所需要的内存空间
返回值
NULL:事假标志组创建失败,
其他值:事件标志组创建成功,返回其句柄
2.2 删除事件标志组
函数原型
void vEventGroupDelete(EventGroupHandle_t xEventGroup);
形参
xEventGroup:待删除的事件标志组句柄
返回值
无
2.3 等待事件标志位
函数原型
EventBits_t xEventGroupWaitBits(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToWairFor,const BaseType_t xClearOnWait,const BaseType_t xWaitForAllBits,TickType_t xTicksToWait);
形参
xEventGroup:等待的事件标志组
uxBitsToWairFor:等待的事件标志位,可以用逻辑或等待多个标志位
xClearOnWait:成功等到事件后需要清除的标志位
xWaitForAllBits:等待xWaitForAllBits中的所有标志位,(逻辑与)
xTicksToWait:等待的阻塞时间
返回值
EventBits_t :等待到的事件标志位
2.4 设置事件标志位
有两个设置事件标志位函数,分别是在任务重和在中断中
在任务中
函数原型
EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet);
形参
xEventGroup:待操作的事件标志组
uxBitsToSet:待设置的事件标志位
返回值
整数:事件组中的事件标志位值
在中断中
函数原型
BaseType_t xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet,BaseType_t * pxHigherPriorityTaskWoken)
形参
xEventGroup:待操作的事件标志组
uxBitsToSet:待设置的事件标志位
pxHigherPriorityTaskWoken:用于标记函数退出后是否需要进行任务切换
返回值
pdPASS:事件标志位设置成功
pdFAIL:事件标志位设置失败
2.5 清除事件标志位
同样是有两种,在任务中和在中断中
在任务中
函数原型
EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToClear)
形参
xEventGroup:待操作的事件标志组
uxBitsToSet:待清除的事件标志位
返回值
整数:清零事件标志位之前事件组中事件标志位的值
在中断中
函数原型
BaseType_t xEventGroupClearBitsFromISR(
EventGroupHandle_t EventGroup,
const EventBits_t uxBitsToClear)
形参
xEventGroup:待操作的事件标志组
uxBitsToSet:待清除的事件标志位
返回值
pdPASS:事件标志位设置成功
pdFAIL:事件标志位设置失败
2.6 获取事件组中的事件标志位
在任务中和在中断中
在任务中
函数原型
EventBits_t xEventGroupGetBits(xEventGroup);
形参
xEventGroup:待获取事件标志位值的事件组
返回值
整数:事件组的事件标志位的值
在中断中
函数原型
EventBits_t xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup);
形参
xEventGroup:待获取事件标志位值的事件组
返回值
整数:事件组的事件标志位的值
2.7 函数xEventGroupSync
此函数一般用于多任务同步,每个任务都必须等待其他任务达到同步点,然后才能继续执行(没理解啥意思,后面理解在补充)。
函数原型
EventBits_t xEventGroupSync(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet,const EventBits_t uxBitsToWaitFor,TickType_t xTicksToWait)
形参
xEventGroup:待获取事件标志位值的事件组
uxBitsToSet:达到同步点后,要设置的事件标志
uxBitsToWaitFor:等待的事件标志
xTicksToWait:等待的阻塞时间
返回值
成功:返回等待到的事件标志位
失败:返回事件组中的事件标志位
3 事件标志组使用
3.1 使用流程
1)创建事件标志组
2)设置标志组标志位
3)获取、等待、删除 标志组标志位
3)删除事件标志组
事件标志位可以使用宏定义的方式设置
#define EVENTBIT_0 (1 << 0) /* 事件位 */
#define EVENTBIT_1 (1 << 1)
#define EVENTBIT_ALL (EVENTBIT_0 | EVENTBIT_1)
3.2获取、等待标志组函数区别
同样都是可以获取当前事件标志组的值,两个函数的区别如下:
特性 | xEventGroupGetBits() | xEventGroupWaitBits() |
---|---|---|
是否阻塞任务 | ❌ 不阻塞,立即返回 | ✔️ 可阻塞(可设置超时) |
是否修改事件组 | ❌ 只读,不修改 | ✔️ 可配置是否清除标志位 |
是否等待标志位 | ❌ 不等待,仅查询 | ✔️ 可等待特定标志位 |
适用场景 | 轮询检查事件状态 | 任务同步(等待事件触发) |
任务同步咋使用呢?