天天看点

FreeRTOS——事件组事件位(事件标志)事件组事件组和事件位数据类型事件组 RTOS API 函数RTOS 在实现事件组时必须克服的挑战

FreeRTOS 基础系列文章

 基本对象

  FreeRTOS——任务

  FreeRTOS——队列

  FreeRTOS——信号量

  FreeRTOS——互斥量

  FreeRTOS——任务通知

  FreeRTOS——流和消息缓冲区

  FreeRTOS——软件定时器

  FreeRTOS——事件组

 内存管理

  FreeRTOS——静态与动态内存分配

  FreeRTOS——堆内存管理

  FreeRTOS——栈溢出保护

 代码组织

  FreeRTOS——源代码组织

  FreeRTOS——创建新的项目

  FreeRTOS——配置文件

FreeRTOS——事件组

  • 事件位(事件标志)
  • 事件组
  • 事件组和事件位数据类型
  • 事件组 RTOS API 函数
  • RTOS 在实现事件组时必须克服的挑战
提示:在许多情况下,“任务通知”可以为事件组提供轻量级的替代方案

事件位(事件标志)

事件位用于指示事件是否发生。事件位通常称为事件标志。例如,一个应用程序可能:

  • 定义一个位(或标志),当它设置为 1 时表示“一条消息已被接收并准备好进行处理”,当它设置为 0 时表示“没有消息等待处理”。
  • 定义一个位(或标志),当它设置为 1 时表示“应用程序已将准备发送到网络的消息排入队列”,当它设置为 0 时表示“没有将准备发送到网络的消息排入队列”。
  • 定义一个位(或标志),当它设置为 1 时表示“是时候向网络发送心跳消息了”,当它设置为 0 时表示“还没有到发送另一个心跳消息的时候”。

事件组

事件组是一组事件位。事件组内的单个事件位由位编号引用。扩展上面提供的示例:

  • 表示“已收到消息并准备好处理”的事件位可能是事件组中的位号 0 。
  • 表示“应用程序已将准备发送到网络的消息排入队列”的事​​件位可能是同一事件组中的位号 1 。
  • 表示“是时候将心跳消息发送到网络上”的事件位可能是同一事件组中的位号 2 。

事件组和事件位数据类型

事件组由

EventGroupHandle_t

类型的变量引用。

如果

configUSE_16_BIT_TICKS

设置为

1

,则事件组中存储的位(或标志)数为

8

如果 configUSE_16_BIT_TICKS

设置为

,则为

24

事件组中的所有事件位都存储在

EventBits_t

类型的单个无符号变量中。事件位 0 存储在位位置 0,事件位 1 存储在位位置 1,依此类推。

下图表示一个 24 位事件组,它使用三位来保存上面描述的三个示例事件。仅设置了事件位 2。

FreeRTOS——事件组事件位(事件标志)事件组事件组和事件位数据类型事件组 RTOS API 函数RTOS 在实现事件组时必须克服的挑战

包含 24 个事件位的事件组,其中只有三个正在使用

事件组 RTOS API 函数

提供的事件组 API 函数允许任务设置事件组中的一个或多个事件位,清除事件组中的一个或多个事件位,以及挂起(进入阻塞状态,因此任务不会消耗任何处理时间)以等待事件组的一个或多个事件位被设置。

事件组还可以用于同步任务,创建通常称为任务“集合点”的内容。任务同步点是应用程序代码中的一个位置,在该位置任务将在阻塞状态(不消耗任何 CPU 时间)中等待,直到参与同步的所有其他任务也到达它们的同步点。

RTOS 在实现事件组时必须克服的挑战

RTOS 在实现事件组时必须克服的两个主要挑战是:

  1. 避免在用户的应用程序中创建竞争条件:

    如果出现以下情况,事件组实现将在应用程序中创建竞争条件:

    · 不清楚谁负责清除单个位(或标志)。

    · 不清楚何时要清除位。

    · 不清楚在任务退出测试位值的 API 函数时是否设置或清除了位(可能是另一个任务或中断已更改该位的状态)。

    FreeRTOS 事件组实现通过包含内置智能来确保位的设置、测试和清除看起来是原子的,从而消除了竞争条件的可能性。线程本地存储和 API 函数返回值的谨慎使用使这成为可能。

  2. 避免不确定性:

    事件组概念意味着不确定性行为,因为它不知道在一个事件组上有多少任务被阻塞,因此当事件位被设置时,不知道有多少条件需要被测试或多少任务需要被解除阻塞。

    FreeRTOS 质量标准不允许在中断被禁用时或在中断服务程序中执行不确定的动作。为了确保在设置事件位时不违反这些严格的质量标准:

    · RTOS 调度程序的锁定机制用于确保在 RTOS 任务设置事件位时中断保持启用状态。

    · 集中延迟中断机制用于在尝试从中断服务程序设置事件位时,将设置位的动作推迟到任务。

继续阅读