一、概述
事件是一种实现任务间通信的机制,主要用于实现多任务间的同步,但事件通信只能是事件类型的通信,无数据传输。与信号量不同的是,它可以实现一对多,多对多的同步。 即一个任务可以等待多个事件的发生:可以是任意一个事件发生时唤醒任务进行事件处理; 也可以是几个事件都发生后才唤醒任务进行事件处理。同样,也可以是多个任务同步多个事件。
每一个事件组只需要很少的 RAM 空间来保存事件组的状态。事件组存储在一个 EventBits_t 类型的变量中,该变量在事件组结构体中定义。
如果宏configUSE_16_BIT_TICKS定义为1,那么变量uxEventBits就是16位的,其中有8个位用来存储事件组;而如果宏 configUSE_16_BIT_TICKS 定义为0,那么变量uxEventBits就是32位的, 其中有24个位用来存储事件组。
在STM32中,我们一般将configUSE_16_BIT_TICKS定义为0,那么uxEventBits是32位的,有24个位用来实现事件标志组。每一位代表一个事件,任务通过“逻辑与”或“逻辑或”与一个或多个事件建立关联,形成一个事件组。
例如,如果一个事件组的值是0x92(二进制1001 0010),那么只有事件位1、4和7被设置,因此只有由1、4和7表示的事件发生。下图显示了EventBits_t类型的变量,它设置了事件位1、4和7,并清除了所有其他事件位,使事件组的值为0x92。
- 事件只与任务相关联,事件相互独立,一个 32 位的事件集合(EventBits_t 类型的 变量,实际可用与表示事件的只有 24 位),用于标识该任务发生的事件类型,其中每一位表示一种事件类型(0 表示该事件类型未发生、1 表示该事件类型已经发生),一共 24 种事件类型。
- 事件仅用于同步,不提供数据传输功能。
- 事件无排队性,即多次向任务设置同一事件(如果任务还未来得及读走),等效于只设置一次。
- 允许多个任务对同一事件进行读写操作。
- 支持事件等待超时机制。
二、函数接口
1.事件标志组创建
include "event_groups.h"
EventGroupHandle_t xEventGroupCreate(void)
参数说明:无
返回值:
成功-返回事件标志组的句柄。
失败-返回NULL。
2.事件标志组删除
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
参数说明:
- xEventGroup-事件标志组的句柄
返回值:无
3.事件标志组指定的位置位
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
参数说明:
- xEventGroup-事件标志组的句柄
- uxBitsToSet-指定事件中的事件标志位。
如设置uxBitsToSet为0x08(0000 1000)则只置位位3,
如果设置uxBitsToSet为0x09(0000 1001)则位3和位0都需要被置位。
返回值:
成功-返回调用xEventGroupSetBits()时事件组中的值。
4.在中断中执行事件标志组置位
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
参数说明:
- xEventGroup-事件标志组的句柄
- uxBitsToSet-指定事件中的事件标志位。如设置 uxBitsToSet为0x08则只置位位3,
如果设置 uxBitsToSet 为 0x09 则位3和位0都需要被置位。
- pxHigherPriorityTaskWoken在使用之前必须初始化成 pdFALSE。
如果API函数(即xEventGroupSetBitsFromISR)导致一个任务解锁,
并且解锁的任务优先级高于当前运行的任务,则API函数(即xEventGroupSetBitsFromISR)
将*pxHigherPriorityTaskWoken设置成pdTRUE,
在中断退出前,触发一次任务切换,可提高实时性;
若为pdFALSE,则在下一个时钟节拍才进行任务切换。
pxHigherPriorityTaskWoken 作为一个可选参数,可以设置为NULL。
返回值:
成功-返回pdPASS。
失败-返回pdFAIL。
5.等待事件标志组
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait )
参数说明:
- xEventGroup-事件标志组的句柄
- uxBitsToWaitFor-一个按位或的值,指定需要等待事件组中的哪些位置 1。
如果需要等待 bit 0 and/or bit 2 那么 uxBitsToWaitFor 配置为 0x05(0101'b)。
- xClearOnExit-pdTRUE:当 xEventGroupWaitBits()等待到满足任务唤醒的事件时,
系统将清除由形参 uxBitsToWaitFor 指定的事件标志位。
pdFALSE:不会清除由形参 uxBitsToWaitFor 指定的事件标志位。
- xWaitForAllBits-pdTRUE: 当形参uxBitsToWaitFor 指定的位都置位的时候,
xEventGroupWaitBits()才满足任务唤醒的条件,这也是“逻辑与” 等待事件,
并且在没有超时的情况下返回对应的事件标志位的值。
pdFALSE:当形参 uxBitsToWaitFor-指定的位有其中任意一个置位的时候,
这也是常说的“逻辑或”等待事件,在没有超时的情况下 函数返回对应的事件标志位的值。
- xTicksToWait-最大超时时间,单位为系统节拍周期,常量 portTICK_PERIOD_MS
用于辅助把时间转换成 MS,若一直等待,填写portMAX_DELAY。
6.事件标志组指定的位清零
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
参数说明:
- xEventGroup-事件标志组的句柄
- uxBitsToClear-指定事件组中的哪个位需要清除。
如设置 uxBitsToSet 为 0x08 则只清除位 3,
如果设置 uxBitsToSet 为 0x09 则位3和位0都需要被清除。
返回值:
事件标志组还没有清除指定位之前的值。
7.在中断中执行事件标志组指定的位清零
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear )
参数说明:
- xEventGroup-事件标志组的句柄
- uxBitsToClear-指定事件组中的哪个位需要清除。
如设置 uxBitsToSet 为 0x08 则只清除位 3,
如果设置 uxBitsToSet 为 0x09 则位3和位0都需要被清除。
返回值:
成功-返回pdPASS。
失败-返回pdFAIL。
注意事项:
若使用xEventGroupSetBitsFromISR、xEventGroupClearBitsFromISR等函数,官方要求3个宏定义生效,详细代码如下:
FreeRTOSConfig.h
#define configUSE_TRACE_FACILITY 1
#define configUSE_TIMERS 1
FreeRTOS.h
#ifndef INCLUDE_xTimerPendFunctionCall
#define INCLUDE_xTimerPendFunctionCall 1
#endif
三、示例代码
1、代码例子是,设置事件的逻辑与,逻辑或,来控制灯的状态。当逻辑与时,按键1和按键2按下灯1亮;当逻辑或时,按键1或按键2按下一个即可灯亮。
源码:
https://download.csdn.net/download/m0_63622771/90897003