目录
6、函数xTaskNotifyAndQueryFromISR()
从 v8.2.0 版本开始,FreeRTOS 新增了任务通知(Task Notifictions)这个功能,可以使用任务通知来代替信号量、消息队列、事件标志组等这些东西。使用任务通知的话效率会更高,当然,这也是我们学习它的原因。
1.了解任务通知
任务通知在FreeRTOS中是一个可选的功能,要使用任务通知的话就需要将宏configUSE_TASK_NOTIFICATIONS 定义为1。
这个宏在task.h函数里面,如下图
FreeRTOS 的每个任务都有一个 32 位的通知值,任务控制块中的成员变量 ulNotifiedValue 就是这个通知值。任务通知是一个事件,假如某个任务通知的接收任务因为等待任务通知而阻 塞的话,向这个接收任务发送任务通知以后就会解除这个任务的阻塞状态。也可以更新接收任 务的任务通知值,任务通知可以通过如下方法更新接收任务的通知值:
● 不覆盖接收任务的通知值(如果上次发送给接收任务的通知还没被处理)。
● 覆盖接收任务的通知值。
● 更新接收任务通知值的一个或多个 bit。
● 增加接收任务的通知值。
合理、灵活的使用上面这些更改任务通知值的方法可以在一些场合中替代队列、二值信号量、计数型信号量和事件标志组。使用任务通知来实现二值信号量功能的时候,解除任务阻塞的时间比直接使用二值信号量要快 45%(FreeRTOS 官方测试结果,使用v8.1.2 版本中的二值信号量,GCC 编译器,-O2 优化的条件下测试的,没有使能断言函数 configASSERT()),并且使用的RAM 更少!
任务通知的发送使用函数 xTaskNotify()或者 xTaskNotifyGive()(还有此函数的中断版本)来完成,这个通知值会一直被保存着,直到接收任务调用函数xTaskNotifyWait()或者ulTaskNotifyTake()来获取这个通知值。假如接收任务因为等待任务通知而阻塞的话那么在接收到任务通知以后就会解除阻塞态。
任务通知虽然可以提高速度,并且减少 RAM 的使用,但是任务通知也是有使用限制的:
● FreeRTOS 的任务通知只能有一个接收任务,其实大多数的应用都是这种情况。
● 接收任务可以因为接收任务通知而进入阻塞态,但是发送任务不会因为任务通知发送失败而阻塞。
注意!!! FreeRTOS 的每一个任务都有对应的通知值,但每一个通知只能有一个接收任务,所以它不能完全替代队列、信号量、事件组使用,使用时要根据实际情况灵活考虑。
2.任务通知发送函数
任务通知发送函数有 6 个,如下表:
1、函数 xTaskNotify()
此函数用于发送任务通知,此函数发送任务通知的时候带有通知值,此函数是个宏,真正执行的函数 xTaskGenericNotify(),函数原型如下: