FreeRTOS 任务通知
FreeRTOS 任务通知
简介
FreeRTOS的任务之间都是相互独立的,这些任务间可能需要通信。任务通信有不同的方式,一般有两种:通过中间对象通信、直接通信。
通过中间对象通信
数据并不是直接由发送->接收,而是通过一个中间对象传递。
任务间直接通信——任务通知
任务通知允许任务、中断之间直接通信而不用中间对象。
配置
通过将configUSE_TASK_NOTIFICATIONS 设置为 1 开启功能
prob & cons
优点:快,省内存
缺点:
- 不能通过消息通知将数据发送给ISR
- 不能向多个任务发送
- 只能包含一个值
- 任务通知的发送不能进入阻塞态
API
xTaskNotifyGive() 发送通知
vTaskNotifyGiveFromISR() 中断中发送通知
ulTaskNotifyTake() 获取通知
示例 用任务通知替换信号量
图解
xTaskNotify() xTaskNotifyFromISR()
xTaskNotify()是xTaskNotifyGive()的一个功能更强大的版本,可以通过以下任何方式更新接收任务的通知值:
- 增加任务通知数值
- 选择一位或多位任务通知数值。类似于轻量版的事件组!
- 在接收任务的通知值中写入一个全新的数,但前提是接收任务自上次更新后已读取其通知值。这允许任务的通知值提供与长度为1的队列所提供的功能相似的功能。
- 在接收任务的通知值中写入一个全新的数,即使接收任务自上次更新后尚未读取其通知值。这允许任务的通知值提供与xQueueOverwrite()的功能类似的功能。有时称为“邮箱”。
xTaskNotifyWait()
xTaskNotifyWait()是ulTaskNotifyTake()的一个更强大的版本。它允许任务等待(可选超时),以便调用任务的通知状态变为挂起(如果尚未挂起), xTaskNotifyWait()为调用任务的通知值中需要清楚地位提供了选项,无论是在进入函数时还是退出函数时。
示例 UART
外围驱动程序库提供在硬件接口上执行常见操作的功能。通常为其提供此类库的外围设备的示例包括通用异步接收器和发射器(uart)、串行外围接口(SPI)端口、模数转换器(adc)和以太网端口。这些库通常提供的功能的示例包括初始化外设、向外设发送数据和从外设接收数据的功能。
一些外围设备上的操作需要相对较长的时间才能完成。此类操作的示例包括高精度ADC转换和在UART上传输大数据包。在这些情况下,可以实现驱动程序库功能来轮询(重复读取)外围设备的状态寄存器,以确定操作何时完成。然而,这种方式的轮询几乎总是浪费时间,因为它在不执行生产性处理的情况下利用了处理器的100%时间。在多任务系统中,这种浪费尤其昂贵,因为在多任务系统中,轮询外围设备的任务可能会阻止执行具有生产性处理的低优先级任务。
为了避免浪费处理时间的可能性,一个高效的RTOS感知设备驱动程序应该是中断驱动的,并且给一个启动长时间操作的任务一个选项,就是在阻塞状态下等待操作完成。这样,低优先级的任务可以在执行长时间操作的任务处于阻塞状态时执行,并且没有任务使用处理时间,除非它们能够有效地使用它。