欢迎光临
我们一直在努力

Free RTOS:任务通知

目录

1.任务通知的本质

2.任务通知的原理

每个任务都有一个结构体:TCB(Task Control Block),里面有 2 个成员:

TCB结构体

通知状态有3种取值:

3种取值

通知值可以有很多种类型:

图理解

3.任务通知的优势

4.任务通知的限制

不能发送数据给 ISR:

数据只能给该任务独享

无法缓冲数据

无法广播给多个任务

如果发送受阻,发送方无法进入阻塞状态等待

5.任务通知的使用

简化版函数

发送通知函数

取出通知函数

专业版函数

参发送通知函数(参数1,参数2,参数3)

任务A发通知给任务B,B里的Val值怎么修改,是看参数3

取出通知函数(参数1,参数2,参数3,参数4)


1.任务通知的本质

在之前的队列、信号量、互斥量、事件组这些操作里面,任务A给任务B传输信息或者数据,双发都是不知道对方是谁的

任务通知也可以叫通知任务,两个任务之间的传输信息或数据等等,他们都是明确直到对方的,然后就可以通过一个函数去传递信息或者数据了

使用队列、信号量、事件组时,我们都要事先创建对应的结构体,双方通过中间的结构体通信:

使用任务通知时,任务结构体TCB中就包含了内部对象,可以直接接收别人发过来的"通知":


2.任务通知的原理

每个任务都有一个结构体:TCB(Task Control Block),里面有 2 个成员:

一个是 uint8_t 类型,用来表示通知状态

一个是 uint32_t 类型,用来表示通知值

TCB结构体

通知状态有3种取值:

taskNOT_WAITING_NOTIFICATION:任务没有在等待通知

taskWAITING_NOTIFICATION:任务在等待通知

taskNOTIFICATION_RECEIVED:任务接收到了通知,也被称为 pending(有数据了,待处理)

3种取值

通知值可以有很多种类型:

计数值

位(类似事件组)

任意数值

图理解


3.任务通知的优势

效率更高:使用任务通知来发送事件、数据给某个任务时,效率更高。比队列、信号量、事件组都有大的优势

更节省内存:使用其他方法时都要先创建对应的结构体,使用任务通知时无需额外创建结构体


4.任务通知的限制

不能发送数据给 ISR:

ISR 并没有任务结构体,所以无法使用任务通知的功能给 ISR 发送数据。但是ISR 可以使用任务通知的功能,发数据给任务

数据只能给该任务独享

使用队列、信号量、事件组时,数据保存在这些结构体中,其他任务、ISR 都可以访问这些数据。使用任务通知时,数据存放入目标任务中,只有它可以访问这些数据

在日常工作中,这个限制影响不大。因为很多场合是从多个数据源把数据发给某个任务,而不是把一个数据源的数据发给多个任务

无法缓冲数据

使用队列时,假设队列深度为 N,那么它可以保持 N 个数据

使用任务通知时,任务结构体中只有一个任务通知值,只能保持一个数据

无法广播给多个任务

使用事件组可以同时给多个任务发送事件

使用任务通知,只能发个一个任务

如果发送受阻,发送方无法进入阻塞状态等待

假设队列已经满了,使用 xQueueSendToBack()给队列发送数据时,任务可以进入阻塞状态等待发送完成

使用任务通知时,即使对方无法接收数据,发送方也无法阻塞等待,只能即刻返回错误


5.任务通知的使用

场景任务A发通知给任务B,任务B接收到了A发送的通知值,对应任务B里的Val值

任务通知有两类函数,简化版函数和专业版函数

简化版函数

发送通知函数

任务A使用了发送通知函数,不论任务B要不要接收这个函数,里面的Val值都会++

取出通知函数

如果任务B使用了取出通知函数,那么就进入等待任务通知的状态(阻塞状态),任务A使用发送通知函数,任务B就被唤醒,变为已经接收到了通知的通知状态,然后Val值–,然后,处理任务A发送的数据或信息

如果任务B没有使用取出通知函数,Val值会一直++,通知状态变为已经接收到了通知,但是,并不会影响任务B的运行状态

专业版函数

参发送通知函数(参数1,参数2,参数3)

参数1:需要通知的任务

参数2:需要发送的通知值

参数3:发送的通知值怎么用

任务A发通知给任务B,B里的Val值怎么修改,是看参数3

eNoAction:A发通知给B只是把B的状态变为已经接收到通知,不会修改B里的Val值

eSetBits:比如A发了一个通知值,设置B里的Val值中的一位bit3为1

eIncrement:不会在意任务A传入了什么通知值,只是将任务B里的Val值在原来的基础上加1

eSetValueWithoutOverwrite:就是当任务B为已经接收到通知的状态,就不会覆盖B里的Val值

eSetValueWithOverwrite:不论任务B是什么状态,都将任务A的通知值覆盖任务B中的Val值

取出通知函数(参数1,参数2,参数3,参数4)

参数1:函数入口处,若是还没有接收到通知的状态,就清除任务B的Val值的某些位,如果是接收到了通知的状态,就不会清除任务B的Val值的某些位

参数2:收到通知和保存通知值后,清除任务B的Val值的若干位

参数3:收到通知后,这个指针用来保存通知值

参数4:超时时间

赞(0)
未经允许不得转载:171主机测评 » Free RTOS:任务通知
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址