FreeRTOS-TaskNotify

本文档深入探讨了FreeRTOS中的任务通知功能,一种无需创建额外通信对象就能实现任务间交互的方式。任务通知提供了快速、低内存开销的通信手段,但也存在局限性,例如不能用于ISR到任务的通信。文中详细介绍了任务通知的优势、API用法、示例以及在中断处理和外围设备驱动中的应用,展示了如何使用任务通知代替信号量进行数据传输。
摘要由CSDN通过智能技术生成
 

9.1本章介绍与范围

已经看到,使用FreeRTOS的应用程序被构造为一组独立的任务,并且这些任务很可能必须彼此通信,以便它们可以共同提供有用的系统功能。

通过中介对象进行通信

本书已经描述了任务之间可以相互通信的各种方式。 到目前为止描述的方法需要创建通信对象。 通信对象的示例包括队列,事件组和各种不同类型的信号量。

使用通信对象时,事件和数据不会直接发送到接收任务或接收ISR,而是会发送到通信对象。 同样,任务和ISR从通信对象接收事件和数据,而不是直接从发送事件或数据的任务或ISR接收事件和数据。 这在图76中进行了描述。

在这里插入图片描述

任务通知-直接进行任务通信

“任务通知”允许任务与其他任务进行交互,并与ISR同步,而无需单独的通信对象。 通过使用任务通知,任务或ISR可以将事件直接发送到接收任务。 这在图77中进行了描述。

在这里插入图片描述

任务通知功能是可选的。 要包括任务通知功能,请在FreeRTOSConfig.h中将configUSE_TASK_NOTIFICATIONS设置为1。

当configUSE_TASK_NOTIFICATIONS设置为1时,每个任务都有一个“通知状态”(可以是“挂起”或“未挂起”)和一个“通知值”(一个32位无符号整数)。 当一个任务收到通知,其通知状态设置为挂起。 当任务读取其通知值时,其通知状态将设置为“未挂起”。

任务可以在“阻止”状态下等待,并具有可选的超时时间,以使其通知状态变为挂起状态。

范围

本章旨在使读者更好地理解:

  • 任务的通知状态和通知值。
  • 如何以及何时可以使用任务通知代替通信对象(例如信号量)。
  • 使用任务通知代替通信对象的优点。

9.2任务通知; 好处和局限性

任务通知的性能优势

使用任务通知将事件或数据发送到任务比使用队列,信号量或事件组执行等效操作要快得多。

任务通知的RAM足迹优势

同样,与使用队列,信号量或事件组执行等效操作相比,使用任务通知将事件或数据发送到任务所需的RAM要少得多。 这是因为必须先创建每个通信对象(队列,信号量或事件组),然后才能使用它,而启用任务通知功能具有固定的开销,即每个任务只有8个字节的RAM。

任务通知的局限性

与通信对象相比,任务通知速度更快并且使用的RAM更少,但是任务通知不能在所有情况下都使用。 本节介绍了无法使用任务通知的方案:

  • 将事件或数据发送到ISR
    通信对象可用于从ISR向任务以及从任务向ISR发送事件和数据。
    任务通知可用于将事件和数据从ISR发送到任务,但不能用于将事件或数据从任务发送到ISR。

  • 启用多个接收任务
    任何知道其句柄(可能是队列句柄,信号量句柄或事件组句柄)的任务或ISR都可以访问该通信对象。 任何数量的任务和ISR都可以处理发送到任何给定通信对象的事件或数据。
    任务通知直接发送到接收任务,因此只能由发送通知的任务处理。 但是,这在实际情况中很少受到限制,因为尽管有多个任务和ISR发送到相同的通信对象是很常见的,但很少有多个任务和ISR从同一个通信对象接收到。

  • 缓冲多个数据项
    队列是一次可以容纳多个数据项的通信对象。 已发送到队列但尚未从队列接收的数据被缓冲在队列对象中。
    任务通知通过更新接收任务的通知值将数据发送到任务。 任务的通知值一次只能保存一个值。

  • 广播多个任务
    事件组是一个通信对象,可用于一次将事件发送到多个任务。
    任务通知直接发送到接收任务,因此只能由接收任务处理。

  • 在阻止状态下等待发送完成
    如果通信对象暂时处于无法再写入任何数据或事件的状态(例如,当队列已满时,无法再向该队列发送任何数据),则尝试写入该对象的任务可以 (可选)进入“阻止”状态,以等待其写入操作完成。
    如果任务试图将任务通知发送到已经有待处理的通知的任务,则发送任务不可能在“阻止”状态下等待接收任务重置其通知状态。 可以看出,在使用任务通知的实际情况下,这很少是一种限制。

9.3使用任务通知

任务通知API选项

任务通知是一项非常强大的功能,通常可以用来代替二进制信号量,计数信号量,事件组,有时甚至是队列。 通过使用xTaskNotify()API函数发送任务通知,并使用xTaskNotifyWait()API函数接收任务通知,可以实现广泛的使用场景。

但是,在大多数情况下,不需要xTaskNotify()和xTaskNotifyWait()API函数提供的完全灵活性,并且更简单的函数就足够了。 因此,提供xTaskNotifyGive()API函数作为xTaskNotify()的一种更简单但不太灵活的替代方法,并且提供ulTaskNotifyTake()API函数作为xTaskNotifyWait()的一种更简单但不太灵活的替代方法。

xTaskNotifyGive()API函数

xTaskNotifyGive()直接向任务发送通知,并增加(添加一个)接收任务的通知值。 调用xTaskNotifyGive()会将接收任务的通知状态设置为“挂起”(如果尚未挂起)。

提供了xTaskNotifyGive()1 API函数,以使任务通知的重量更轻,并且可以更快地替代二进制或计数信号量。

在这里插入图片描述

Parameter Name/ Returned Value Description
xTaskToNotify 将通知发送到的任务的句柄-有关获取任务句柄的信息,请参阅xTaskCreate()API函数的pxCreatedTask参数。
Returned value xTaskNotifyGive()是调用xTaskNotify()的宏。 设置宏传递给xTaskNotify()的参数,以使pdPASS是唯一可能的返回值。 本书稍后将介绍xTaskNotify()。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值