0
点赞
收藏
分享

微信扫一扫

第20章 任务通知

一、任务通知的基本概念

任务控制块有一个32位的成员变量用作通知值,有些情况下可以取代信号量(二值信号量、计数信号量)、事件组、以及长队为1的消息队列。

任务通知的优势:

(1)不需要额外创建通讯资源,如信号量、消息队列、事件组这些都是需要通过创建后才能够使用,

(2)解除阻塞速度比其他通讯方式快45%,

(3)不需要额外占用RAM空间

任务通知的缺点:

(1)只能一个任务接收任务通知消息

(2)只有等待通知的任务被进入阻塞状态,发送通知的任务不会因发送失败进入阻塞状态

二、任务通知的运作机制

每个任务有一个32位的通知值ulNotifiedValue,任务在等到的通知暂时无效时,任务会根据用户指定的阻塞超时事件进入阻塞状态,阻塞时间超时或者有任务通知被发送,阻塞的任务会从阻塞状态恢复为就绪状态。

另外等待任务通知只可以在任务中,不允许在中断中进行,但是发送通知可以在任务或者中断中进行

三、任务通知的数据结构

任务控制块结构体里的两个成员变量,一个是32位通知值ulNotifiedValue另一个是8位的通知状态ucNotifyState

第20章 任务通知_句柄

四、任务通知函数

1.发送任务通知函数,

发送任务通知有3中操作,每个操作具有两个版本:带中断保护不带中断保护

(1)xTaskNotifyGivexTaskNotifyGiveFromISR

可做二值信号量和计数信号量的一种轻量型实现,任务通知值只做加1操作,

2)xTaskNotifyxTaskNotifyFromISR

发送任务通知时指定通知值,任务通知值会更新,并且更新的方式由参数决定

(3)xTaskNotifyAndQuery和xTaskNotifyAndQueryFromISR

用于发送新通知值的通知回收上一次的任务通知值:任务通知值会更新更新方式由参数决定,同时根据最后参数选择是否回传原的任务通知值

注:以上3组在任务中的发送通知函数(即不带FromISR),会调用一个通用的任务通知发送函数,经过封装后,传入的参数有些不一样

2.通用的任务通知发送函数xTaskGenericNotify

该函数有4个参数:目标任务句柄(即被通知的任务句柄,或者接收该通知的任务句柄)、任务通知值、通知值的更新方式(四种更新方式:按位或、自加、覆盖、条件覆盖)、任务原通知值(可以通过该参数回传原来任务的通知值)

通知发送的设计思路:

(1)根据参数判断是否需要回传原任务通知值,如果要回传,则赋值到第四个参数中

(2)保留通知目标任务的任务状态,同时更新目标任务通知状态为接收通知状态

(3)根据任务值更新方式,对目标任务的通知值进行更新,更新方式有4种:

------eSetBits:任务通知值按位或上新任务通知

------eIncrement:任务通知值自加

------eSetValueWithOverWrite无条件更新任务通知值

------eSetValueWithoutOverwrite:如果上一次任务通知值没有被取走,则不做覆盖,只有被取走后,才对任务通知值进行更新

------eNoAction只发送通知不更新任务通知值,可以理解为催促目标任务赶紧把任务通知取走

(4)判断目标任务是否由于等待任务通知而进入阻塞状态,如果是,则将目标任务从阻塞延时列表中移除,添加到任务就绪列表中,使得任务进入就绪状态,下一次任务切换时可以被切换

(5)完成目标任务进入就绪状态后,判断目标任务优先级是否比当前任务优先级高,如果是,则进行任务抢占式切换

第20章 任务通知_信号量_02

第20章 任务通知_句柄_03

第20章 任务通知_阻塞状态_04

3.任务通知值加1方式的发送通知xTaskNotifyGive()

类似于释放一个信号量的操作,任务通知值的更新方式为加1方式,通用任务通知发送函数封装后,参数只有目标任务句柄,

第20章 任务通知_阻塞状态_05


4.中断版本的加1方式发送通知xTaskNotifyGiveFromISR

设计思路与通用的任务通知发送函数类似,只是将任务切换的动作放在退出中断前,而不是在发送任务通知函数里进行任务切换

