下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

内核
最新资讯
简化任何设备的身份验证云连接。
利用 CoAP 设计节能型云连接 IoT 解决方案。
11.0.0 版 FreeRTOS 内核简介:
FreeRTOS 路线图和代码贡献流程。
使用 FreeRTOS 实现 OPC-UA over TSN。

RTOS 任务通知
[任务间通信和同步]



描述

[另请参阅博客文章“通过 FreeRTOS 通知减少 RAM 占用空间并加速执行”]

每个 RTOS 任务都有一个任务通知数组。 每条任务通知 都有“挂起”或“非挂起”的通知状态, 以及一个 32 位通知值。 常量 configTASK_NOTIFICATION_ARRAY_ENTRIES 可设置 任务通知数组中的索引数量。 在 FreeRTOS V10.4.0 版本前,任务只有单条任务通知, 而无通知数组。

直达任务通知是直接发送至任务的事件, 而不是通过中间对象 (如队列、事件组或信号量)间接发送至任务的事件。 向任务发送“直达任务通知” 会将目标任务通知设为“挂起”状态。 正如任务可以阻塞中间对象 (如等待信号量可用的信号量),任务也可以阻塞任务通知, 以等待通知状态变为“挂起”。

向任务发送“直达任务通知”也可以 更新目标通知的值(可选),可使用下列任一方法

  • 覆盖原值,无论接收任务是否 已读取被覆盖的值。
  • 覆盖原值(仅当接收任务已读取 被覆盖的值时)。
  • 在值中设置一个或多个位。
  • 对值进行增量(添加 1)。
调用 xTaskNotifyWait()/xTaskNotifyWaitIndexed() 来读取通知值会将通知状态清除为“非挂起”。 此外,也可以通过调用 xTaskNotifyStateClear()/xTaskNotifyStateClearIndexed() 将通知状态明确设置为“非挂起”。

注意:数组中的每条通知均独立运行,一个任务 一次只能阻塞数组中的一条通知,且不会 被发送到任何其他数组索引的通知解除阻塞状态。

默认情况下,RTOS 任务通知功能为启用状态,并且可以 通过将 FreeRTOSConfig.h 中的 configUSE_TASK_NOTIFICATIONS 设置为 0 将其从构建中排除(每个数组索引的每个任务节省 8 字节)。

重要提示: FreeRTOS 流和消息缓冲区 使用 数组索引 0 的任务通知。 若希望保持 调用流或消息缓冲区 API 函数的任务通知,可 使用数组索引大于 0 的任务通知。


性能优势和使用限制

任务通知具有高度灵活性,使用时无需 创建单独 队列二进制信号量计数信号量事件组。 通过直接通知解除 RTOS 任务阻塞状态的速度和使用中间对象(如二进制信号量)相比快了 45% *使用的 RAM 也更少 。 不过 这些性能优势也有一些意料之内的使用限制:
  1. RTOS 任务通知仅可在只有一个任务 可以接收事件时使用。 不过,这个条件在 大多数真实世界情况下是满足的。比如,中断解除了一个任务的阻塞状态,该任务 将处理由中断接收的数据。

  2. 仅可在使用 RTOS 任务通知代替 队列时使用: 当某个接收任务可在阻塞状态下等待通知 (因而不花费任何 CPU 时间)时,发送任务不能 在阻塞状态下等待发送完成(在发送不能立刻完成的情况下) 。


用例

通知使用 xTaskNotifyIndexed()xTaskNotifyGiveIndexed() API 函数(及其 中断安全等效物)进行发送 并保持挂起,直到接收到 RTOS 任务调用 (来自 xTaskNotifyWaitIndexed()ulTaskNotifyTakeIndexed() API 函数)。 每个上述 API 函数都有一个无 "Indexed" 前缀的等效物。 非 "Indexed" 版本始终在任务通知上以 数组索引 0 运行。 例如,xTaskNotifyGive( TargetTask ) 等同于 xTaskNotifyGiveIndexed( TargetTask, 0 ),两者都在任务索引 0 处 对由以 TargetTask 为句柄的任务所引用的任务进行增量。

示例


* 通过使用二进制信号量实现进行测量。该实现由 FreeRTOS V8.1.2 版本使用 GCC 于 -O2 优化时编译而成,未定义 configASSERT()。 仍可使用 FreeRTOS V8.2.0 和更高版本中经优化的二进制信号量实现以获得 35% 的提升。





Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.