第5章---事件控制块_第1页
第5章---事件控制块_第2页
第5章---事件控制块_第3页
第5章---事件控制块_第4页
第5章---事件控制块_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第5章 事件控制块引言 事件控制块是信号量、消息、事件标志组等各种事件的基础性数据结构。 本章主要内容事件控制块的概念事件控制块数据结构3个事件控制块相关算法4种对事件控制块的操作。5.1 基本概念 在C/OS-II中,有多种方法可以保护任务之间的共享数据和提供任务之间的通信。在前面的章节中,已经讲到了其中的两种:1、利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来关闭中断和打开中断。 2、利用函数OSSchedLock()和OSSchekUnlock()对C/OS-II中的任务调度函数上锁和开锁。3、还有三种用于数据共享和任务通信的方法: 信号量、互斥信号

2、量、消息邮箱、消息队列、事件标志组等。它们是如何进行通信的呢? 如何通信呢?图5.1 任务和中断服务子程序之间的通信过程 超时ECB任务发信号任务等信号超时ECB中断发信号任务等信号A超时ECB中断任务等信号任务任务发信号B超时超时ECB任务等/发信号任务等/发信号C事件的概念:一个任务或者中断服务子程序可以通过事件控制块ECB(Event Control Blocks)来向另外的任务发信号。这里,所有的信号都被看成是事件(Event)。 事件控制块的概念用于实现信号量管理、互斥型信号量管理、消息邮箱管理及消息队列管理等功能函数的基本数据结构叫事件控制块ECB(Event Control Bl

3、ocks)该结构除了包含事件本身的定义外(用于信号量的计数器、互斥信号量的位、指向消息邮箱的指针、指向消息队列的指针数组),还定义了等待该事件的所有任务列表。每个信号量、互斥信号量、消息邮箱及消息队列都应分配到一个事件控制块ECB。四、等待任务列表 每个等待事件发生的任务都被加入到该事件事件控制块中的等待任务列表中,该列表包括.OSEventGrp和.OSEventTbl两个域。通过对该表的判别,可以确定有那些任务在等待事件的发生。.OSEventPtr指针型变量,只有在定义的事件是邮箱或者消息队列时才使用。当所定义的事件是邮箱时,它指向一个消息,而当所定义的事件是消息队列时,它指向一个数据结

4、构,详见有关消息队列的章节。.OSEventTbl和.OSEventGrp是等待任务列表中的两个成员变量,与就绪表中的OSRdyTbl和OSRdyGrp很相似,不同的是前两个表示的是等待某事件的任务,后两个表示的是处于就绪状态的任务。.OSEventCnt 是一个用于信号量的计数器,只有当事件是信号量时才使用。.OSEventType是事件具体类型的描述,详细说明如下: 当事件是信号量时,其值是OS_EVENT_SEM; 当事件是互斥信号量时,其值是OS_EVENT_MUTEX; 当事件是邮箱时,其值是OS_EVENT_TYPE_MBOX; 当事件是消息队列时,其值是OS_EVENT_TYPE

5、_Q。 三、ECB数据结构OS_EVENT .OS_EventPtr .OS_EventCnt .OS_EvenType .OS_EventGrp765432106362616059585756peventOS_EventTbl图5.2 事件控制块(ECB)五、OSEventGrp和.OSEventTbl之间的对应关系例:63/8+1=8例:15 = 0 x0F = 00001111 当一个事件发生后,该事件的等待事件列表中优先级最高的任务,也即在.OSEventTbl中,所有被置1的位中,优先级代码最小的任务得到该事件。.OSEventTbl数组的大小由系统中任务的最低优先级决定,这个值由O

6、S_CFG.H文件中的OS_LOWEST_PRIO常数决定。在系统的定义中,应该尽量减少任务的优先级配置,以减少C/OS-II系统对RAM的占用量。 表6.1 OSMapTblIndexBit Mask (Binary)0000000011000000102000001003000010004000100005001000006010000007100000005.2 将任务置于等待事件的任务列表 一、原理:将相应列表变量和组变量置1用次低的3位作数组元素下标查表OSMapTbl,将组变量相应位置1;用任务优先级的最低3位作数组元素下标查表OSMapTbl,将列表变量相应位置1;二、程序源代码

