FreeRTOS 任务通知

FreeRTOS 任务通知

简介

FreeRTOS的任务之间都是相互独立的,这些任务间可能需要通信。任务通信有不同的方式,一般有两种:通过中间对象通信、直接通信。

通过中间对象通信

数据并不是直接由发送->接收,而是通过一个中间对象传递。FreeRTOS 任务通知

任务间直接通信——任务通知

任务通知允许任务、中断之间直接通信而不用中间对象。
FreeRTOS 任务通知

配置

通过将configUSE_TASK_NOTIFICATIONS 设置为 1 开启功能

prob & cons

优点:快,省内存
缺点:

  • 不能通过消息通知将数据发送给ISR
  • 不能向多个任务发送
  • 只能包含一个值
  • 任务通知的发送不能进入阻塞态

API

xTaskNotifyGive() 发送通知

FreeRTOS 任务通知
FreeRTOS 任务通知

vTaskNotifyGiveFromISR() 中断中发送通知

FreeRTOS 任务通知

ulTaskNotifyTake() 获取通知

FreeRTOS 任务通知
FreeRTOS 任务通知
FreeRTOS 任务通知

示例 用任务通知替换信号量

FreeRTOS 任务通知
FreeRTOS 任务通知
图解
FreeRTOS 任务通知

xTaskNotify() xTaskNotifyFromISR()

xTaskNotify()是xTaskNotifyGive()的一个功能更强大的版本,可以通过以下任何方式更新接收任务的通知值:

  • 增加任务通知数值
  • 选择一位或多位任务通知数值。类似于轻量版的事件组!
  • 在接收任务的通知值中写入一个全新的数,但前提是接收任务自上次更新后已读取其通知值。这允许任务的通知值提供与长度为1的队列所提供的功能相似的功能。
  • 在接收任务的通知值中写入一个全新的数,即使接收任务自上次更新后尚未读取其通知值。这允许任务的通知值提供与xQueueOverwrite()的功能类似的功能。有时称为“邮箱”。

FreeRTOS 任务通知
FreeRTOS 任务通知
FreeRTOS 任务通知
FreeRTOS 任务通知

xTaskNotifyWait()

xTaskNotifyWait()是ulTaskNotifyTake()的一个更强大的版本。它允许任务等待(可选超时),以便调用任务的通知状态变为挂起(如果尚未挂起), xTaskNotifyWait()为调用任务的通知值中需要清楚地位提供了选项,无论是在进入函数时还是退出函数时。

FreeRTOS 任务通知

示例 UART

外围驱动程序库提供在硬件接口上执行常见操作的功能。通常为其提供此类库的外围设备的示例包括通用异步接收器和发射器(uart)、串行外围接口(SPI)端口、模数转换器(adc)和以太网端口。这些库通常提供的功能的示例包括初始化外设、向外设发送数据和从外设接收数据的功能。

一些外围设备上的操作需要相对较长的时间才能完成。此类操作的示例包括高精度ADC转换和在UART上传输大数据包。在这些情况下,可以实现驱动程序库功能来轮询(重复读取)外围设备的状态寄存器,以确定操作何时完成。然而,这种方式的轮询几乎总是浪费时间,因为它在不执行生产性处理的情况下利用了处理器的100%时间。在多任务系统中,这种浪费尤其昂贵,因为在多任务系统中,轮询外围设备的任务可能会阻止执行具有生产性处理的低优先级任务。

为了避免浪费处理时间的可能性,一个高效的RTOS感知设备驱动程序应该是中断驱动的,并且给一个启动长时间操作的任务一个选项,就是在阻塞状态下等待操作完成。这样,低优先级的任务可以在执行长时间操作的任务处于阻塞状态时执行,并且没有任务使用处理时间,除非它们能够有效地使用它。

UART 发送

FreeRTOS 任务通知

UART 接收

FreeRTOS 任务通知

示例 ADC

FreeRTOS 任务通知