马上就要上课了,老师正在教室里等待:
张三、李四、王五都到教室了,那就可以开始上课了。
快下课时,老师说这道题回答完就可以下课了,谁举手谁就来回答。
在这个场景中:
- 上课:需要大家都到教室了,这是“与”的关系。
- 下课:需要
有一个人举手回答问题,这是“或”的关系。
在FreeRTOS中,可以使用事件组来解决这个问题。
使用事件组最多的几个场合:
- 用来做任务与任务之间的同步即一个任务发生了就触发了另一个任务的运行
- 用来任务与多个任务之间的同步,即多个任务都已经发生完了才会触发一个任务运行
1、事件组的特性
- 事件组可以简单理解为一个有16或32个bit位的整数(当configUSE_16_BIT_TICKS为1时16位;当其为0时32位)。其中最高8位为控制位,低8/24位则用来存储事件状态,每一位都代表一个不同的事件(1-事件发生;0-事件未发生)
- 事件仅用于多线程同步,不能传输数据。
- 在等待其它事件发生时,可进入阻塞状态。
- 与设置队列/信号量不同,设置事件组不会堵塞,即使多次设置同一事件,除第一次外都属于无效操作。
- 事件获取时,可以用“与”“或”两种逻辑等待多个事件。
- 同队列、信号量相比事件组具有“广播”作用,事件发生时会唤醒所有符合条件的任务。
- 一个或多个任务、ISR都可以去读或写这些位。
- 同队列、信号量相比,事件组的那些事件标志位在读取时可以选择清除或保存。
2、事件组API
2.1、创建事件组
- 动态分配内存:
EventGroupHandle_t xEventGroupCreate( void );
参数 | 描述 |
---|---|
返回值 | 成功则返回事件组句柄 |
- 静态分配内存:
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer );
参数 | 描述 |
---|---|
pxEventGroupBuffer | 执行一个StaticEventGroup_t 结构体,用来保存事件组的数据结构 |
返回值 | 成功则返回句柄 |
2.2、设置事件
/*在任务中使用*/
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet );
/*在ISR中使用*/
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t * pxHigherPriorityTaskWoken );
参数 | 描述 |
---|---|
xEventGroup | 事件组句柄,表示设置哪个事件组, |
uxBitsToSet | 设置哪些位,如0x05就设置bit2,bit0 |
pxHigherPriorityTaskWoken | 有没有导致更高优先级的任务进入就绪态 pdTRUE-有, pdFALSE-没有 |
返回值 | pdPASS-成功, pdFALSE-失败 |
2.3、等待事件
使用此函数等待事件,可以等待一个、也可以等待多个中的任意一个、多个中的全部,在等到期待的事件后还可以选择是否清除对应的位。
EventBits_t xEventGroupWaitBits(
EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait );
参数 | 描述 |
---|---|
xEventGroup | 事件组句柄,表示等待哪个事件组 |
uxBitsToWaitFor | 要等待哪些位,如0x09,就是要等待bit3、bit0 |
xClearOnExit | 函数退出前是否清除事件, pdTRUE: 清除uxBitsToWaitFor指定的位 pdFALSE: 不清除 |
xWaitForAllBits | 怎么等待?pdTRUE:等待的位都被设置后;pdFALSE:等待的位任意一个被设置 |
xTicksToWait | 如果等待的事件未达成,可以让任务进入阻塞态,xTicksToWait 表示阻塞时间。若设为0,则会直接返回;若设为portMAX_DELAY,则一直等待到条件达成 |
返回值 | 函数返回事件组的当前状态(事件值),包括所有事件位的当前状态。 |
2.4、事件组同步函数
xEventGroupSync() 函数用于同步多个任务的操作,使它们能够在相同的时间点上等待一组特定的事件。它通过等待事件组的特定位或位组合被设置来实现同步。
EventBits_t xEventGroupSync(
EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const EventBits_t uxBitsToSet,
TickType_t xTicksToWait);
参数 | 描述 |
---|---|
xEventGroup | 要操作事件组的句柄 |
uxBitsToWaitFor | 等待的位掩码,表示需要等待设置的特定位。 |
uxBitsToSet | 设置的位掩码,表示需要设置的特定位。 |
xTicksToWait | 在等待过程中,可以让任务进入阻塞态,xTicksToWait 表示阻塞时间。若设为0,则会直接返回;若设为portMAX_DELAY,则一直等待到条件达成 |
返回值 | 函数返回事件组的当前状态(事件值),包括所有事件位的当前状态。 |
2.5、删除事件组
对于动态创建的事件组,在不使用时可以删除以回收内存防止溢出。
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
参数 | 描述 |
---|---|
xEventGroup | 事件组句柄,表示删除哪个事件组 |