嵌入式实时操作系统μCOS原理与实践4.ppt

上传人:本田雅阁 文档编号:3206536 上传时间:2019-07-31 格式:PPT 页数:49 大小:1.08MB
返回 下载 相关 举报
嵌入式实时操作系统μCOS原理与实践4.ppt_第1页
第1页 / 共49页
嵌入式实时操作系统μCOS原理与实践4.ppt_第2页
第2页 / 共49页
嵌入式实时操作系统μCOS原理与实践4.ppt_第3页
第3页 / 共49页
嵌入式实时操作系统μCOS原理与实践4.ppt_第4页
第4页 / 共49页
嵌入式实时操作系统μCOS原理与实践4.ppt_第5页
第5页 / 共49页
点击查看更多>>
资源描述

《嵌入式实时操作系统μCOS原理与实践4.ppt》由会员分享,可在线阅读,更多相关《嵌入式实时操作系统μCOS原理与实践4.ppt(49页珍藏版)》请在三一文库上搜索。

1、嵌入式实时操作系统C/原理与实践,教材 :嵌入式实时操作系统C/OS原理与实践 电子工业出版社 作者:卢有亮 电子科技大学能源科学与工程学院,第4章 事件管理,4.1 事件管理重要数据结构 4.2 事件管理程序 4.3 信号量管理 4.4 互斥信号量管理 4.5事件标志组管理 习题,C/OS-II作为实时多任务操作系统,是事件驱动的,支持信号量,消息等机制。 事件主要包括信号量和互斥信号量,而事件的组合可以用事件标志组来管理。 本章的内容包括事件管理中数据结构,事件管理程序,信号量管理,互斥型信号量管理,以及事件标志组管理。,4.1 事件管理重要数据结构,4.1.1 事件控制块ECB,事件控

2、制块ECB在事件管理中占据着举足轻重的作用。虽然事件控制块ECB并没有任务控制块TCB的内容丰富,但是在事件处理中仍然是核心的数据结构,频繁被访问。ECB的定义出现在操作系统的头文件ucos_ii.h中。,4.1.2事件等待组和事件等待表,一个事件块标志着一个事件,等待这个事件的任务在事件块的事件等待组和事件等待表中标记自己的存在,然后被阻塞。当事件发生的时候,操作系统会找到优先级最高的等待事件发生的任务,并将该任务就绪,然后在事件等待组和事件等待表中取消该任务的标记。事件等待组和事件等待表的关系和就绪组与就绪表的关系是完全相同的。,上图没有任务等待事件的发生,因此就绪组为0,就绪表的内容也是

3、全0。假设有优先级为20和32的任务在等待事件的发生,那么就绪组和就绪表应如下图所示:,4.1.3事件控制块空闲链表,事件管理中,将空闲的事件块链接为一个单向的链表,事件控制块空闲链表。这个链表的形式和任务块TCB的空闲链表的形式是完全相同的。 当创建一个事件的时候,要在事件控制块ECB空闲链表查找是否有空闲的ECB可用。如果有就从链表中取出分配给事件。要做这件事,首先要找到链表的表头,因此声明了一个重要的全局变量OSEventFreeList指示表头的地址,称之为事件空闲链表指针。 OSEventFreeList的定义为: OS_EVENT *OSEventFreeList; 在事件控制块初

4、始化程序结束的时候,该链表如图所示。,4.2.1 事件控制块ECB初始化,事件控制块的初始化在操作系统初始化函数OS_Init中被调用事件控制块的初始化函数是OS_InitEventList 表4.3 ECB初始化函数OS_InitEventList解析 ECB初始化函数OS_InitEventList首先清空了所有的ECB块,也就是清空了事件表。然后从0到OS_MAX_EVENTS - 1u)循环对除最后一个ECB块之外的所有ECB块进行初始化,并顺便构建了单向的链表。循环结束后最后一个ECB 块OSEventTblOS_MAX_EVENTS - 1进行初始化。最后一个事件控制块OSEven

