1-事件位(标志)
事件位用于指示事件是否发生。事件位通常称为事件标志。例如,一个应用程序可以:
- 定义一个标志,当为1时,表示消息已经接收并进行处理,当为0时,表示没有消息要处理。
- 定义一个比特位(或标志),当它设置为1时,表示“已经把应用程序准备的消息队列发送到网络,而当它设置为0时,表示“没有应用程序准备的消息队列发送到网络”。
- 定义一个比特位(或标志),当它设置为1时,表示“可以向网络上发送检测到的消息信号,而当它设置为0时,表示“没有”。
2- 事件组
事件组是一组事件位。事件组是由单个事件位组成的。例如:
- 表示“消息已接收并准备处理”的事件位可能是事件组中的位0。
- 在同一个事件组中,表示“已经把应用程序准备的消息队列发送到网络”的事件位可能是位1。
- 表示“可以向网络上发送检测到的消息信号”的事件位可能是同一个事件组中的第2位。
3- 事件组和事件位数据类型
事件组由EventGroupHandle_t类型的变量定义。
如果configUSE_16_BIT_TICKS设置为1,则事件组中存储的位(或标志)为8,如果configUSE_16_BIT_TICKS设置为0,则存储的比特位(或标志)数目为24。对configUSE_16_BIT_TICKS的依赖源于进程内部实现中用于线程本地存储的数据类型。
事件组中的所有事件位都存储在一个无符号变量中,类型为EventBits_t。事件位0存储在位0中,事件比1存储在位1中,以此类推。
下图描述了一个24位的事件组,用三个位描述上面说到的3个事件,在下图中,只有位2被设置。
4- 事件组API函数
在事件组API函数中,允许在事件组中设置一个或多个事件位,清除事件组中的一个或多个事件位,以及等待时间组中设置一个或者多个事件位(进入阻塞状态,以便任务不消耗任何处理时间) 。
事件组也可以用来同步任务,创建通常被称为任务“会合”的内容。任务同步点是应用程序代码中的一个位置,在这个位置上,一个任务将以阻塞状态等待(不消耗任何CPU时间),直到所有参与同步的其他任务也到达它们的同步点。
5- 事件组可能遇到的问题
5.1 避免在用户应用程序中创建争用条件:
事件组实现将在 在以下情况下申请:
- 目前尚不清楚谁负责清除单个位 (或标志)。
- 目前尚不清楚何时清除位。
- 不清楚在进程退出测试该位值的API函数时,该位是否被设置或清除(可能是另一个进程或中断已经改变了该位的状态)。
5.2 避免不确定性
事件组概念意味着非确定性行为,因为 不知道一个事件组上有多少任务被阻止,因此 不知道需要测试多少条件或任务 设置事件位时取消阻止。
FreeRTOS 质量标准不允许非确定性 禁用中断时或从内部执行的操作 中断服务例程。为了确保这些严格的质量标准是 设置事件位时不违反:
RTOS 调度程序的锁定机制用于确保 从 RTOS 设置事件位时,中断保持启用状态 任务。
集中式延迟中断机制用于延迟 在尝试将位设置为任务的操作 从中断服务例程中设置事件位。
注:有关的演示例程请参考:FreeRTOS/Demo/Common/Minimal目录中的文件。