第十七章 FreeRTOS的任务通知

目录

一. 任务通知的简介

1.1 任务通知值的更新方式

1.2 任务通知的优势及劣势

 二. 任务通知值和任务通知状态

2.1 任务通知值

2.2 任务通知状态 

三. 任务通知的相关函数

3.1 发送通知相关API函数

3.1.1 xTaskGenericNotify()

3.2 接收通知相关API函数

 3.2.1 ulTaskNotifyTake()

3.2.2 xTaskGenericNotifyWait()


一. 任务通知的简介

      FreeRTOS的每个任务都有一个32位的通知值,任务控制块中的成员变量ulNotifiedValue就是这个通知值。

    

      任务通知是一个事件,假如某个任务通知的接收任务,因为等待任务通知而阻塞的话,则向这个接收任务发送任务通知,就会解除这个任务的阻塞状态。

使用任务通知时,任务结构体TCB中就包含了内部对象,可以直接接收别人发过来的"通知"


1.1 任务通知值的更新方式

① 不覆盖接收任务的通知值 (如果上次发送给接收任务的通知还没有被处理) 。
② 覆盖接收任务的通知值。
③ 更新接收任务通知值的一个或多个bit。
④ 增加接收任务的通知值。


1.2 任务通知的优势及劣势

任务通知的优势

效率更高

使用任务通知向任务发送事件或数据比使用队列、事件标志组或信号量快得多

使用内存更小

使用其他方法时都要先创建对应的结构体,使用任务通知时无需额外创建结构体

任务通知的劣势

无法发送数据给ISR

ISR没有任务结构体,所以无法给ISR发送数据。但是ISR可以使用任务通知的功能,发数据给任务。

无法广播给多个任务

任务通知只能是被指定的一个任务接收并处理

无法缓存多个数据

任务通知是通过更新任务通知值来发送数据的,任务结构体中只有一个任务通知值,只能保持一个数据。

发送受阻不支持阻塞

发送方无法进入阻塞状态等待


 二. 任务通知值和任务通知状态

typedef struct tskTaskControlBlock
{
	/*.....*/

	#if( configUSE_TASK_NOTIFICATIONS == 1 )
		volatile uint32_t ulNotifiedValue;    // uint32_t 类型,用来表示通知值
		volatile uint8_t ucNotifyState;       // uint8_t 类型,用来表示通知状态
	#endif

	/*.....*/

} tskTCB;

2.1 任务通知值

任务通知值的更新方式有多种类型:

计数值       (数值累加,类似信号量)
相应位置一(类似事件标志组)
任意数值    (支持覆写和不覆写,类似队列)

2.2 任务通知状态 

任务通知状态共有3种:

任务未等待通知  (任务通知默认的初始化状态)
等待通知             (接收方已经准备好了(调用了接收任务通知函数),等待发送方给个通知)
等待接收             (发送方已经发送出去(调用了发送任务通知函数),等待接收方接收)

三. 任务通知的相关函数

任务通知API函数主要有两类

        ①发送通知               ②接收通知

注意

        发送通知API函数可以用于任务和中断服务函数中接收通知API函数只能用在任务中


3.1 发送通知相关API函数

函数

描述

xTaskNotify()

发送通知,带有通知值

xTaskNotifyAndQuery()

发送通知,带有通知值并且保留接收任务的原通知值

xTaskNotifyGive()

发送通知,不带通知值

xTaskNotifyFromISR()

在中断中发送任务通知

xTaskNotifyAndQueryFromISR()

vTaskNotifyGiveFromISR()

#define    xTaskNotifyAndQuery( xTaskToNotify ,  
                                 ulValue ,  
                                 eAction , 
                                 pulPreviousNotifyValue    
                               )	 

		   xTaskGenericNotify( ( xTaskToNotify ), 
					           ( tskDEFAULT_INDEX_TO_NOTIFY ), 
					           ( ulValue ), 
					           ( eAction ),
					           ( pulPreviousNotifyValue ) 
                             )

--------------------------------------------------------------------

#define    xTaskNotify  (  xTaskToNotify ,  
                           ulValue ,  
                           eAction  
                        ) 							

 		   xTaskGenericNotify(  ( xTaskToNotify ) ,  
                                ( tskDEFAULT_INDEX_TO_NOTIFY ) ,  
                                ( ulValue ) ,  
                                ( eAction ) ,  
                                ( NULL  )
                             )

--------------------------------------------------------------------

#define    xTaskNotifyGive (  xTaskToNotify  )
		   xTaskGenericNotify(  ( xTaskToNotify ) ,  
                                ( tskDEFAULT_INDEX_TO_NOTIFY ) , 
                                ( 0 ) ,  
                                ( eIncrement ),  
                                ( NULL )
                             )                                        

3.1.1 xTaskGenericNotify()

xTaskNotify()、xTaskNotifyAndQuery()、xTaskNotifyGive() 三个宏函数,调用的全都是xTaskGenericNotify() 这个函数。

BaseType_t	 xTaskGenericNotify(  TaskHandle_t 	    xTaskToNotify,
                                  UBaseType_t 	    uxIndexToNotify,
                                  uint32_t 		    ulValue,
                                  eNotifyAction 	eAction,
                                  uint32_t * 		pulPreviousNotificationValue  
                               )

形参

描述

xTaskToNotify

接收任务通知的任务句柄

uxIndexToNotify

任务的指定通知(任务通知相关数组成员)

ulValue

任务通知值

eAction

通知方式(通知值更新方式)

pulPreviousNotificationValue

用于保存更新前的任务通知值(为NULL则不保存)

typedef  enum
{    
	eNoAction = 0, 			    /* 无操作 */
	eSetBits				    /* 更新指定bit */
	eIncrement				    /* 通知值加一 */
 	eSetValueWithOverwrite		/* 覆写的方式更新通知值 */
	eSetValueWithoutOverwrite	/* 不覆写通知值 */
} eNotifyAction;

3.2 接收通知相关API函数

函数

描述

ulTaskNotifyTake()

获取任务通知,可以设置在退出此函数的时候将任务通知值清零或者减一。

当任务通知用作二值信号量或者计数信号量的时候,使用此函数来获取信号量。

xTaskNotifyWait()

获取任务通知,比 ulTaskNotifyTak()更为复杂,可获取通知值和清除通知值的指定位

总结

当任务通知用作于信号量时,使用函数获取信号量: ulTaskNotifyTake ()
当任务通知用作于 事件标志组或队列 时,使用此函数来获取: xTaskNotifyWait ()

 3.2.1 ulTaskNotifyTake()

uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )

形参

描述

xClearCountOnExit

指定在成功接收通知后,将通知值清零或减 1

pdTRUE:把通知值清零;pdFALSE:把通知值减一

xTicksToWait

阻塞等待任务通知值的最大时间

返回值

描述

0

接收失败

0

接收成功,返回任务通知的通知值


3.2.2 xTaskGenericNotifyWait()

BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, 
                            uint32_t ulBitsToClearOnExit, 
                            uint32_t *pulNotificationValue, 
                            TickType_t xTicksToWait 
                          )

形参

描述

uxIndexToWaitOn

任务的指定通知(任务通知相关数组成员)

ulBitesToClearOnEntry

等待前清零指定任务通知值的比特位(旧值对应bit0

ulBitesToClearOnExit

成功等待后清零指定的任务通知值比特位(新值对应bit0

pulNotificationValue

用来取出通知值(如果不需要取出,可设为NULL

xTicksToWait

阻塞等待任务通知值的最大时间

返回值

描述

pdTRUE

等待任务通知成功

pdFALSE

等待任务通知失败

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值