一,任务通知介绍
任务通知能够使任务或者ISR直接发送一个事件到接收任务,使用任务通知之前,须将宏configUSE_TASK_NOTIFICATIONS设置为1。每个任务有一个任务通知状态和一个任务通知值,任务通知值是一个32位的无符号整型值。当一个任务接收到通知后,通知状态变为“Pending”,而在读取任务通知后,通知状态变为“Not-Pending”。
任务通知的优点是:
1,发送事件或者消息到一个任务比使用队列,信号量和事件组更有快,。
2,任务通知占用更小的内存开销,每个任务只有固定的八字节开销。
任务通知的缺点是:
1,任务通知不能够从任务发送事件或者数据到ISR。
2,任务通知只能一个接收任务。
3,不能缓冲多个数据。
4,任务通知的发送任务不会因为任务状态为‘Not-Pending’而进入阻塞状态。
二,任务通知API函数
1,xTaskNotifyGive()为xTaskNotify()的一个特定参数的宏,使用该宏会使任务通知的值增加1,并且使任务通知的状态更改为“Pending”,可以替代二进制信号量和计数信号量使用。
2,ulTaskNotifyTake()为xTaskNotifyWait()的一个特定参数的宏,根据传入参数的不同,该函数可以使用任务通知的值减1或者清零。
3,xTaskNotify() and xTaskNotifyFromISR()能够使用下面多种方式更新接收任务的通知值。
a,使接收任务的通知值加1,这种情况下和xTaskNotifyGive()的功能一样。
b,设置一位或者多位接收任务的通知值。这时接收任务的通知值能够作为一种更快,更轻量级的事件组使用。
c,当接收任务的通知值被读取以后,可以完全重新写接收任务的通知值。这时任务通知的值可以作为一个长度为1的队列功能使用。
d,直接更新接收任务的通知值,不管上次的通知值是否被读取。这时任务通知的值提供了类似于xQueueOverwrite() API的功能,这种行为有时候也被叫作“mailbox”。
其中eAction参数的说明如下:
4,xTaskNotifyWait()能够选择进入函数或者退出函数时,将通知值清零。
三,应用举例
1,使用信号量设计UART发送函数
上面的应用有下面几个缺点:
a,使用了多个信号量,增加了RAM开销。
b,要先创建信号量,才能使用。
c,当信号量可以使用时,需要从阻塞在该信号量上面的任务重选择进入就绪状态的任务,这需要增加处理开销,而在该应用中,不可能在任何时间都存在多个任务阻塞在该信号量上。
使用任务通知设计的UART发送函数可以避免上面缺点
上面需要注意的是:xTaskToNotify能够被任务和中断访问,如果一个内存写操作可以更新xTaskToNotify,那么将xTaskToNotify的更新可以放在临界段之外,如:在32位的机器上面更新32位的变量。否则需要在临界段之内更新xTaskToNotify的值,如:在16位的机器上面更新32位的变量。
使用任务通知设计的UART接收函数
2,使用任务通知的值来存储ADC值得应用举例:
3,任务通知在云服务器连接上面的应用举例如下: