FreeRTOS#7——任务通知
任务通知
-
任务通知也是用于任务间进行同步和通讯的一种机制,但是相对于前面章节介绍的队列、事件标志组和信号量等而言,任务通知在内存占用和效率方面都有很大的优势
-
在 FreeRTOS 中,每一个任务都有两个用于任务通知功能的数组,分别为任务通知数组和任务通知状态数组。其中任务通知数组中的每一个元素都是一个 32 位无符号类型的通知值;而任务通知状态数组中的元素则表示与之对应的任务通知的状态。
-
任务通知数组中的 32 位无符号通知值,用于任务到任务或中断到任务发送通知的“媒介”。当通知值为 0 时,表示没有任务通知;当通知值不为 0 时,表示有任务通知,并且通知值就是通知的内容。
-
任务通知有三种状态,分别为未等待通知状态、等待通知状态和等待接收通知状态,其中未等待通知状态为任务通知的复位状态;当任务在没有通知的时候接收通知时,在任务阻塞等待任务通知的这段时间内,任务所等待的任务通知就处于等待通知状态;当有其他任务向任务发送通知,但任务还未接收这一通知的这段期间内,任务通知就处于等待接收通知状态
-
任务通知功能所使用到的任务通知数组和任务通知状态数组为任务控制块中的成员变量,因此任务通知的传输是直接传出到任务中的,不同通过中间媒介 即 任务的通讯对象(队列、事件标志组和信号量就属于通讯对象)这个间接的方式
优势
- 速度快
- 不需要额外开销
劣势
- 不能发送事件或数据到中断
- 通讯对象可以发送事件或数据从中断到任务,或从任务到中断,但是由于任务通知依赖于任务控制块中的两个成员变量,并且中断不是任务,因此任务通知功能并不适用于从任务往中断发送事件或数据的这种情况,但是任务通知功能可以在任务之间或从中断到任务发送事件或数据。
- 不能同时接收多个任务
- 通讯对象可以被已知通讯对象句柄的任意多个任务或中断访问(发送或接收),但任务通知是直接发送事件或数据到指定接收任务的,因此传输的事件或数据只能由接收任务处理。然而在实际中很少受到这种情况的限制,因为,虽然多个任务和中断发送事件或数据到一个通讯对象是很常见的,但很少出现多个任务或中断接收同一个通讯对象的情况。
- 不能缓冲多个数据项
- 通讯对象中的队列是可以一次性保存多个已经被发送到队列,有着一定的缓冲多个数据的能力,但是任务通知是通过更新任务通知值来发送事件或数据的,一个任务通知值只能保存一次。
- 不能同时发送到多个任务
- 通讯对象中的事件标志组是可以将一个事件同时发送到多个任务中的,但任务通知只能是被指定的一个接收任务接收并处理。
- 不能 阻塞等待接收任务
- 当通讯对象处于暂时无法写入的状态(例如队列已满,此时无法再向队列写入消息)时,发送任务是可以选择阻塞等待接收任务接收,但是任务因尝试发送任务通知到已有任务通知但还未处理的任务而进行阻塞等待的。但是任务通知也很少在实际情况中收到这种情况的限制。
相关API
发送任务通知
-
xTaskNotify()
- 用于往指定任务发送任务通知,通知方式可以自由指定,并且不获取发送任务通知前任务通知的通知值
-
xTaskNotifyAndQuery()
- 用于往指定任务发送任务通知,通知方式可以自由指定,并且获取发送任务通知前任务通知的通知值
-
xTaskNotifyGive()
- 用于往指定任务发送任务通知,通知方式为将通知值加 1,并且不获取发送任务通知前任务通知的通知值
-
xTaskNotifyIndexed()
-
xTaskNotifyAndQueryIndexed()
-
xTaskNotifyGiveIndexed()
在中断中发送任务通知
- xTaskNotifyFromISR()
- xTaskNotifyAndQueryFromISR()
- vTaskNotifyGiveFromISR()
- xTaskNotifyIndexedFromISR()
- xTaskNotifyAndQueryIndexedFromISR()
- vTaskNotifyGiveIndexedFromISR()
接收任务通知
-
ulTaskNotifyTake()
- 用于获取任务通知的通知值,并且在成功获取任务通知的通知值后,可以指定将通知值清零或减 1
-
xTaskNotifyWait()
- 用于等待任务通知通知值中的指定比特位被置一,此函数可以在等待前和成功等待到任务通知通知值中的指定比特位被置一后清零指定比特位,并且还能获取等待超时后任务通知的通知值
-
ulTaskNotifyTakeIndexed()
-
xTaskNotifyWaitIndexed()
更多推荐

所有评论(0)