第20章 任务通知_句柄_06

第20章 任务通知_阻塞状态_07

第20章 任务通知_阻塞状态_08

5.xTaskNotify()

发送任务通知的时候指定一个通知值,参数指定目标任务,任务通知值,任务通知值的更新方式

第20章 任务通知_句柄_09

6.带中断版本任务通知值的发送xTaskNotifyFromISR不返回原任务通知值

第20章 任务通知_句柄_10

最终调用的是带中断版本的通用的任务通知发送函数xTaskGenericNotifyFromISR该函数与任务版本的通用任务通知发送函数类似,只是将任务切换的动作挪到发送函数外,退出中断之前执行,而任务版本的任务通知发送函数的任务切换是在发送消息后,调用抢占式的任务发送

第20章 任务通知_句柄_11

7.发送任务通知并返回原任务通知值xTaskNotifyAndQuery

第20章 任务通知_句柄_12

相比上一个发送任务通知的函数xTaskNotify,该函数多了一个返回原任务通知值的一个操作

8.带中断版本的发送任务通知并返回原通知值函数xTaskNotifyAndQueryFromISR

核心函数还是xTaskGenericNotifyFromISR

第20章 任务通知_阻塞状态_13

9.获取任务通知函数

获取任务通知函数智能出现在任务中,不能够出现在中断函数里,有两个API函数:ulTaskNotifyTakexTaskNotifyWait

(1)ulTaskNotifyTake

获取的是xTaskNotifyGive和xTaskNotifyGiveFromISR这两个发送函数发送的来的任务通知,类似于信号量的获取函数,当任务通知值大于0时,该获取函数才能有效,否则任务将会进入阻塞等待状态,

函数设计思路:先判断任务通知值是否为0,任务值是0进入阻塞状态,任务值不为0,将任务值返回,并且根据参数xClearCountOnExit,是否对任务值进行清0操作,否则只进行普通的减1操作

第20章 任务通知_句柄_14

第20章 任务通知_句柄_15

(2)全功能版本等待任务通知函数xTaskNotifyWait

该等待函数可以等待任务任务通知发送函数发送来的通知

函数有四个参数:处理任务通知前需要置位指定位,退出函数时需要清除置定位,原任务通知值返回,无通知时等待的时长

设计思路,同样是在没有任务通知值的时候,将根据通知值置位参数,对任务通知值先做清除指定位的操作,然后将任务进行阻塞等待,当任务在次被唤醒时,根据退出函数通知值置位参数,对通知值进行处理,然后改变任务通知的状态

第20章 任务通知_信号量_16

第20章 任务通知_句柄_17

第20章 任务通知_阻塞状态_18


学习心得:

1.理解到任务通知其实是任务控制块里添加的两个成员变量,一个是任务通知值,一个是任务通知状态

2.任务通知的发送:6个发送函数(3个任务版本,3个中断版本

(1)第一类是类似与信号量的释放,任务通知值进行加1处理xTaskNotifyGive和xTaskNotifyGiveFromISR

(2)第二类是发送任务通知值xTaskNotify()和xTaskNotifyFromISR,这个函数指定通知值,以及值的更新方式,总共有5中更新方式:按位或、自加、无条件覆盖、有条件覆盖、不更新

(3)第三类是发送任务通知值并查询原任务通知值,与第二类差不多,只是比第二类的函数多了一个保存原任务通知值的阐述

(4)理解任务通知发送的机制:保存原值-----更新状态-----根据任务通知值更新方式修改任务通知值------唤醒阻塞状态的任务-----根据被唤醒的任务优先级高低切换任务(中断版本是退出发送函数后,进行任务切换)

3.任务通知的获取:

(1)分两个类型,一类是单纯地获取任务通知值后,通知值进行有条件的减1操作;另一类是先对任务通知值进行有条件的置位操作,再获取任务通知值,在退出接收函数前对任务通知值进行有条件的置位操作

(2)理解接收的机制:改变任务通知状态-----有条件地对任务通知值进行处理-----任务进入阻塞等待状态----任务切换------任务唤醒-----保留原任务通知值------有条地修改任务通知值----返回

举报

相关推荐

0 条评论