一.任务通知简介
1.什么是任务通知?
答:用来通知任务,任务控制块中的结构体成员变量ulNotfiedValue就是这个通知值。
2.为什么使用任务通知?
答:前面学习的队列,信号量,事件标志组也可以用作通知任务,但创建需要占用较大内存,
相较之下,任务通知消耗的内存比较小,无需提前创建。
使用任务通知时,任务结构体TCB就包含了内部对象,可以直接接收别人发送的通知。
任务一发送通知(对结构体成员变量赋值),任务二接收(直接读取成员变量的值)
3.任务通知值的更新方式
(1)不覆盖接收任务的通知值 (2)覆盖接收任务的通知值 类似于队列的覆写和不覆写
(3)更新接收任务通知值的一bit或多bit 类似于事件标志组读取某一位或多位
(4)增加接收任务的通知值(++) 类似于计数型信号量
4.任务通知的优势和劣势
优势
(1)效率高:使用任务通知向任务发送事件或数据,比队列、信号量、事件标志组更快。
(2)使用内存更小:使用其他方法时需要额外创建结构体,使用任务通知无需额外创建。
劣势
(1)无法向ISR发送数据:ISR(中断)没有任务结构体,无法给ISR发送数据。但ISR可以使用任务通知向任务发送数据。
(2)无法广播给多个任务:任务通知只能被指定的一个任务接收并处理(一对一)。
(3)无法缓存多个数据:任务通知通过更新任务通知的值来发送数据,任务结构体只有一个任务通知值,只能保持一个数据。
(4)发送受阻不支持阻塞:发送方无法进入阻塞状态等待。
5.任务通知值和任务状态
(1)任务通知值
多种更新方式:(1)计数值 (2)相应位置1 (3)任意数值,数值可覆盖
(2)任务通知状态(3种):
任务未等待通知:任务默认的初始化状态
等待通知:接收方已经准备好(调用接收通知的函数),等待发送方发送通知
等待接收:发送方已经发送完(调用发送通知的函数),等待接收方接收通知
二.任务通知相关的API函数
API函数主要分为:发送通知 和 接收通知
注意:发送任务通知可以在任务和中断服务函数中使用;接收任务通知只能在任务中使用
1.发送任务通知相关API函数
函数原型:
2.接收任务通知相关API函数
(1)ulTaskNotifyTake() 函数原型:用于模拟二值信号量和计数型信号量
(2)xTaskNotifyWait()函数原型:用于模拟队列和事件标志组
综合实验(模拟二值信号量):
1.创建2个任务,StartTaskKeySend,StartTaskRecMessage
StartTaskKeySend:按键KEY0按下,发送任务通知值发给StartTaskRecMessage任务
StartTaskRecMessage:接收StartTaskKeySend发送的任务通知值,未接收为阻塞态
2.CubeMX配置
(1)创建两个任务
此处省略任务创建.....
3.代码部分:
(1)StartTaskKeySend
(2)StartTaskRecMessage
现象:
综合实验(模拟计数型信号量):
1.创建2个任务,StartTaskKeySend,StartTaskRecMessage
StartTaskKeySend:按键KEY0按下,任务通知值++,并发给StartTaskRecMessage任务
StartTaskRecMessage:接收StartTaskKeySend发送的任务通知值,并打印,未接收为阻塞态
2.CubeMX配置
(1)创建两个任务
此处省略任务创建.....
3.代码部分:
(1)StartTaskKeySend
(2)StartTaskRecMessage
现象:
综合实验(模拟队列/消息邮箱):
1.创建2个任务,StartTaskKeySend,StartTaskRecMessage
StartTaskKeySend:按键按下,发送键值通过任务通知发送给指定任务
StartTaskRecMessage:接收StartTaskKeySend发送的任务通知值,对不同值进行不同处理
2.CubeMX配置
(1)创建两个任务
此处省略任务创建.....
3.代码部分:
(1)StartTaskKeySend
(2)StartTaskRecMessage
修改:图中0x01:清除bit0
现象:
综合实验(模拟事件标志组):
1.创建2个任务,StartTaskKeySend,StartTaskRecMessage
StartTaskKeySend:按键按下,发送任务通知设置不同的标志位
StartTaskRecMessage:接收任务通知,当按键KEY0和KEY1都按下,打印信息提示
2.CubeMX配置
(1)创建两个任务
此处省略任务创建.....
3.代码部分:
(1)StartTaskKeySend
(2)StartTaskRecMessage
现象: