事件标志(Event Flags)

事件位(Event Bits)被用来标志某个事件发生与否。事件位也被称为事件标志。举个栗子,比如某个bit也就是某个标志代表当前是否需要刷新LCD上的内容,如果置位则需要刷新,清空则不需要。当该标志被置位时,任务进行LCD上的内容刷新。

事件组

事件标志的集合。每一bit代表某个事件。

事件组和事件标志数据类型

事件组引用的变量类型定义为EventGroupHandle_t,事件组的位数由configUSE_16_BIT_TICKS决定,当设置为1时,事件组为8bit,设置为0时,事件组为24bit。(这个宏定义实际上是用来定义TickType_t的位数的,不知道为什么会拿来定义事件组的位数,而不是再设计一个宏专门定义事件组的位数)。

下图是一个24bit的事件组,包含3个事先定义好的事件,bit2被置位。

24-bit Event Group

事件组的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文件中。