7、: pevent-OSEventGrp |= OSMapTblprio 3; pevent-OSEventTblprio 3 |= OSMapTblprio & 0 x07; 其中,prio是任务的优先级,pevent是指向事件控制块的指针。三、作用:将任务置于该列表中,以等待事件的发生 当有任务需要等待一个事件的发生的时候,首先就要将任务置于该事件的等待任务列表中,以等待事件的发生。将任务置于等待事件的任务列表的原理是将对应的两个列表变量分别置1,实现方法如下: 5.3 从等待事件的任务列表中使任务脱离等待状态 一、原理: 首先清除任务在.OSEventTbl中的相应位,如果其所在的组中不再

8、有处于等待该事件的任务时(即.OSEventTblprio3为0),将.OSEventGrp中的相应位也清除。二、源代码:从等待任务列表中删除一个任务if (pevent-OSEventTblprio 3 &= OSMapTblprio & 0 x07) = 0) pevent-OSEventGrp &= OSMapTblprio 3;三、作用: 当事件发生后,得到事件的任务就要脱离等待状态,转入就绪。 5.4 在等待事件的任务列表中查找优先级最高的任务 原理:用组变量的值作索引查表OSUnMapTbl,求得值yy = OSUnMapTblpevent-OSEventGrp; 用表变量的值作索

9、引查表OSUnMapTbl,求得值xx = OSUnMapTblpevent-OSEventTbly; 计算最高优先级:prio=y8+x二、范例 例:若.OSEventGrp = 01101000B,则OSUnMapTbl.OSEventGrp= 3,说明最高优先级任务所在的组是3。类似地,若.OSEventTbl3 = 11100100B OSUnMapTbl.OSEventTbl3 = 2,则处于等待状态的任务的最高优先级是38+226。5.5 空闲事件控制块链表 什么是在空闲事件控制块链表? 调用OSInit()时,所有事件控制块被链接成一个单向链表空闲事件控制块链表。空闲事件控制块链

10、表的功能每当建立一个信号量、邮箱或者消息队列时,就从该链表中取出一个空闲事件控制块,并对它进行初始化。当信号量、邮箱和消息队列被删除后,事件控制块也要放回到空闲事件控制块链表中。 事件控制块的数量事件控制块的总数由用户所需要的信号量、邮箱和消息队列的总数决定。该值由OS_CFG.H 中的#define OS_MAX_EVENTS定义。5.5.1 基本概念图5.4 空余事件控制块链表 通用操作对于事件控制块进行的一些通用操作包括:初始化一个事件控制块使一个任务进入就绪态使一个任务进入等待该事件的状态因为等待超时而使一个任务进入就绪态实现函数为了避免代码重复和减短程代码长度,以上操作由4个系统函数

11、实现,它们是:OSEventWaitListInit(),初始化一个事件控制块 ;OSEventTaskRdy(),使一个任务进入就绪态 ;OSEventWait(),使一个任务进入等待某事件发生状态 ;OSEventTO(),由于等待超时而将任务置为就绪态 。5.5.2 对事件控制块的基本操作5.6 初始化一个事件控制块 函数原型void OSEventWaitListInit (OS_EVENT *pevent)功能:函数初始化一个空的等待任务列表,其中没有任何任务。当建立一个信号量、邮箱或者消息队列时,相应的建立函数OSSemInit(),OSMboxCreate(),或者OSQCrea