5、tTblOS_MAX_EVENTS - 1的OSEventPtr域指向空地址0,构造完成了如图4-3所示的空闲事件控制块链表。 然后将ECB空闲链表的表头地址给OSEventFreeList,初始化完成,4.2 事件管理程序,4.2.2 事件等待表初始化,当建立一个事件或消息,如信号量、邮箱、消息队列时,如信号量的建立函数OSSemCreate等,需要对事件等待表进行初始化。 表4.4事件等待表初始化函数为OS_EventWaitListInit解析 pevent-OSEventGrp = 0u; /* 清空任务等待组*/ for (i = 0u; i OSEventTbli = 0u; /*

6、 采用循环模式清空任务等待表*/ ,4.2.3设置事件等待,当任务等待事件发生,并获得事件控制块ECB后,需要在ECB中标记任务在等待事件的发生,才可以在事件发生时取消任务的阻塞。 表4.5事件等待函数OS_EventTaskWait解析 OS_EventTaskWait做了两件事情: 1.标记。在ECB中登记本任务,即在ECB的事件等待表中对应优先级处标记为1,事件等待组中对应位标记为1。 2.取消标记。在就绪表和就绪组中取消对该事件就绪的标记,将就绪表中对应优先级处标记为0,如果就绪表该任务所在的一组没有任务就绪,将就绪组中的对应位标记为0。,4.2.4取消事件等待,OS_EventTas

7、kRemove 是与OS_EventTaskWait相反的操作,当一个事件由于某种原因不再需要等待事件需运行OS_EventTaskRemove 。 void OS_EventTaskRemove (OS_TCB *ptcb, OS_EVENT *pevent) INT8U y; y = ptcb-OSTCBY; pevent-OSEventTbly /*删除事件等待组的事件等待标志*/ ,4.2.5将等待事件的任务就绪,任务因为等待事件而在ECB中登记自己的等待,当事件发生的时候,如果该任务是事件等待表中优先级最高的任务,就绪被取消等待而回到就绪状态。等待的事件发生的函数为OS_EventT

8、askRdy 表4.8将等待事件的任务就绪函数OS_EventTaskRdy的声明 表4.9将等待事件的任务就绪函数OS_EventTaskRdy解析 OS_EventTaskRdy的流程为: 1.在事件等待表和事件等待组中找到最高优先级的等待任务的优先级。 2.根据优先级查优先级指针表,找到该任务的任务控制块TCB指针。 3.对任务控制块的相关参数进行赋值。 4.判断任务是否被挂起,如果未被挂起就将任务就绪。完成从阻塞态到就绪态的转移。 5.调用OS_EventTaskRemove在ECB的事件等待表中删除该任务。 6.返回任务的优先级。,4.3 信号量管理,信号量在资源共享管理,任务同步与

9、通信等方面都有广泛的应用。C/OS-II单独为信号量管理编写了C文件os_sem.c。,4.3.1 信号量的建立OSSemCreate,信号量在操作系统初始化的时候并不存在。这时操作系统中的事件管理数据结构事件控制块ECB为全空,所有的事件控制块都在ECB空闲链表中排队。信号量的建立函数OSSemCreate将使用一个并配置一个ECB,使其具备信号量的属性。 表4.11创建信号量函数OSSemCreate解析 假设信号量值为5,则赋值后的ECB应该如图4-4所示。,宏OS_EVENT_TYPE_SEM的值是3,所以ECB中的OSEventType的值为3。假设该信号量为创建的第一个事件,那么图

10、4.3的事件空闲任务链表将去掉第一个事件控制块,变为如图4.5所示。,4.3.2 信号量的删除OSSemDel,信号量如果不再使用了就应该尽快删除,否则很快系统就没有可用的事件块可用。 信号量的删除函数是OSSemDel。 删除信号量比创建一个信号量更复杂 。 表4.12删除信号量函数OSSemDel解析,4.3.3 请求信号量OSSemPend,请求信号量也称为等待信号量。等待信号量的参数为3个,分别是ECB的指针pevent,32位无符号整数超时时间timeout,和用来返回结果的指向整型的指针perr。 表4.13等待信号量函数OSSemPend解析,4.3.4 提交信号量,当任务A获得

11、信号量之后将信号量数字减1,然后就可以访问资源R。这时,如果信号量的值为0,任务B如果也要访问资源R,必须等待信号量,因此将任务B阻塞。任务A在对资源的访问完成之后,应将信号量的值加1。因为资源已经可以被其他的任务访问了,因此应该将任务B唤醒,使任务B就绪。 当访问资源的任务有2个以上,资源R可同时被N个任务访问,因此信号量的值在最开始创建的时候应该等于N。当任务A访问信号量,信号量值变为N-1,任务B又访问,信号量等于N-2,当第M个任务访问,信号量等于N-M。当N-M=0的时候,也就是当N=M的时候,当第N+1也要访问该资源R,第N+1个任务必须等待。当任何一个任务(例如第2个)访问资源完

12、成,应该唤醒第N+1个任务让其访问资源。当第N+1个任务访问完成之后,因为没有其他的任务等待信号量,只需简单地将信号量值加1。 表4.14提交信号量函数OSSemPost解析,4.3.5 无等待请求信号量,在中断服务程序和有些用户任务中,需要无等待的请求信号量。也就是说,使用信号量请求资源,当没有可用的资源,信号量为0的时候,并不阻塞自己,而是继续执行其他代码。OSSemAccept就是无等待的请求信号量函数 。 表4.15无等待地请求信号量函数OSSemAccept解析 1进行参数检查 2将信号量的值赋值给局部变量cnt,如果cnt 0说明资源有效或信号量有效,因此将信号量的值减1然后哦返回

13、cnt,可以执行访问资源的代码了。如果函数返回值为0,不能执行访问资源的代码。,4.3.6 放弃等待信号量,放弃等待信号量并非放弃本任务对信号量的等待。 如果是放弃本任务对信号量的等待,那么本任务在等待信号量,那么本任务应该处于阻塞状态,一个处于阻塞状态的任务得不到运行,怎么能执行放弃等待信号量的代码呢?因此,一定是放弃其他任务对一个信号量的等待。 表4.16放弃等待信号量函数OSSemPendAbort解析 1.参数检查,如果ECB指针无效或ECB的类型不是信号量类型,返回参数检查错误信息。 2.如果pevent-OSEventGrp为0说明没有任务等待信号量,返回0。 3.否则根据参数op

14、t(选项)进行分支转移,如果为OS_PEND_OPT_BROADCAST,使用while语句循环地将等待该信号量的每个任务用OS_EventTaskRdy来取消等待并使其就绪(除非任务还被挂起);如果为其他值则只将最高优先级的任务取消等待并就绪之。两种情况下都返回取消等待信号量的任务数。,4.3.7 信号量值设置,操作系统提供了直接设置信号量值的函数OSSemSet。一般情况下无需使用该函数设置信号量的值,应该在信号量创建的时候初始化信号量的值。当一个信号量的值在创建之后为N,每次有任务请求信号量就将该值减1,反之将该值加1,一般情况下是不允许随便修改的。但是,在极其特殊的情况下,因为某种特殊

15、的需要,例如突然增加了其他的资源,需要修改资源数N,可采用OSSemSet直接对信号量赋值,但条件是这时没有任务在等待该信号量。 表4.17设置信号量值函数OSSemSet解析,4.3.8 查询信号量状态,信号量状态查询将ECB中关于信号量的信息拷贝到另一个数据结构信号量数据OS_SEM_DATA,信号量数据OS_SEM_DATA的声明见下表。 表4.19查询信号量状态函数OSSemQuery解析,4.3.9 信号量应用举例,假设有共享资源R,允许2个任务分时访问R,那么信号量的值应设置为2。系统中有3个用户任务访问资源R,分别为任务A、B、C,优先级分别为7、6、5。三个任务在操作系统初始化

16、和启动多任务之前被创建。任务A运行后创建信号量,并访问R,访问完成后任务A将自己阻塞1000个时钟周期,也就是10秒。任务B先阻塞300个时钟周期,然后操作步骤同任务A。任务C先阻塞400个时钟周期,然后操作步骤同任务A。假设三个任务才做资源R需要的时间都是1000个时钟周期,对资源R的操作可以用延时语句虚拟完成。 表4.20操作资源R的三个任务的实现代码,4.3 互斥信号量管理,互斥信号量是一种特殊的信号量,取值只能是0或1。也就是说,只能有一个任务访问的独占资源,应采用互斥信号量来管理。独占资源在系统中是非常常见的,例如各种IO端口如串口、USB设备、网络设备等。为了保证系统的实时性,拒绝

17、优先级反转,对互斥信号量的管理采用了优先级继承机制。 优先级继承机制: 优先级继承机制对优先级升级的机制以优化系统的调度。例如当前的任务的优先级是比较低的,如优先级为50。优先级为3的任务请求互斥信号量的时候因为信号量已被占有所以只有阻塞。这时有优先级为20的任务就绪,而不请求该互斥信号量。因此优先级为20的任务会先运行。如果又有优先级为30、40的任务运行,那么优先级为50的任务总也得不到运行也就不能释放信号量,更可怕的是优先级为3的任务还在苦苦等待信号量。这样,就发生了优先级反转。代码中的解决办法为将占有信号量的任务的优先级提高,例如提高为2,这样保证他对互斥资源处理完成,释放资源后又恢复

18、他本来的优先级50,优先级为3的任务就不需要等待优先为20、30、40的那些中等优先级任务的运行了,纠正了优先级反转!,4.4.1 互斥信号量的建立,与信号量一样,互斥信号量在操作系统初始化的时候并不存在。这时操作系统中的事件管理数据结构事件控制块ECB为全空,所有的事件控制块都在ECB空闲链表中排队。信号量的建立函数OSMutexCreate将使用并配置一个ECB,使其具备互斥信号量的属性。 不同的是,互斥信号量中采用了优先级升级技术,因此OSMutexCreate使用了一个优先级参数prio来创建信号量,含义是:prio是取得信号量的任务的被提升的优先级。含义是如果某任务取得了互斥信号量而

19、使用互斥资源,这时候高优先级的任务试图取得互斥信号量,那么拥有此资源的任务就被提升为优先级prio。目的是使正在使用互斥信号量的资源优先级高于在请求该互斥信号量的任务 表4.22创建互斥信号量函数OSMutexCreate解析,4.4.2 请求互斥信号量,因为涉及优先级继承机制,请求互斥信号量与请求信号量的操作有极大的差异。虽然如此,但是两者的参数是完全相同的。请求互斥信号量的参数为3个,分别是ECB的指针pevent,32位无符号整数超时时间timeout,和用来返回结果的指向整型的指针perr。请求互斥信号量函数为OSMutexPend,代码和分析见表4.17。,4.4.3 互斥信号量的删

20、除,互斥信号量的删除函数是OSMutexDel。参数OSSemDel一样,是ECB指针pevent、整型的删除选项opt和用来返回结果的指向整型的指针perr。其中opt的值为 OS_DEL_NO_PEND 表示只有当没有任务等待该事件的时候才允许删除,opt的值为 OS_DEL_ALWAYS 表示无论如何都删除。 OSMutexDel在表4.18中解析。,4.4.4 发互斥信号量,当任务占有互斥信号量后就可以对互斥资源进行访问,这时候ECB中的OSEventCnt高8位是优先级继承优先级,低8位占有互斥信号量的任务的优先级。任务在对互斥资源访问完成后,应调用OSMutexPos提交互斥信号量

21、,或称发互斥信号量。这时候,如果任务的优先级是经过升级的,就要恢复原来的优先级,即OSEventCnt中低8位。如果有任务等待互斥信号量,就可以恢复最高优先级的等待任务为就绪态,否则只需设置互斥信号量有效然后返回即可表4.14提交信号量函数OSSemPost解析 表4.25提交互斥信号量函数OSMutexPost解析,4.4.5 无等待请求互斥信号量,在有些用户任务中,需要无等待的请求互斥信号量。也就是说,使用互斥信号量请求互斥资源,当互斥资源已经被占用的时候,并不阻塞自己,而是继续执行其他代码。OSMutexAccept就是无等待的请求互斥信号量函数,参数是请求的信号量的ECB指针,和以地址

22、形式传递的错误码供返回错误信息。返回值是BOOLEAN型表示否取得资源访问权 表4.26无等待地请求互斥信号量函数OSMutexAccept解析,4.4.6 查询互斥信号量状态,信号量状态查询将ECB中关于互斥信号量的信息拷贝到另一个数据结构OS_SEM_DATA,互斥信号量数据OS_MUTEX_DATA的声明见下表。 表4.28查询互斥信号量状态函数OSMutexQuery解,4.4.7 改变任务的优先级并重新就绪,在互斥信号量的请求和删除等部分都调用了OSMutex_RdyAtPrio函数,这个函数的功能是改变任务的优先级,并将任务按新的优先级重新就绪。因为在前面并没有详细论述,因此在互斥

23、信号量管理的最后部分讨论这个函数。该函数有两个参数分别是任务控制块的指针和任务的优先级。 表4.29改变任务的优先级并重新就绪函数OSMutex_RdyAtPrio解析,4.4.8 互斥信号量应用举例,假设有高优先级任务TaskMutex1和低优先级任务TaskMutex2,以及中任务TaskPrint。任务信息列如表4.30所示。,表4.31互斥信号量管理应用例程,4.5 事件标志组管理,在信号量和互斥信号量的管理中,任务请求资源,如果资源未被占用就可继续运行,否则只能阻塞,等待资源释放的事件发生。这种事件是单一的事件。如果任务要等待多个事件的发生,或多个事件中的某一个事件的发生就可以继续运

24、行,那么就应该采用本章的事件标志组管理。 举例说明,若创建一个事件标志组,这个事件标志组中的事件标志定义如图 :,当事件A和D发生的时候,事件标志应如图,如果一个任务请求事件标志组,请求的标志为0x03,条件是全部事件发生,因为0x03是00000011,因此要求事件A和事件B都发生才能继续运行,因此要被阻塞。只有等待上图中的位0和位3都为1的时候才能被就绪。 如果请求的标志还是0x03,但是条件是任务事件发生,那么由于A事件已经发生,任务可以继续运行。,4.5.1事件标志组数据结构,事件标志组OS_FLAG_GRP,4.5.1事件标志组数据结构,事件标志节点OS_FLAG_NODE,4.5.

25、1事件标志组数据结构,事件标志组实体 OS_FLAG_GRP OSFlagTblOS_MAX_FLAGS。 OS_MAX_FLAGS是宏,默认值是5。这里是生成了数组OSFlagTbl, 占用了S_MAX_FLAGS* SizeOf(OS_FLAG_GRP)那么大的存储空间。,4.5.1事件标志组数据结构,事件标志组链表 所有没有被使用的事件标志组连接为一个单向的链表,这个链表被称为空闲事件标志组链表。 事件标志组中OSFlagWaitList用来指示空闲事件标志组链表中的下一个事件标志组。如果该事件标志组是空闲事件标志组链表中的最后一个,那么OSFlagWaitList的值就是一个空指针。

26、如果要创建一个事件标志组,就需要在这个链表中取出一个。 为了找到这个链表,定义了全局变量OSFlagFreeList指示该链表的表头。,4.5.1事件标志组数据结构,事件标志节点链表 等待事件标志组的任务每个都要占用一个事件标志组节点,如果等待某事件事件标志组的任务数有N个,那么这N个事件标志组节点就要手来手链接为一个双向链表,这个链表就是事件标志节点链表。 事件标志组中的OSFlagWaitList这时用来找到该链表,也就是指向该链表的表头。 C/OS-II的所有的链表操作,删除和添加都是在表头进行的。,4.5.2事件标志组初始化,事件标志组的初始化函数在操作系统的初始化中被调用,函数名称为

27、OS_FlagInit。 表4.36事件标志组初始化函数OS_FlagInit分析 流程为: 1.将所有事件标志组全部清为全0。 2.使用for循环将除最后一个事件标志组OSFlagTblOS_MAX_FLAGS - 1之外的所有事件标志组初始化,并基本构建了单向的事件标志组空闲链表。,4.5.2创建事件标志组,和信号量或互斥信号量的管理一样,要使用事件标志组依然需要创建。创建事件标志组就是将从事件标志组空闲链表的表头取下一个事件标志组,将其各种属性进行设置。初创建事件标志组的函数名称为OSFlagCreate。参数是事件标志flags和为返回运行信息而传递的地址参数,perr。创建事件标志组

28、的函数OSFlagCreate的代码分析见下表。 表4.37事件标志组创建函数OSFlagCreate分析 流程如下: 1.判断是否在中断服务程序中调用本函数,如果是就返回。 2. 取得事件标志组的链表首地址送pgrp。 3.判断pgrp是否为空指针,如果是则说明是系统已经没有空闲的事件标志组可供使用,填写错误信息,返回空指针。 4.从空闲事件标志组链表取下表头,对pgrp所指的事件标志组的各个域进行赋值。 5.返回事件标志组的指针pgrp。,4.5.3事件标志组阻塞函数,事件标志阻塞函数OS_FlagBlock是C/OS-II的内部函数,功能是将事件阻塞,直到请求的事件标志被设置。 表4.3

29、8事件标志阻塞函数OS_FlagBlock的定义 表4.39事件标志阻塞函数OS_FlagBlock分析 根据对代码的分析,流程如下: 1.首先是针对任务控制块TCB的操作,在OSTCBStat中设置事件标志组等待标志,将OSTCBStatPend初始化事件等待状态,给OSTCBDly赋值为超时时间,给OSTCBFlagNode赋值为当前事件标志节点地址。 2.然后设置节点中各个域,包括事件标志,节点类型和TCB地址。 3.在事件节点等待任务链表的头部插入本节点。 4.在事件标志组中修改事件等待节点链表的首地址。 5.取消任务的就绪标志。 该函数在下小节事件请求事件标志函数中就将被调用。,4.

30、5.4请求事件标志,请求事件标志组函数OSFlagPend用于等待事件标志组中的组合条件。用户任务可以任意任务位被置位或所有位都被置位。 表4.40事件标志组创请求函数OSFlagPend的函数声明 表4.41事件标志组请求函数OSFlagPend分析 1.首先要说明的是事件标志节点的声明 2.消费标志的提取和等待标志的提纯。 3.根据wait_type执行不同的代码。 4.在以上设置完成后,执行一次任务调度,本任务将进入阻塞态。 5.当事件标志中满足本任务要求的事件发生,即A事件和C事件都发生的情况,任务被重新就绪,再获得运行,将而在(5)处继续执行。,4.5.5 删除事件标志组,和其他事件

31、的删除函数一样,OSFlagDel也要进行谨慎的操作。OSFlagDel的参数是事件标志组的指针pgrp、整型的删除选项opt和用来返回结果的指向整型的指针perr。其中opt的值为 OS_DEL_NO_PEND 表示只有当没有任务等待该事件标志组的时候才允许删除,opt的值为 OS_DEL_ALWAYS 表示无论如何都删除。Perr用于返回运行过程的一些信息。返回值OS_FLAG_GRP为事件标志组的指针。下表给出OSFlagDel的代码解析。 表4.43 事件标志组删除函数OSFlagDel解析 1.参数检查,及判断是否在ISR中调用,是否是有效的事件标志组类型,选项是否有效。 2. 根据

32、标志组中OSFlagWaitList是否为空指针,判断是否有任务在等待。根据判断结果对tasks_waiting赋值。 3.如果选项为OS_DEL_NO_PEND,若tasks_waiting为假,可删除该事件标志组。删除方法是初始化该事件标志组的各个域,然后归还给空闲事件标志组链表,然后返回0;如果tasks_waiting为真,不能删除该事件标志组,返回事件标志组的指针。 4. 如果选项为OS_DEL_NO_ALWAYS,找到第一个事件标志节点送pnode, 循环调用OS_FlagTaskRdy将所有等待事件标志组的任务就绪。初始化事件标志组的各个域,将事件标志组添加回空闲事件标志组链表,

33、然后执行一次任务调度,最后返回0。,4.5.6 提交事件标志组,提交事件标志组函数将对事件标志组中的事件标志进行操作,并根据事件等待的标志,恢复阻塞的任务就绪。是事件标志组管理中的核心函数之一 表4.44 事件标志组提交函数OSFlagPost解析 1.参数检查。 2.根据选项为清除或置位,设置新的事件标志组的事件标志。 3. 将sched设置为假。 4. 找到第一个事件标志节点赋值给pnode。 5. 遍历事件标志节点链表,根据事件标志节点任务的等待类型OSFlagNodeWaitType和等待标志OSFlagNodeFlags,判断是否该任务的等待条件已经满足。如果满足,就将该任务就绪,并

34、将sched设置为真。 6.如果sched为真,就执行一次任务调度。这时从阻塞态回到就绪态的任务有可能获得运行。 7.返回当前事件标志的标志。,4.5.7标志节点任务就绪,标志节点任务就绪函数OS_FlagTaskRdy执行的功能比较简单,实现的功能是将事件是将事件标志节点指示的任务块进行赋值,如果该任务只等待事件标志,那么由于事件标志有效,将该任务就绪。返回是否需要调度。 表4.45 标志节点任务就绪函数OS_FlagTaskRdy代码解析 该函数首先在事件标志节点中找到事件控制块地址,然后对事件控制块中的一些域赋值,清任务延迟时间。因为等待事件标志组成功,因此将OSTCBStat中的事件标

35、志组等待标志清除。OSTCBFlagsRdy中是使任务就绪的事件标志,将参数flags_rdy赋值给他。将OSTCBStatPend赋值为OS_STAT_PEND_OK,表示等待成功结束。 然后,如果OSTCBStat = OS_STAT_RDY,即去除掉事件标志等待状态后,任务没有其他的事件等待了,那么就可以将该任务就绪。操作就绪表,将任务就绪,然后返回真表示需要进行调度。如果OSTCBStat != OS_STAT_RDY,那么说明事件还等待其他的任务,或者被挂起,不能将任务就绪,返回假。,4.5.8无等待的请求事件标志,与信号量管理类似,事件标志管理中存在无等待地请求事件标志的函数,这个

36、函数就是OSFlagAccept。 表4.46 无等待的请求事件标志OSFlagAccept代码解析 该函数首先进行参数检查,然后从等待类型waittype中提取消费标志consume,以及将等待类型提纯后赋值回waittype,然后根据waittype、请求的事件标志flags,以及事件标志组中的事件标志,判定是否已经满足了请求的条件。如果满足了条件,根据消费标志consume判定是否进行消费,返回时perr 所指存储单元的值为 OS_ERR_NONE。如果请求的条件不满足,perr所指存储单元的值为OS_ERR_FLAG_NOT_RDY。调用该函数的任务根据perr获取是否请求成功。,4.

37、5.9事件标志管理应用举例,假设有任务TaskDataProcess。任务TaskDataProcess是数据处理任务,处理的数据是由4个输入输出(IO)任务TaskIO1TaskIO4每秒接收不同端口的数据,并将接收的数据分别存放在8位无符号整型数组IO410中。当4个IO任务都将数据接收完成,任务TaskDataProcess才能进行数据处理。 表4.47无等待的请求事件标志OSFlagAccept代码解析,习题 1. 事件控制块的初始化过程对哪里数据结构进行了处理,都做了哪些处理。假设最大事件数量是5,画出初始化后的空闲控制块链表。 2.解释事件等待函数OS_EventTaskWait,

38、该函数是如何实现在事件等待表中添加任务的事件等待标志的? 3.解释取消事件等待函数OS_EventTaskRemove,该函数是如何实现在事件等待表中取消任务的事件等待标志的? 4.用流程图形式画出将等待的任务就绪函数 OS_EventTaskRdy的流程。 5. 有任务A、任务B、任务C均访问资源R,资源R只能被两个任务同时访问。应该采用哪种事件处理机制来管理对R的访问,请编写这三个任务。(任务的其他信息自己定义) 6. 互斥信号量管理和信号量管理的最大区别是什么?假设有高优先级任务A、中优先级任务B、低优先级任务C均访问互斥资源源R,并有中优先级的任务D也在运行。采用信号量管理实现A、B、C对互斥资源R的独占访问,说明为什么产生优先级反转。上机验证。 7. 上题中,改用互斥信号量管理来编程,说明为什么解决了优先级反转问题。上机验证。 8. 事件标志组管理应用在什么情况下?给出例子。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1