嵌入式实时操作系统ucosII实验2_第1页
嵌入式实时操作系统ucosII实验2_第2页
嵌入式实时操作系统ucosII实验2_第3页
嵌入式实时操作系统ucosII实验2_第4页
嵌入式实时操作系统ucosII实验2_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

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

文档简介

1、嵌入式实时操作系统实验报告任务间通信机制的建立系另寸计算机与电子系专业班级 电子0901班学生姓名高傲指导教师黄向宇提交日期2012 年4月1 日、实验目的二掌握在基于嵌入式实时操作系统卩C/OSI的应用中,任务使用信号量的一般原 理。掌握在基于优先级的可抢占嵌入式实时操作系统的应用中, 出现优先级反转 现象的原理及解决优先级反转的策略 优先级继承的原理。二、实验内容1. 建立并熟悉 Borland C 编译及调试环境。2. 使用课本配套光盘中第五章的例程运行(例 5-4, 例5-5 ,例5-6),观察运 行结果,掌握信号量的基本原理及使用方法, 理解出现优先级反转现象的根本原 因并提出解决方

2、案。3. 试编写一个应用程序,采用计数器型信号量(初值为 2),有3个用户任务 需要此信号量,它们轮流使用此信号量, 在同一时刻只有两个任务能使用信号量, 当其中一个任务获得信号量时向屏幕打印“ TASK N get the signal ”。观察程 序运行结果并记录。4. 试编写一个应用程序实现例 5-7的内容,即用优先级继承的方法解决优先 级反转的问题,观察程序运行结果并记录。5. 在例5-8基础上修改程序增加一个任务 HerTask,它和YouTask 样从邮箱 Str_Box里取消息并打印出来,打印信息中增加任务标识,即由哪个任务打印的; MyTas发送消息改为当Times为5的倍数时