12、te()通过调用OSEventWaitListInit()对事件控制块中的等待任务列表进行初始化。参数:函数的调用参数只有一个,就是指向需要初始化的事件控制块的指针pevent。程序清单5.6 初始化ECB块的等待任务列表void OSEventWaitListInit (OS_EVENT *pevent) INT8U i; pevent-OSEventGrp = 0 x00; for (i = 0; i OSEventTbli = 0 x00; 四、实现代码5.7 使一个任务进入就绪态 功能该函数从等待任务队列中删除HPT任务(Highest Priority Task),并把该任务置于就绪

13、态。当某个事件发生了,该事件等待任务列表中的最高优先级任务要置于就绪态时,该事件对应的OSSemPost(),OSMboxPost(),OSQPost() 和OSQPostFront()函数调用OSEventTaskRdy()实现该操作。void OSEventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)一、函数原型5.7.1 函数原型一、原理5.7.2 原理与实现发信号、邮箱、队 列等事件任务A任务B在事件等待列表中查找优先级最高的任务删除事件等待列表中优先级最高的任务将消息保存在任务控制块中将这个优先级最高的任务插入到任务就绪表中在TCB

14、中设置与事件类型对应的状态标识算法首先在等待任务列表中查找优先级最高的任务;在等待任务列表中删除优先级最高的任务;停止OSTimeTick()函数对.OSTCBDly域的递减操作,所以OSEventTaskRdy()直接将该域清0;因为该任务不再等待该事件的发生,所以OSEventTaskRdy()函数将其任务控制块中指向事件控制块的指针指向NULL;如果OSEventTaskRdy()是由OSMboxPost()或者OSQPost()调用的,该函数还要将相应的消息传递给HPT,放在它的任务控制块中5.7(10);另外,当OSEventTaskRdy()被调用时,位屏蔽码msk作为参数传递给它

15、。该参数是用于对任务控制块中的位清零的位屏蔽码,和所发生事件的类型相对应5.7(11);最后,根据.OSTCBStat判断该任务是否已处于就绪状态5.7(12)。如果是, 则将HPT插入到C/OS-II的就绪任务列表中5.7(13)。注意,HPT任务得到该事件后不一定进入就绪状态,也许该任务已经由于其它原因挂起了。void OSEventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk) OS_TCB *ptcb; y = OSUnMapTblpevent-OSEventGrp; (1) bity = OSMapTbly; (2) x = OSUn

16、MapTblpevent-OSEventTbly; (3) bitx = OSMapTblx; prio = (INT8U)(y OSEventTbly &= bitx) = 0) pevent-OSEventGrp &= bity; (6) ptcb = OSTCBPrioTblprio; (7) ptcb-OSTCBDly = 0; ptcb-OSTCBEventPtr = (OS_EVENT *)0; (8)(9)#if (OS_Q_EN & (OS_MAX_QS = 2) | OS_MBOX_EN ptcb-OSTCBMsg = msg; (10)#else msg = msg;#en

17、dif ptcb-OSTCBStat &= msk; (11) if (ptcb-OSTCBStat = OS_STAT_RDY) (12) OSRdyGrp |= bity; OSRdyTbly |= bitx; (13) 二、实现代码程序清单5.75.8 使一个任务进入等待某事件发生状态 函数原型void OSEventTaskWait (OS_EVENT *pevent) 功能当某个任务要等待一个事件的发生时,相应事件的OSSemPend()、OSMutexPend() 、OSMboxPend()或OSQPend()函数会调用该函数将当前任务从就绪任务表中删除,并放到相应事件的事件控制块

18、的等待任务表中 。 函数原型5.8.2 原理与实现一、原理开始将事件控制块的指针放到任务控制块中从任务就绪表中删除该任务把该任务放到事件控制块的等待任务列表中去结束程序清单5.8 使一个任务进入等待状态void OSEventTaskWait (OS_EVENT *pevent) OSTCBCur-OSTCBEventPtr = pevent; (1) if (OSRdyTblOSTCBCur-OSTCBY &= OSTCBCur-OSTCBBitX) = 0) (2) OSRdyGrp &= OSTCBCur-OSTCBBitY; pevent-OSEventTblOSTCBCur-OSTCBY |= OSTCBCur-OSTCBBitX; (3) pevent-OSEvent

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论