FreeRTOS学习笔记(九)任务通知

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

 &esmp;任务通知功能允许我们可以在不创建任务队列、信号量的前提下为任务发送信息,但这种发送只能发送给一个任务,且只有等待的任务被阻塞。


一、任务通知是什么

1.1 任务通知的引入

  从Free RTOS的V8.2.0版本开始,增加了任务通知这一功能,每一个任务都有32位的通知值,在大多数情况下,任务通知可以代替二值信号量、计数信号量、长度为1的队列已经事件组,但是不可以代替互斥量。任务控制块中的成员变量 ulNotifiedValue就是这个通知值。任务通知是一个事件,假如某个任务通知的接收任务因为等待任务通知而阻塞的话,向这个接收任务发送任务通知以后就会解除这个任务的阻塞状态。也可以更新接收任务的任务通知值,任务通知可以通过如下方法更新接收任务的通知值:
● 不覆盖接收任务的通知值(如果上次发送给接收任务的通知还没被处理)。
● 覆盖接收任务的通知值。
● 更新接收任务通知值的一个或多个 bit。
● 增加接收任务的通知值

1.2 任务通知与队列/信号量的区别

在这里插入图片描述

1.3 任务通知的运行机制

  1. 无需创建、任务和中断都可以发送但是中断不可以等待通知。
  2. 发送通知: 其他任务或中断发送通知时,会修改目标任务的通知值。如果任务当前正在等待通知,接收到通知后它会立即从阻塞状态恢复执行。如果不阻塞,通知值会累积或替换,具体取决于发送通知时设置的操作模式。
  3. 等待通知: 任务可以通过ulTaskNotifyTake()或xTaskNotifyWait()等待通知值到来。在调用这些 API 时,任务可以选择:
    ● 阻塞直到接收到通知。
    ● 超时等待一段时间,若超时仍未收到通知则继续执行其他操作。
    ● 不阻塞直接检查通知值是否可用。
  4. 通知值的处理: 当任务收到通知时,它可以检查通知值,并根据值的变化(例如增加或减少)做出相应动作。任务的通知值可以代表任务的进度、状态或者某些计数。

二、相关API函数

2.1 通知发送

xTaskNotify()
  向目标任务发送通知,可以选择更新通知值(例如增加、设定或替换)。

BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, 
						uint32_t ulValue, eNotifyAction eAction )
  • 参数:

    • xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的。
    • ulValue: 任务通知值。
    • eAction: 任务通知更新的方法,eNotifyAction 是个枚举类型,可以选择枚举类型中的任意一个,不同的应用环境其选择也不同。
      • eNoAction = 0,
      • eSetBits:更新指定的 bit
      • eIncrement:通知值加一
      • eSetValueWithOverwrite:覆写的方式更新通知值
      • eSetValueWithoutOverwrite:不覆写通知值
  • 返回值:

    • 成功:pdPASS,若为eAction其他值统一返回pdPASS
    • 失败:pdFAIL,当参数 eAction 设置为 eSetValueWithoutOverwrite 的时候,如果任务通知值没有更新成功就返回 pdFAIL。

xTaskNotifyFromISR( )
  从中断服务程序(ISR)中发送通知,用于在中断中激活某个任务。此函数用于发送任务通知,是函数 xTaskNotify()的中断版本,此函数是个宏,真正执行的仍然是 xTaskGenericNotifyFromISR(),此函数原型如下:

BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue,  
			 eNotifyAction eAction,  BaseType_t *pxHigherPriorityTaskWoken );
  • 参数:
    • xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的。
    • ulValue: 任务通知值。
    • eAction: 任务通知更新的方法。
    • pxHigherPriorityTaskWoken: 记退出此函数以后是否进行任务切换
  • 返回值:
    • 成功:pdPASS
    • 失败:pdFAIL

xTaskNotifyGive()
  用于增加目标任务的通知值(适用于同步和简单的信号量用途)。
发送任务通知,相对于函数 xTaskNotify(),此函数发送任务通知的时候不带有通知值。此函数只是将任务通知值简单的加一,此函数原型如下:

BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
  • 参数:
    • xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的
  • 返回值:
    • pdPASS: 此函数只会返回 pdPASS

vTaskNotifyGiveFromISR( )
  此函数为 xTaskNotifyGive()的中断版本,用在中断服务函数中,函数原型如下:

