在FreeRTOS中可以使用任务通知来代替信号量、消息队列、事件标志组等这些东西。使用任务通知的话效率会更高。
***任务信号量(即任务通知)***和任务消息队列分别与多值信号量和消息队列非常相似,不同之处是,前者仅发布给一个特定任务,而后者可以发布给多个任务。 因此,前者的操作相对比较简单,而且省时。 如果任务信号量和任务消息队列可以满足设计需求,那么尽量不要使用普通多值信号量和消息队列 任务信号量伴随任务存在,只要创建了任务,其任务信号量就是该任务的一个数据成员,任务信号量的数据成员被包含在任务控制块里。
一、任务通知简介
任务通知在 FreeRTOS 中是一个可选的功能,要使用任务通知的话就需要将宏configUSE_TASK_NOTIFICATIONS 定义为 1。FreeRTOS 的每个任务都有一个 32 位的通知值,任务控制块中的成员变量 ulNotifiedValue就是这个通知值。任务通知是一个事件,假如某个任务通知的接收任务因为等待任务通知而阻塞的话,向这个接收任务发送任务通知以后就会解除这个任务的阻塞状态。
也可以更新接收任务的任务通知值。
任务通知可以通过如下方法更新接收任务的通知值:
● 不覆盖接收任务的通知值(如果上次发送给接收任务的通知还没被处理)。
● 覆盖接收任务的通知值。
● 更新接收任务通知值的一个或多个 bit。
● 增加接收任务的通知值。
合理、灵活的使用上面这些更改任务通知值的方法可以在一些场合中替代队列、二值信号量、计数型信号量和事件标志组。使用任务通知来实现二值信号量功能的时候,解除任务阻塞的时间比直接使用二值信号量要快 45%。
虽然FreeRTOS任务通知速度更快并且占用内存更少,但它也有一些限制:
只能有一个任务接收通知事件。(只能给一个任务发送,消息队列可以多任务)
接收通知的任务可以因为等待通知而进入阻塞状态,但是发送通知的任务即便不能立即完成通知发送也不能进入阻塞状态。
每个RTOS任务都有一个32位的通知值,任务创建时,这个值被初始化为0。FreeRTOS任务通知相当于直接向任务发送一个事件,接收到通知的任务可以解除阻塞状态,前提是这个阻塞事件是因等待通知而引起的。发送通知的同时,也可以可选的改变接收任务的通知值。
二、相关API函数
1.发送任务通知函数
向指定任务发送指定的通知值。如果打算使用RTOS任务通知实现轻量级的二进制或计数信号量,推荐使用API函数xTaskNotifyGive()来代替本函数。
1.1 函数 xTaskNotify()
1.2 函数 xTaskNotifyFromISR()
1.3 函数 xTaskNotifyGive()
1.4 函数 vTaskNotifyGiveFromISR()
1.5 函数 xTaskNotifyAndQuery()
1.6 函数 xTaskNotifyAndQueryFromISR()
2.获取任务通知
2.1 函数 ulTaskNotifyTake()
2.2 函数 xTaskNotifyWait()