第三章 拼凑内核(4) -- 事件组解析
前言
这篇文章的内容是关于事件组的解析分析。依旧是数据结构和程序逻辑2个方向;让我们来继续解析FreeRTOS中的事件组组件。
事件组简介
在加入分析前,还是要有一些前置的知识背景,才可以更好的去理解
事件组概念
先和队列进行一下对比,当我现在有一个队列可以使用,它可以让当前任务等待对应数据到来再执行,而事件组与队列类似,不过与队列最不同的点在于:
队列主要用于数据的生产和消费。
事件组更像标志位集合用来等待某些事情发生后运行,而不是数据传输。

事件位
图例中的event0、event1 ... 称为事件位,所谓的事件位其实是一个抽象的概念,进行替换的话可以变为:
event0:灯每闪烁10次 (灯每闪10次的标志位)。
event1:adc采集完成
event2:串口数据发送完成
在没有事件的情况下,我们一般使用全局变量的标志位来实现,但是这样有一个缺点,当事情多了,变量也就多了,东一个变量西一个变量,并且全局变量的含义不好去理解。
而对于事件位而言,将所有标志位集中起来,统一管理,并且实现事件阻塞等功能。
有引出多事件的概念和功能,既然存在单个事件位判断,那也就说明存在多个事件位判断

如何实现
关于事件驱动程序框架是离不开事件以及触发的,而基于事件组也可以实现基于事件驱动型的程序框架
总结一句话事件组功能就是:
事件发生:通知对应任务,任务运行;
事件未发生:对应任务阻塞或跳过。
这里面就涉及到2个概念,阻塞与事件位
这2件事情就是实现事件组的关键,而要实现阻塞我们类比队列,就可以引出事件的另一个关键的数据:事件等待列表
事件组解析
数据结构
typedef struct xEventGroupDefinition
{
EventBits_t uxEventBits; //事件位
List_t xTasksWaitingForBits; //事件等待列表
} EventGroup_t;
只有简单的2个数据就可以实现事件组的核心结构
-
事件位:区分不同事件
-
事件等待列表

事件组功能
等待对应事件位
任务中需要等待某个事件发生,未发生期间需要事件阻塞,就需要等待事件位来实现
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait )
uxBitsToWaitFor :需要等待的事件位(可以是多位,也可以是单位)
xClearOnExit :事件触发后,是否将事件等待位清零
xWaitForAllBits :等待事件位是单位还是多位
程序逻辑也对应很清晰
-
事件位未发生(多位或单位),将当前任务事件列表项放入事件组中的等待列表;将当前任务放入阻塞列表;实现任务阻塞
-
事件位发生(多位或单位),将当前任务事件列表项取出事件组中的等待列表;将当前任务取出阻塞列表;实现任务运行
设置对应事件位
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet )
程序逻辑也很清楚:
将事件组中对应的位置位,实现事件通知,一般用于事件对任务进行通知。Set和Wait一般都是共用的:任务等待事件,事件发生,通知任务事件。
任务同步事件
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait )
相比Set与Wait同时出现的模式,使用这个函数可以实现多任务的事件同步。
但其实他的实现逻辑也是和之前2个功能类似的,uxBitsToWaitFor提供需要哪些位,而不同任务可以设置不同uxBitsToSet,来达到的任务实现同步的效果。
而任务阻塞的实现,还是与事件组列表、任务状态列表项、任务事件列表项是有关的。
更多推荐


所有评论(0)