1.3.3 事件组
事件标志(Event Flags)
事件位(Event Bits
)被用来标志某个事件发生与否。事件位也被称为事件标志。举个栗子,比如某个bit也就是某个标志代表当前是否需要刷新LCD上的内容,如果置位则需要刷新,清空则不需要。当该标志被置位时,任务进行LCD上的内容刷新。
事件组
事件标志的集合。每一bit代表某个事件。
事件组和事件标志数据类型
事件组引用的变量类型定义为EventGroupHandle_t
,事件组的位数由configUSE_16_BIT_TICKS
决定,当设置为1时,事件组为8bit,设置为0时,事件组为24bit。(这个宏定义实际上是用来定义TickType_t
的位数的,不知道为什么会拿来定义事件组的位数,而不是再设计一个宏专门定义事件组的位数)。
下图是一个24bit的事件组,包含3个事先定义好的事件,bit2被置位。
事件组的RTOS API函数
事件组的API函数允许任务或者其他来置位一个或多个事件标志,或者清空一个或多个事件标志。或者阻塞任务直到事件组中的事件标志置位。
事件组同样可以用来同步。creating what is often referred to as a task 'rendezvous'. A task synchronisation point is a place in application code at which a task will wait in the Blocked state (not consuming any CPU time) until all the other tasks taking part in the synchronisation also reached their synchronisation point.
使用事件组必须克服的问题
在使用事件组的时候,主要有两方面的挑战必须克服:
避免在用户应用中创建竞争条件
事件组会在以下情况创建竞争条件:
- 对于清事件标志没有一个明确的职责分配
- 对何时清时间标志不明确
- 在任务测试完事件标志并退出时,事件标志是被清空还是置位不明确
freeRTOS的事件组实现消除了这种潜在的竞争条件的产生,通过智能的建立确保置位、测试、清除是原子操作。线程的本地存储以及谨慎使用API函数的返回值使得这变得可能。
避免不确定性
事件组的概念意味这不确定的行为,因为不知道在一个事件组上有多少任务被阻塞。因此,也不知道当事件标志置位时候,也不知道需要测试多少事件标志位或者阻塞任务。
freeRTOS的质量标准不允许不确定的行为在中断禁用或者中断服务中发生。为了确保这个严格的质量标准在事件标志置位时不被打破,需要以下两点:
The RTOS scheduler's locking mechanism is used to ensure interrupts remain enabled when an event bit is set from an RTOS task.
The centralised deferred interrupt mechanism is used to defer the action of setting a bit to a task when an attempt is made to set an event bit from an interrupt service routine.
实例代码
相关的实例代码及文档保存在路径FreeRTOS/Demo/Common/Minimal
下的EventGroupsDemo.c
文件中。