3、才发送,HerTask接收消息采用无等待 方式,如果邮箱为空,则输出“ The mailbox is empty”, 观察程序运行结果并 记录。三、实验原理1. 信号量卩C/OS中的信号量由两部分组成:一个是信号量的计数值,它是一个16位的无符号整数 (0 到65,535之间);另一个是由等待该信号量的任务组成的等 待任务表。用户要在 OS_CFG中将OS_SEM_EN关量常数置成1这样卩C/OSI 才能支持信号量。在使用一个信号量之前,首先要建立该信号量,也即调用OSSemCreate(函数(见下一节),对信号量的初始计数值赋值。该初始值为0到65,535 之间的一个数。如果信号量是用来表示

4、一个或者多个事件的发生, 那么该信号量的初始值 应设为 0。如果信号量是用于对共享资源的访问, 那么该信号量的初始值应设为 1 (例如,把它当作二值信号量使用)。最后,如果该信号量是用来表示允许任务 访问n个相同的资源,那么该初始值显然应该是n,并把该信号量作为一个可计数 的信号量使用。卩C/OSI提供了 5个对信号量进行操作的函数。它们是:OSSemCreate(),OSSemPendQ OSSemPost(, OSSemAccept(和OSSemQuery(函数。图 F6.5 说明 了任务、中断服务子程序和信号量之间的关系。 图中用钥匙或者旗帜的符号来表 示信号量: 如果信号量用于对共享资

5、源的访问, 那么信号量就用钥匙符号。 符号 旁边的数字N代表可用资源数。对于二值信号量,该值就是1;如果信号量用于表 示某事件的发生,那么就用旗帜符号。这时的数字 N代表事件已经发生的次数。 从图F6.5中可以看出OSSemPost(函数可以由任务或者中断服务子程序调用, 而 OSSemPe nd和OSSemQuery(函数只能有任务程序调用。2. 优先级反转在本实验中, 要体现嵌入式实时内核的优先级抢占调度的策略, 并显现由于 共享资源的互斥访问而出现的优先级反转现象。优先级反转发生在有多个任务需要使用共享资源的情况下, 可能会出现高优 先级任务被低优先级任务阻塞, 并等待低优先级任务执行的

6、现象。 高优先级任务 需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务, 这种现象就被称为优先级反转。 两个任务都试图访问共享资源是出现优先级反转 最通常的情况。 为了保证一致性, 这种访问应该是顺序进行的。 如果高优先级任 务首先访问共享资源, 则会保持共享资源访问的合适的任务优先级顺序; 但如果 是低优先级任务首先获得共享资源的访问, 然后高优先级任务请求对共享资源的 访问,则高优先级任务被阻塞,直到低优先级任务完成对共享资源的访问。3. 优先级继承优先级继承的主要思想是:当高优先级任务因申请某共享资源失败被阻 塞时,把当前拥有该资源的、 且优先级较低的任务的优先级提升

7、, 提升的高度等 于这个高优先级任务的优先级。在卩C/OS-II中,在创建管理共享资源的互斥信 号量时,可以指定一个 PIP (优先级继承优先级),之后可以把拥有共享资源的 任务优先级提升到这个高度。具体过程如下:1. 当任务A申请共享资源S时,首先判断是否有别的任务正在占用资源 S, 若无,则任务A获得资源S并继续执行;2. 如果任务 A 申请共享资源 S 时任务 B 正在使用该资源,则任务 A 被挂 起,等待任务 B 释放该资源;同时判断任务 B 的优先级是否低于任务 A 的,若 高于任务A,则维持任务B的优先级不变;3. 如果任务B的优先级低于任务 A的,则提升任务B的优先级到PIP,当

8、任务B释放 资源后,再恢复其原来的优先级。4. 建立一个信号量 , OSSemCreate()程序清单L6.9是OSSemCreate()函数的源代码。首先,它从空闲任务控制 块链表中得到一个事件控制块 L6.9(1) ,并对空闲事件控制链表的指针进行适 当的调整,使它指向下一个空闲的事件控制块 L6.9(2) 。如果这时有任务控制 块可 用 L6.9(3), 就 将 该任务控 制块 的 事件类型 设置 成信 号量OS_EVENT_TYPE_SEML6.9(4)其它的信号量操作函数 OSSem?通过检查该 域来保证所操作的任务控制块类型的正确。例如,这可以防止调用 OSSemPost() 函数

9、对一个用作邮箱的任务控制块进行操作 6.06 节,邮箱)接着,用信号量 的初始值对任务控制块进行初始化 L6.9(5) ,并调用 OSEventWaitListInit() 函数对事件控制任务控制块的等待任务列表进行初始化见 6.01 节,初始化一个任务控制块, OSEventWaitListInit()L6.9(6)因为信号量正在被初始化,所以这时没有任何任务等待该信号量)最后,OSSemCreate(返回给调用函数一个指向 任务 控制 块的 指针) 以后 对信 号量 的所有 操作 ,如 OSSemPend(), OSSemPost(), OSSemAccept()和 OSSemQuery都

10、是通过该指针完成的。因此, 这个指针实际上就是该信号量的句柄)如果系统中没有可用的任务控制块, OSSemCreate(将返回一个NULL指针。值得注意的是,在卩C/OS中,信号量一旦建立就不能删除了 ,因此也就不可能将一个已分配的任务控制块再放回到空闲 ECB链表中。如果有任务正在等待某个信号量,或者某任务的运行依赖于某信号量的出现时, 删除该任务是很危 险的。程序清单L6.9建立一个信号量OS_EVENT *OSSemCreate (INT16U ent)OS_EVENT *peve nt;OS_ENTER_CRITICAL();peve nt = OSEve ntFreeList;(1)

11、if (OSEve ntFreeList != (OS_EVENT *)0) OSEve ntFreeList = (OS_EVENT *)OSEve ntFreeList->OSEve ntPtr;OS_EXIT_CRITICAL();(2)if (peve nt != (OS_EVENT *)0) (3)peve nt->OSEve ntType = OS_EVENT_TYPE_SEM;(4)peve nt->OSEve ntCnt = ent;(5)OSEve ntWaitListl nit(peve nt);retur n (peve nt);(6)(7)5. 邮箱邮

12、箱是卩C/OS中另一种通讯机制,它可以使一个任务或者中断服务子程序 向另一个任务发送一个指针型的变量。 该指针指向一个包含了特定“消息”的数 据结构。为了在卩C/OS中使用邮箱,必须将OS_CFG.中的0SMB0XJE1数置为 1。使用邮箱之前,必须先建立该邮箱。该操作可以通过调用OSMboxCreate()函数来完成(见下节),并且要指定指针的初始值。一般情况下,这个初始值是 NULL但也可以初始化一个邮箱,使其在最开始就包含一条消息。如果使用邮箱 的目的是用来通知一个事件的发生 (发送一条消息),那么就要初始化该邮箱为 NULL因为在开始时,事件还没有发生。如果用户用邮箱来共享某些资源,那

13、么 就要初始化该邮箱为一个非NUL的指针。在这种情况下,邮箱被当成一个二值信 号量使用。卩 C/OS 提供了 5种对邮箱的操作:OSMboxCreate(), OSMboxPend() OSMboxPost(), OSMboxAccept()和OSMboxQuery(函数。图 F6.6 描述了任务、中 断服务子程序和邮箱之间的关系,这里用符号“I”表示邮箱。由晞包含的内容是一个指向一条消息的指针。一个邮箱只能包含一个这样的指针(邮箱为满时), 或者一个指向NULL勺指针(邮箱为空时)。从图F6.6可以看出,任务或者中断v7 OSMtoxAccept)MessageFigure Relation

14、ship between tasks, SRs and a message mailbox,服务子程序可以调用函数OSMboxPost(),但是只有任务可以调用函数OSMboxPe nd和 OSMboxQuery(。建立一个邮箱,OSMboxCreate()程序清单L6.14是OSMboxCreate()函数的源代码, 基本上和函数 OSSemCreate()相似。不同之处在于事件控制块的类型被设置成 OS_EVENT_TYPE_MBOXL6.14(1),以及使 用.OSEventPtr域来容纳消息指针,而不是使用.OSEventCnt域L6.14(2)。OSMboxCreate()函数的返回

15、值是一个指向事件控制块的指针L6.14(3)。这个指针在调用函数 OSMboxPend(), OSMboxPost(),OSMboxAccept()和 OSMboxQuery()时使用。因此, 该指针可以看作是对应邮箱的句柄。值得注意的是,如果系统中已经没有事件控制块可用,函 数OSMboxCreate()将返回一个 NULL指针。邮箱一旦建立,是不能被删除的。比如,如果有任务正在等待一个邮箱的信息,这时删除该邮箱,将有可能产生灾难性的后果。程序清单L6.14建立一个邮箱OS_EVENT *OSMboxCreate (void *msg)OS_EVENT *peve nt;OS_ENTER_C

16、RITICAL();peve nt = OSEve ntFreeList;if (OSEve ntFreeList != (OS_EVENT *)0) OSEve ntFreeList = (OS_EVENT *)OSEve ntFreeList->OSEve ntPtr;OS_EXIT_CRITICAL();if (peve nt != (OS_EVENT *)0) peve nt->OSEve ntType = OS_EVENT_TYPE_MBOX;(1)peve nt->OSEve ntPtr = msg;(2)OSEve ntWaitListl nit(peve nt

17、);return (peve nt);(3)等待一个邮箱中的消息,OSMboxPe nd()程序清单L6.15 是OSMboxPend(函数的源代码。同样,它和 OSSemPend() 也很相似,因此,在这里只讲述其中的不同之处。OSMboxPend首先检查该事件 控制块是由OSMboxCreate()函数建立的L6.15(1)。当.OSEventPtr域是一个非 NULL的指针时,说明该邮 箱中有可用的消息L6.15(2)。这种情况 下, OSMboxPend(函数将该域的值复制到局部变量 msg中,然后将.OSEventPtr置为 NULLL6.15(3)。这正是我们所期望的,也是执行 O

18、SMboxPend(函数最快的路 径。如果此时邮箱中没有消息是可用的( .OSEventPtr域是NULL指针), OSMboxPend(函数检查它的 调用者是 否是中断服务子 程序L6.15。象 OSSemPend函数一样,不能在中断服务子程序中调用 OSMboxPend()因为中断服务子程序是不能等待的。这里的代码同样是为了以防万一。但是,如果邮箱中有可用的消息,即使从中断服务子程序中调用OSMboxPe nd(函数,也一样是成功的如果邮箱中没有可用的消息,OSMboxPe nd(的调用任务就被挂起,直到邮箱 中有了消息或者等待超时L6.15(5)。当有其它的任务向该邮箱发送了消息后(或者

19、等待时间超时),这时,该任务再一次成为最高优先级任务,OSSched()返回。这时,OSMboxPend(函数要检查是否有消息被放到该任务的任务控制块中 L6.15 (6)。如果有,那么该次函数调用成功,对应的消息被返回到调用函数。程序清单L6.15等待一个邮箱中的消息void *OSMboxPe nd (OS_EVENT *peve nt, INT16U timeout, INT8U *err)void *msg;OS_ENTER_CRITICAL();if (peve nt->OSEve ntType != OS_EVENT_TYPE_MBOX) (1)OS_EXIT_CRITICA

20、L();*err = OS_ERR_EVENT_TYPE;return (void *)0);msg = peve nt->OSEve ntPtr;if (msg != (void *)0) (2)peve nt->OSEve ntPtr = (void *)0;(3)OS_EXIT_CRITICAL();*err = OS_NO_ERR; else if (OSI ntNest ing > 0) (4)OS_EXIT_CRITICAL();*err = OS_ERR_PEND_ISR; else OSTCBCur->OSTCBStat |= OS_STAT_MBOX;

21、(5)OSTCBCur->OSTCBDIy = timeout;OSEve ntTaskWait(peve nt);OS_EXIT_CRITICAL();OSSched();OS_ENTER_CRITICAL();if (msg = OSTCBCur->OSTCBMsg) != (void *)0) OSTCBCur->OSTCBMsg = (void *)0;OSTCBCur->OSTCBStat = OS_STAT_RDY;OSTCBCur->OSTCBEve ntPtr = (OS_EVENT *)0;OS_EXIT_CRITICAL();*err= OS_

22、NO_ERR;(8)(9)(10)(12) else if (OSTCBCur->OSTCBStat & OS_STAT_MBOX) OSEve ntTO(peve nt);OS_EXIT_CRITICAL();msg= (void *)0;*err= OS_TIMEOUT; else msg= peve nt->OSEve ntPtr;peve nt->OSEve ntPtr = (void *)0;(11)OSTCBCur->OSTCBEve ntPtr = (OS_EVENT *)0;OS_EXIT_CRITICAL();*err= OS_NO_ERR;r

23、eturn (msg);无等待地从邮箱中得到一个消息,OSMboxAccept()应用程序也可以以无等待的方式从邮箱中得到消息。这可以通过程序清单L6.17中的OSMboxAccept()函数来实现。OSMboxAccept()函数开始也是检查事件 控制块是否是由OSMboxCreate()函数建立的L6.17(1)。接着,它得到邮箱中 的当前内容L6.17(2),并判断是否有消息是可用的L6.17(3)。如果邮箱中有 消息,就把邮箱清空L6.17,而邮箱中原来指向消息的指针被返回给OSMboxAccept()的调用函数L6.17(5)。OSMboxAccept()函数的调用函数必须检查该返回

24、值是否为NULL如果该值是NULL说明邮箱是空的,没有可用的消息。 如果该值是非NULLS,说明邮箱中有消息可用,而且该调用函数已经得到了该消息。中断服务子程序在试图得到一个消息时,应该使用OSMboxAccept()函数,而不能使用OSMboxPend(函数。OSMboxAccept()函数的另一个用途是,用户可以用它来清空一个邮箱中现有的内 容。程序清单L6.17无等待地从邮箱中得到消息void *OSMboxAccept (OS_EVENT *peve nt)void *msg;OS_ENTER_CRITICAL();if (peve nt->OSEve ntType != OS_

25、EVENT_TYPE_MBOX) (1)OS_EXIT_CRITICAL();return (void *)0);msg = peve nt->OSEve ntPtr;(2)if (msg != (void *)0) (3)peve nt->OSEve ntPtr = (void *)0;(4)OS_EXIT_CRITICAL();return (msg);(5)四、实验步骤1. 准备实验环境先在C盘上建一个名称为 bc31的目录,然后到互联网上下载一个 Borland C+3.1并安装到目录bc31中(因为书中的代码是用Borland C+3.1编译的),接着 再把实验程序文件夹

26、Software复制到C盘上。例 4-4Bc31TEST.exe, 观察运行2. 打开实验例程1) 运行结果;运行结果如下:例题4-4运行结果:例题4-5运行结果:例题4-6运行结果:'/Task running llerTask running VouTask running VouTask running VouTask running HyTask Pend_Semp VouTask running HyTnsk running VouTask running '/uiTdsk runni no Voulask running HerTask running VouTas

27、k running VouTask running MyTask Pend_Semp NyTask running VauTcJsk running VouTask running HRrT:isl< runnins VouTask running VouTesk runnins HyTask Pend_Semp HyTask running VoljiT曰wk running2)分析整个实验文件目录结构及实验参考程序实验参考程序分析a. 例题4-4:ucos-ll进行初始化和配置后,由于MyTas任务的优先级高,贝U 先运行MyTask,MyTas是对信号量进行操作的一个任务,先向共享

28、资源 Fun_Semp 请求信号量,显示字符MyTasK在调用一次Fun函数,再发送信号量给Fun_Semp 而后优先级低的YouTasI执行,也是先向共享资源Fun_Sem请求信号量,显示字 符YouTasK在调用一次Fun函数,再发送信号量给 Fun_Semp这样让MyTas和 YouTasK能交替共享资源Fun_Semp由于MyTas延时只有1s,所以YouTasI执行 一次,MyTas执行2次。b. 例题4-5: ucos-ll进行初始化和配置后,先执行优先级高的MyTasK先进行信号量的请求,但由于YouTasK未对信号量进行释放,所以不显示 MyTas而显 示YouTask,当Yo

29、uTasK行6次后,释放信号量,此时MyTasK向共享资源请求Fun_Sem请求信号量成功,显示MyTask,并调用一次Fun函数,而后在运行优先级 低的 YouTask。c. 例题4-6 : ucos-II进行初始化和配置后,任务MyTas和HerTask都要使用 一个共享资源Semp而用于保护该资源的信号量在同一时间只能有一个任务以独 占的方式对该资源进行访问,任务 HerTask正在运行,且在t1时刻获得信号量并 开始访问共享资源Semp在此过程中,任务YouTask等待的事件也来了,由于任务 YouTask的优先级高于HerTask,所以任务YouTasI剥夺了任务HerTask的CP使用权,任务HerTask只好等待,这样任务MyTasI只有当任务YouTask运行结束,并使 任务HerTask继续运行且释放了信号量的时刻,才能获得信号量而得以重新运行。出现优先级反转现象的原因:是因为一个优先级别较低的任务在获得了信号 量使用共享资源期间,被较高优先级的任务打断而不能释放信号量,从而使正在等待这个信号量的更高级别的任务因得不到信号量而被迫处于等待状态,这个等待期间,就让优先级别低于它而高于占据信号量的任务的任务先运行了。解决优先级反转现象:使获得信号量的任务的优先级别在使

温馨提示

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

评论

0/150

提交评论