void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, 
BaseType_t * pxHigherPriorityTaskWoken );
  • 参数:
    • xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的
    • pxHigherPriorityTaskWoken: 记退出此函数以后是否进行任务切换

xTaskNotifyAndQuery( )
  此函数和 xTaskNotify()很类似,此函数比 xTaskNotify()多一个参数,此参数用来保存更新前的通知值。此函数原型如下:

BaseType_t xTaskNotifyAndQuery ( TaskHandle_t xTaskToNotify, 
	uint32_t ulValue, eNotifyAction eAction, uint32_t * pulPreviousNotificationValue);
  • 参数:
    • xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的
    • ulValue: 任务通知值
    • eAction: 任务通知更新的方法
    • pulPreviousNotificationValue:用来保存更新前的任务通知值
  • 返回值:
    • 成功:pdPASS
    • 失败:pdFAIL

xTaskNotifyAndQueryFromISR( )
  此函数为 xTaskNorityAndQuery()的中断版本,用在中断服务函数中。此函数同样为宏,此函数的原型如下:

BaseType_t xTaskNotifyAndQueryFromISR ( TaskHandle_t xTaskToNotify, 
	uint32_t ulValue, eNotifyAction eAction, uint32_t * pulPreviousNotificationValue
	BaseType_t * pxHigherPriorityTaskWoken );
  • 参数:
    • xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的。
    • ulValue: 任务通知值。
    • eAction: 任务通知更新的方法。
    • pulPreviousNotificationValue:用来保存更新前的任务通知值。
    • pxHigherPriorityTaskWoken: 记退出此函数以后是否进行任务切换
  • 返回值:
    • 成功:pdPASS
    • 失败:pdFAIL

2.2 通知等待

ulTaskNotifyTake( )
  目标任务等待接收通知值,常用于任务同步。任务可以选择阻塞直到收到通知。此函数为获取任务通知函数,当任务通知用作二值信号量或者计数型信号量的时候可以使用此函数来获取信号量,函数原型如下:

uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t
			 xTicksToWait );
  • 参数:
    • xClearCountOnExit: 选择二值信号量或者计数型信号量,可选参数为:
      • pdFALSE:退出函数时任务通知值减一,类似计数型信号量
      • pdTRUE:退出函数的时候任务任务通知值清零,类似二值信号量
    • xTickToWait: 阻塞时间
  • 返回值:任务通知值减少或者清零之前的值。

xTaskNotifyWait( )
  任务等待通知值并处理,可以设置多个标志位等待特定的通知类型。此函数也是用来获取任务通知的,不过此函数比 ulTaskNotifyTake()更为强大,不管任务通知用作二值信号量、计数型信号量、队列和事件标志组中的哪一种,都可以使用此函数来获取任务通知。但是当任务通知用作位置信号量和计数型信号量的时候推荐使用函数ulTaskNotifyTake()。此函数原型如下:

BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t
  ulBitsToClearOnExit, uint32_t * pulNotificationValue, TickType_t xTicksToWait );
  • 参数:
    • ulBitsToClearOnEntry:当没有接收到任务通知的时候将任务通知值与此参数的取反值进行按位与运算,当此参数为 0xffffffff 或者 ULONG_MAX 的时候就会将任务通知值清零
    • ulBitsToClearOnExit:如果接收到了任务通知,在做完相应的处理退出函数之前将任务通知值与此参数的取反值进行按位与运算,当此参数为0xffffffff 或者ULONG_MAX 的时候就会将任务通知值清零
    • pulNotificationValue:此参数用来保存任务通知值
    • xTickToWait: 阻塞时间
  • 返回值:
    • 成功:pdTRUE
    • 失败:pdFALSE

xTaskNotifyStateClear( )
  xTaskNotifyStateClear() 是 FreeRTOS 提供的一个函数,用于清除任务的通知状态(即通知标志位),它的主要功能是将任务的通知状态重置为“未通知”状态。这通常用于确保任务不会处理旧的通知信号,特别是在任务需要明确从零开始等待新通知时。

void xTaskNotifyStateClear(TaskHandle_t xTask);
  • 参数说明
    • xTask: 这是目标任务的句柄,表示要清除通知状态的任务,如为 NULL,则表示清除调用此函数的当前任务的通知状态

免责声明:本文参考了网上公开资料,仅用于学习交流,若有错误或侵权请联系笔者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值