




已阅读5页,还剩24页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
UC/OSII任务间通讯和同步的设计与实现1目录摘要2第一章嵌入式系统简介311研究背景312嵌入式系统的发展状况3第二章UC/OSII任务间通讯与同步的实现521开发环境介绍5211JX44B0教学实验系统的组成5212ADTIDE集成开发环境522任务间通讯与同步的实现步骤6221事件控制块ECB8222初始化一个事件控制块,OSEVENTWAITLISTINIT12223使一个任务进入就绪态,OSEVENTTASKRDY12224使一个任务进入等待某事件发生状态,OSEVENTTASKWAIT15225信号量16227邮箱22结束语27参考文献28致谢29UC/OSII任务间通讯和同步的设计与实现2摘要嵌入式系统的迅速发展,对人类社会诸多领域产生了巨大的影响。在嵌入式的操作系统中,C/OSII以其优秀的性能越来越引起人们的关注。在今天,嵌入式操作系统层出不穷,而且他们以其各自不同的特色广泛分布于通信、航空航天、汽车、医疗、电子消费等不同的领域。因此,开发和架构这种操作系统是符合时代发展的需要。研究嵌入式系统UC/OSII任务间通讯和同步旨在提高通信速度和安全性,研究用几种不同的方法(如用宏、函数、信号量、邮箱、队列)实现UC/OSII任务间通讯和同步,保护任务之间的共享数据具有很好的实用性。考虑到设计的通用性,选择在JJ44B0ARM嵌入式开发环境下,实现对UC/OSII任务间通讯和同步功能的设计,并实现UC/OSII操作系统下使用信号量、邮箱、队列解决任务之间的同步问题,探讨UC/OSII操作系统下任务间通讯的方法。关键字嵌入式系统,C/OSII,通讯和同步,ARMUC/OSII任务间通讯和同步的设计与实现3第一章嵌入式系统简介11研究背景近年来,随着软件资源的成熟和完善,嵌入式系统的发展可谓日新越异,其应用更是涉及金融、航天、电信、网络、信息家电、医疗、工业控制、军事等各个领域,以致一些学者断言嵌入式技术将成为后PC时代的主宰;同时可实现强大功能的RISC、DSP架构芯片不断涌现,我国也令人可喜地推出了龙芯、方舟等32位嵌入式处理器。目前,嵌入式技术已成为通信和消费类产品的共同发展方向。嵌入式系统几乎包括了生活中的所有电器设备,如掌上、移动计算设备、电视机顶盒、手机上网、数字电视、多媒体、汽车、微波炉、数字相机、家庭自动化系统、电梯、空调、安全系统、自动售货机、蜂窝式电话、消费电子设备、工业自动化仪表与医疗仪器等。嵌入式系统自其诞生以来已经经历了几十年的风风雨雨。在经济不景气的现在,许多人相信资讯家电、智慧型手机与PDA等产品将是挽救台湾PC王国的最後一张王牌,而这张王牌的正确名称应该称作嵌入式系统EMBEDDEDSYSTEM,上述所有的产品全都属於嵌入式系统的一项分支。12嵌入式系统的发展状况在展望未来之前,先来大致回顾一下嵌入式系统的历史。1987年到1997年的十年是ASIC风行的十年,而后的十年,也就是1997年到2007年是现场可编程器件的大好时光,制造标准化但应用定制化是这个阶段的明显特征。UC/OSII任务间通讯和同步的设计与实现4图10“许氏循环”和“牧本浪潮”与嵌入式系统核心技术发展规律图10通过我国科学家许居衍院士发表的“许氏循环”以及日本科学家牧本次夫的“牧本浪潮”MAKIMOTOSWAVE总结和预测了嵌入式系统核心技术的发展规律。通过这张图我们不难看出应用微电子技术成果之上的嵌入式系统的演进过程。1977到1987年的十年是嵌入式系统微处理器时代,嵌入式系统通过对微处理器和微控制器软件编程来实现板极的功能,随着时代的发展与科学的进步,软编程已经渐渐不能适应嵌入式系统对于板极功能实现的要求,于是,就出现了硬编程这一概念。当今,嵌入式系统对软硬双可编程提出了需求,软核进入FPGA成为了时代的需要,因此嵌入式系统技术也随之进入了软核(SOFTCORE)时代。就目前而言,FPGA的利用率已经超过了90,应用FPGA的产品也广泛出现在我们的日常生活之中,如PDP/LCD电视,投影仪,DVD等等。而如何实现FPGA的高利用率也就成为了目前嵌入式系统的一个焦点问题。就目前而言,可以从三个方面实现FPGA的高利用率。1工艺上的创新,通过采用7到10层的金属层大大提高了FPGA的利用率和布线成功率。2结构的创新,通过灵活的内部可配置功能模块和在FPGA中不断完善I/O、DSP和存储器等功能提高性能。3EDA设计平台的创新,使得FPGA设计学习的门槛大为降低,更具有可用性。以信息家电为代表的互联网时代嵌入式产品,不仅为嵌入式市场展现了美好前景,注入了新的生命;同时也对嵌入式系统技术,特别是软件技术提出新的挑战。这主要包括支持日趋增长的功能密度、灵活的网络联接、轻便的移动应用和多媒体的信息处理,此外,当然还需对付更加激烈的市场竞争。UC/OSII任务间通讯和同步的设计与实现5第二章UC/OSII任务间通讯与同步的实现21开发环境介绍JX44B0教学实验系统是一套硬件、软件集成的,基于ARM的完整的教学实验系统,系统包含丰富的硬件资源、完善优越的调试手段和详尽的教学实验教程。此系统具有如下的特点1使用方便ADTIDE采用了一个通用的界面,可以非常方便的进行工程管理、编辑、编译、链接和调试,使得我们可以很快地进入到具体的实验中;2接口丰富含多种外设接口LED输出、7段码输出、LCD输出、A/D转换接口、不进电机接口、网络接口、IDE接口、CF卡接口、GPRS模块和GPS模块等;3扩充性好采用模块化设计,便于硬件升级换代,并提高丰富的扩展以便扩充外部接口;4实验丰富本系统专门为嵌入式系统教学进行了定制,精心设计了多个实验,包括嵌入式开发基础实验、基本接口实验、BOOTLOADER及操作系统实验和高级接口实验。211JX44B0教学实验系统的组成1ADTIDE集成开发环境;2ADTEMULATORFORARMJTAG仿真器;3JX44B0系列教学实验箱JX44B01B、JX44B01、JX44B02、JX44B03;4各种连接线、电源适配器以及实验指导书;212ADTIDE集成开发环境ADTIDE是一套应用于嵌入式软件开发的新一代集成开发环境,它提供高效、清晰、可视化的嵌入式软件开发平台,包括一整套完备的面向嵌入式系统的开发和调试工具编辑器、编译器、链接器、工程管理器以及调试器等。ADTIDE运行于UC/OSII任务间通讯和同步的设计与实现6WINDOWNT、98、2000及XP,采用类VISUALSTDIO界面风格,其界面如图30所示。图20ADTIDE集成开发环境界面22任务间通讯与同步的实现步骤在C/OSII中,有多种方法可以保护任务之间的共享数据和提供任务之间的通讯。其中最主要的有两种一是利用宏OS_ENTER_CRITICAL和OS_EXIT_CRITICAL来关闭中断和打开中断。当两个任务或者一个任务和一个中断服务子程序共享某些数据时,可以采用这种方法;二是利用函数OSSCHEDLOCK和OSSCHEKUNLOCK对C/OSII中的任务调度函数上锁和开锁。用这种方法也可以实现数据的共享。这里将介绍另外三种用于数据共享和任务通讯的方法信号量、邮箱和消息队UC/OSII任务间通讯和同步的设计与实现7列。图21介绍了任务和中断服务子程序之间是如何进行通讯的。一个任务或者中断服务子程序可以通过事件控制块ECB(EVENTCONTROLBLOCKS)来向另外的任务发信号。这里,所有的信号都被看成是事件(EVENT)。这也说明为什么上面把用于通讯的数据结构叫做事件控制块。一个任务还可以等待另一个任务或中断服务子程序给它发送信号。这里要注意的是,只有任务可以等待事件发生,中断服务子程序是不能这样做的。对于处于等待状态的任务,还可以给它指定一个最长等待时间,以此来防止因为等待的事件没有发生而无限期地等下去。多个任务可以同时等待同一个事件的发生。在这种情况下,当该事件发生后,所有等待该事件的任务中,优先级最高的任务得到了该事件并进入就绪状态,准备执行。上面讲到的事件,可以是信号量、邮箱或者消息队列等。当事件控制块是一个信号量时,任务可以等待它,也可以给它发送消息。图21事件控制块的使用UC/OSII任务间通讯和同步的设计与实现8221事件控制块ECBC/OSII通过UCOS_IIH中定义的OS_EVENT数据结构来维护一个事件控制块的所有信息程序清单L31,也就是本章开篇讲到的事件控制块ECB。该结构中除了包含了事件本身的定义,如用于信号量的计数器,用于指向邮箱的指针,以及指向消息队列的指针数组等,还定义了等待该事件的所有任务的列表。程序清单L31是该数据结构的定义。程序清单L31ECB数据结构TYPEDEFSTRUCTVOIDOSEVENTPTR/指向消息或者消息队列的指针/INT8UOSEVENTTBLOS_EVENT_TBL_SIZE/等待任务列表/INT16UOSEVENTCNT/计数器当事件是信号量时/INT8UOSEVENTTYPE/时间类型/INT8UOSEVENTGRP/等待任务所在的组/OS_EVENTOSEVENTPTR指针,只有在所定义的事件是邮箱或者消息队列时才使用。当所定义的事件是邮箱时,它指向一个消息,而当所定义的事件是消息队列时,它指向一个数据结构。OSEVENTTBL和OSEVENTGRP很像前面讲到的OSRDYTBL和OSRDYGRP,只不过前两者包含的是等待某事件的任务,而后两者包含的是系统中处于就绪状态的任务。OSEVENTCNT当事件是一个信号量时,OSEVENTCNT是用于信号量的计数器。OSEVENTTYPE定义了事件的具体类型。它可以是信号量(OS_EVENT_SEM)、邮箱(OS_EVENT_TYPE_MBOX)或消息队列(OS_EVENT_TYPE_Q)中的一种。用户要根据该域的具体值来调用相应的系统函数,以保证对其进行的操作的正确性。当一个事件发生后,该事件的等待事件列表中优先级最高的任务,也即在OSEVENTTBL中,所有被置1的位中,优先级代码最小的任务得到该事件。图32UC/OSII任务间通讯和同步的设计与实现9给出了OSEVENTGRP和OSEVENTTBL之间的对应关系。该关系可以描述为当OSEVENTTBL0中的任何一位为1时,OSEVENTGRP中的第0位为1。当OSEVENTTBL1中的任何一位为1时,OSEVENTGRP中的第1位为1。当OSEVENTTBL2中的任何一位为1时,OSEVENTGRP中的第2位为1。当OSEVENTTBL3中的任何一位为1时,OSEVENTGRP中的第3位为1。当OSEVENTTBL4中的任何一位为1时,OSEVENTGRP中的第4位为1。当OSEVENTTBL5中的任何一位为1时,OSEVENTGRP中的第5位为1。当OSEVENTTBL6中的任何一位为1时,OSEVENTGRP中的第6位为1。当OSEVENTTBL7中的任何一位为1时,OSEVENTGRP中的第7位为1。图22事件的等待任务列表下面的代码将一个任务放到事件的等待任务列表中。程序清单L32将一个任务插入到事件的等待任务列表中PEVENTOSEVENTGRP|OSMAPTBLPRIO3PEVENTOSEVENTTBLPRIO3|OSMAPTBLPRIOUC/OSII任务间通讯和同步的设计与实现10其中,PRIO是任务的优先级,PEVENT是指向事件控制块的指针。从程序清单L32可以看出,插入一个任务到等待任务列表中所花的时间是相同的,和表中现有多少个任务无关。从图32中可以看出该算法的原理任务优先级的最低3位决定了该任务在相应的OSEVENTTBL中的位置,紧接着的3位则决定了该任务优先级在OSEVENTTBL中的字节索引。该算法中用到的查找表OSMAPTBL(定义在OS_COREC中)一般在ROM中实现。表31OSMAPTBLINDEXBITMASKBINARY000000001100000010200000100300001000400010000500100000601000000710000000从等待任务列表中删除一个任务的算法则正好相反,如程序清单L33所示。程序清单L33从等待任务列表中删除一个任务IFPEVENTOSEVENTTBLPRIO3该代码清除了任务在OSEVENTTBL中的相应位,并且,如果其所在的组中不再有处于等待该事件的任务时(即OSEVENTTBLPRIO3为0),将OSEVENTGRP中的相应位也清除了。和上面的由任务优先级确定该任务在等待表中的位置的算法类似,从等待任务列表中查找处于等待状态的最高优先级任务的算法,也不是从OSEVENTTBL0开始逐个查询,而是采用了查找另一个表OSUNMAPTBL256。这里,用于索引的8位分别代表对应的8组中有任务处于等待状态,其中的最低位具有最高的优先级。用这个值索引,首先得到最高优先级任务所在的组的位置(07之间UC/OSII任务间通讯和同步的设计与实现11的一个数)。然后利用OSEVENTTBL中对应字节再在OSUNMAPTBL中查找,就可以得到最高优先级任务在组中的位置(也是07之间的一个数)。这样,最终就可以得到处于等待该事件状态的最高优先级任务了。程序清单L34是该算法的具体实现代码。程序清单L34在等待任务列表中查找最高优先级的任务YOSUNMAPTBLPEVENTOSEVENTGRPXOSUNMAPTBLPEVENTOSEVENTTBLYPRIOYOSEVENTGRP0X00FORI0IOSEVENTTBLI0X00223使一个任务进入就绪态,OSEVENTTASKRDY程序清单L36是函数OSEVENTTASKRDY的源代码。当发生了某个事件,该事件等待任务列表中的最高优先级任务要置于就绪态时,该事件对应的OSSEMPOST,OSMBOXPOST,OSQPOST,和OSQPOSTFRONT函数调用OSEVENTTASKRDY实现该UC/OSII任务间通讯和同步的设计与实现13操作。换句话说,该函数从等待任务队列中删除HPT任务(HIGHESTPRIORITYTASK),并把该任务置于就绪态。图34给出了OSEVENTTASKRDY函数最开始的4个动作。该函数首先计算HPT任务在OSEVENTTBL中的字节索引,其结果是一个从0到OS_LOWEST_PRIO/81之间的数,并利用该索引得到该优先级任务在OSEVENTGRP中的位屏蔽码。然后,OSEVENTTASKRDY函数判断HPT任务在OSEVENTTBL中相应位的位置,其结果是一个从0到OS_LOWEST_PRIO/81之间的数,以及相应的位屏蔽码。根据以上结果,OSEVENTTASKRDY函数计算出HPT任务的优先级,然后就可以从等待任务列表中删除该任务了。任务的任务控制块中包含有需要改变的信息。知道了HPT任务的优先级,就可以得到指向该任务的任务控制块的指针、。因为最高优先级任务运行条件已经得到满足,必须停止OSTIMETICK函数对OSTCBDLY域的递减操作,所以OSEVENTTASKRDY直接将该域清澈。因为该任务不再等待该事件的发生,所以OSEVENTTASKRDY函数将其任务控制块中指向事件控制块的指针指向NULL。如果OSEVENTTASKRDY是由OSMBOXPOST或者OSQPOST调用的,该函数还要将相应的消息传递给HPT,放在它的任务控制块中。另外,当OSEVENTTASKRDY被调用时,位屏蔽码MSK作为参数传递给它。该参数是用于对任务控制块中的位清零的位屏蔽码,和所发生事件的类型相对应。最后,根据OSTCBSTAT判断该任务是否已处于就绪状态。如果是,则将HPT插入到C/OSII的就绪任务列表中。注意,HPT任务得到该事件后不一定进入就绪状态,也许该任务已经由于其它原因挂起了。另外,OSEVENTTASKRDY函数要在中断禁止的情况下调用。程序清单L36使一个任务进入就绪状态VOIDOSEVENTTASKRDYOS_EVENTPEVENT,VOIDMSG,INT8UMSKOS_TCBPTCBINT8UXINT8UYINT8UBITXUC/OSII任务间通讯和同步的设计与实现14INT8UBITYINT8UPRIOYOSUNMAPTBLPEVENTOSEVENTGRPBITYOSMAPTBLYXOSUNMAPTBLPEVENTOSEVENTTBLYBITXOSMAPTBLXPRIOINT8UYOSEVENTTBLYPTCBOSTCBPRIOTBLPRIOPTCBOSTCBDLY0PTCBOSTCBEVENTPTROS_EVENT0IFOS_Q_ENELSEMSGMSGENDIFPTCBOSTCBSTATIFPTCBOSTCBSTATOS_STAT_RDYOSRDYGRP|BITYOSRDYTBLY|BITXUC/OSII任务间通讯和同步的设计与实现15图24使一个任务进入就绪状态224使一个任务进入等待某事件发生状态,OSEVENTTASKWAIT程序清单L37是OSEVENTTASKWAIT函数的源代码。当某个任务要等待一个事件的发生时,相应事件的OSSEMPEND,OSMBOXPEND或者OSQPEND函数会调用该函数将当前任务从就绪任务表中删除,并放到相应事件的事件控制块的等待任务表中。程序清单L37使一个任务进入等待状态VOIDOSEVENTTASKWAITOS_EVENTPEVENTOSTCBCUROSTCBEVENTPTRPEVENTIFOSRDYTBLOSTCBCUROSTCBYPEVENTOSEVENTTBLOSTCBCUROSTCBY|OSTCBCUROSTCBBITXPEVENTOSEVENTGRP|OSTCBCUROSTCBBITYUC/OSII任务间通讯和同步的设计与实现16在该函数中,首先将指向事件控制块的指针放到任务的任务控制块中,接着将任务从就绪任务表中删除,并把该任务放到事件控制块的等待任务表中。225信号量C/OSII中的信号量由两部分组成一个是信号量的计数值,它是一个16位的无符号整数(0到65,535之间);另一个是由等待该信号量的任务组成的等待任务表。用户要在OS_CFGH中将OS_SEM_EN开关量常数置成1,这样C/OSII才能支持信号量。在使用一个信号量之前,首先要建立该信号量,也即调用OSSEMCREATE函数(见下一节),对信号量的初始计数值赋值。该初始值为0到65,535之间的一个数。如果信号量是用来表示一个或者多个事件的发生,那么该信号量的初始值应设为0。如果信号量是用于对共享资源的访问,那么该信号量的初始值应设为1(例如,把它当作二值信号量使用)。最后,如果该信号量是用来表示允许任务访问N个相同的资源,那么该初始值显然应该是N,并把该信号量作为一个可计数的信号量使用。C/OSII提供了5个对信号量进行操作的函数。它们是OSSEMCREATE,OSSEMPEND,OSSEMPOST,OSSEMACCEPT和OSSEMQUERY函数。图35说明了任务、中断服务子程序和信号量之间的关系。图中用钥匙或者旗帜的符号来表示信号量如果信号量用于对共享资源的访问,那么信号量就用钥匙符号。符号旁边的数字N代表可用资源数。对于二值信号量,该值就是1;如果信号量用于表示某事件的发生,那么就用旗帜符号。UC/OSII任务间通讯和同步的设计与实现17图25任务、中断服务子程序和信号量之间的关系程序清单L39建立一个信号量OS_EVENTOSSEMCREATEINT16UCNTOS_EVENTPEVENTOS_ENTER_CRITICALPEVENTOSEVENTFREELIST1IFOSEVENTFREELISTOS_EVENT0OSEVENTFREELISTOS_EVENTOSEVENTFREELISTOSEVENTPTROS_EXIT_CRITICALIFPEVENTOS_EVENT0PEVENTOSEVENTTYPEOS_EVENT_TYPE_SEMPEVENTOSEVENTCNTCNTOSEVENTWAITLISTINITPEVENTRETURNPEVENT等待一个信号量,OSSEMPEND程序清单L310是OSSEMPEND函数的源代码。它首先检查指针PEVENT所指UC/OSII任务间通讯和同步的设计与实现18的任务控制块是否是由OSSEMCREATE建立的。如果信号量当前是可用的(信号量的计数值大于0),将信号量的计数值减1,然后函数将“无错”错误代码返回给它的调用函数。显然,如果正在等待信号量,这时的输出正是我们所希望的,也是运行OSSEMPEND函数最快的路径。如果此时信号量无效(计数器的值是0),OSSEMPEND函数要进一步检查它的调用函数是不是中断服务子程序。在正常情况下,中断服务子程序是不会调用OSSEMPEND函数的。这里加入这些代码,只是为了以防万一。当然,在信号量有效的情况下,即使是中断服务子程序调用的OSSEMPEND,函数也会成功返回,不会出任何错误。因为当前任务已经不是就绪态了,所以任务调度函数将下一个最高优先级的任务调入,准备运行。当信号量有效或者等待时间到后,调用OSSEMPEND函数的任务将再一次成为最高优先级任务。这时OSSCHED函数返回。这之后,OSSEMPEND要检查任务控制块中的状态标志,看该任务是否仍处于等待信号量的状态。如果是,说明该任务还没有被OSSEMPOST函数发出的信号量唤醒。事实上,该任务是因为等待超时而由TIMETICK函数把它置为就绪状态的。这种情况下,OSSEMPEND函数调用OSEVENTTO函数将任务从等待任务列表中删除,并返回给它的调用任务一个“超时”的错误代码。如果任务的任务控制块中的OS_STAT_SEM标志位没有置位,就认为调用OSSEMPEND的任务已经得到了该信号量,将指向信号量ECB的指针从该任务的任务控制块中删除,并返回给调用函数一个“无错”的错误代码。程序清单L310等待一个信号量VOIDOSSEMPENDOS_EVENTPEVENT,INT16UTIMEOUT,INT8UERROS_ENTER_CRITICALIFPEVENTOSEVENTTYPEOS_EVENT_TYPE_SEMOS_EXIT_CRITICALERROS_ERR_EVENT_TYPEIFPEVENTOSEVENTCNT0UC/OSII任务间通讯和同步的设计与实现19PEVENTOSEVENTCNTOS_EXIT_CRITICALERROS_NO_ERRELSEIFOSINTNESTING0OS_EXIT_CRITICALERROS_ERR_PEND_ISRELSEOSTCBCUROSTCBSTAT|OS_STAT_SEMOSTCBCUROSTCBDLYTIMEOUTOSEVENTTASKWAITPEVENTOS_EXIT_CRITICALOSSCHEDOS_ENTER_CRITICALIFOSTCBCUROSTCBSTATOS_EXIT_CRITICALERROS_TIMEOUTELSEOSTCBCUROSTCBEVENTPTROS_EVENT0OS_EXIT_CRITICALERROS_NO_ERR发送一个信号量,OSSEMPOST程序清单L311是OSSEMPOST函数的源代码。它首先检查参数指针PEVENT指向的任务控制块是否是OSSEMCREATE函数建立的,接着检查是否有任务在等待该信号量。如果该任务控制块中的OSEVENTGRP域不是0,说明有任务正在等待该信号量。这时,就要调用函数OSEVENTTASKRDY,OSEVENTTASKRDY,把其中的UC/OSII任务间通讯和同步的设计与实现20最高优先级任务从等待任务列表中删除并使它进入就绪状态。然后,调用OSSCHED任务调度函数检查该任务是否是系统中的最高优先级的就绪任务。如果是,这时就要进行任务切换当OSSEMPOST函数是在任务中调用的,准备执行该就绪任务。如果不是,OSSCHED直接返回,调用OSSEMPOST的任务得以继续执行。如果这时没有任务在等待该信号量,该信号量的计数值就简单地加1。上面是由任务调用OSSEMPOST时的情况。当中断服务子程序调用该函数时,不会发生上面的任务切换。如果需要,任务切换要等到中断嵌套的最外层中断服务子程序调用OSINTEXIT函数后才能进行。程序清单L311发出一个信号量INT8UOSSEMPOSTOS_EVENTPEVENTOS_ENTER_CRITICALIFPEVENTOSEVENTTYPEOS_EVENT_TYPE_SEMOS_EXIT_CRITICALRETURNOS_ERR_EVENT_TYPEIFPEVENTOSEVENTGRPOSEVENTTASKRDYPEVENT,VOID0,OS_STAT_SEMOS_EXIT_CRITICALOSSCHEDRETURNOS_NO_ERRELSEIFPEVENTOSEVENTCNTOSEVENTCNTOS_EXIT_CRITICALRETURNOS_NO_ERRELSEOS_EXIT_CRITICALRETURNOS_SEM_OVFUC/OSII任务间通讯和同步的设计与实现21无等待地请求一个信号量,OSSEMACCEPT当一个任务请求一个信号量时,如果该信号量暂时无效,也可以让该任务简单地返回,而不是进入睡眠等待状态。这种情况下的操作是由OSSEMACCEPT函数完成的,其源代码见程序清单L312。该函数在最开始也是检查参数指针PEVENT指向的事件控制块是否是由OSSEMCREATE函数建立的,接着从该信号量的事件控制块中取出当前计数值,并检查该信号量是否有效(计数值是否为非0值)。如果有效,则将信号量的计数值减1,然后将信号量的原有计数值返回给调用函数。调用函数需要对该返回值进行检查。如果该值是0,说明该信号量无效。如果该值大于0,说明该信号量有效,同时该值也暗示着该信号量当前可用的资源数。应该注意的是,这些可用资源中,已经被该调用函数自身占用了一个(该计数值已经被减1)。中断服务子程序要请求信号量时,只能用OSSEMACCEPT而不能用OSSEMPEND,因为中断服务子程序是不允许等待的。程序清单L312无等待地请求一个信号量INT16UOSSEMACCEPTOS_EVENTPEVENTINT16UCNTOS_ENTER_CRITICALIFPEVENTOSEVENTTYPEOS_EVENT_TYPE_SEMOS_EXIT_CRITICALRETURN0CNTPEVENTOSEVENTCNTIFCNT0PEVENTOSEVENTCNTOS_EXIT_CRITICALUC/OSII任务间通讯和同步的设计与实现22RETURNCNT查询一个信号量的当前状态,OSSEMQUERY和其它与信号量有关的函数一样,OSSEMQUERY也是先检查PEVENT指向的事件控制块是否是OSSEMCREATE产生的,然后将等待任务列表和计数值从OS_EVENT结构拷贝到OS_SEM_DATA结构变量中去。程序清单L313查询一个信号量的状态INT8UOSSEMQUERYOS_EVENTPEVENT,OS_SEM_DATAPDATAINT8UIINT8UPSRCINT8UPDESTOS_ENTER_CRITICALIFPEVENTOSEVENTTYPEOS_EVENT_TYPE_SEMOS_EXIT_CRITICALRETURNOS_ERR_EVENT_TYPEPDATAOSEVENTGRPPEVENTOSEVENTGRPPSRCPDESTFORI0IOSCNTPEVENTOSEVENTCNTOS_EXIT_CRITICALRETURNOS_NO_ERRUC/OSII任务间通讯和同步的设计与实现23227邮箱邮箱是C/OSII中另一种通讯机制,它可以使一个任务或者中断服务子程序向另一个任务发送一个指针型的变量。该指针指向一个包含了特定“消息”的数据结构。为了在C/OSII中使用邮箱,必须将OS_CFGH中的OS_MBOX_EN常数置为1。使用邮箱之前,必须先建立该邮箱。该操作可以通过调用OSMBOXCREATE函数来完成(见下节),并且要指定指针的初始值。一般情况下,这个初始值是NULL,但也可以初始化一个邮箱,使其在最开始就包含一条消息。如果使用邮箱的目的是用来通知一个事件的发生(发送一条消息),那么就要初始化该邮箱为NULL,因为在开始时,事件还没有发生。如果用户用邮箱来共享某些资源,那么就要初始化该邮箱为一个非NULL的指针。在这种情况下,邮箱被当成一个二值信号量使用。C/OSII提供了5种对邮箱的操作OSMBOXCREATE,OSMBOXPEND,OSMBOXPOST,OSMBOXACCEPT和OSMBOXQUERY函数。图F36描述了任务、中断服务子程序和邮箱之间的关系,这里用符号“I”表示邮箱。邮箱包含的内容是一个指向一条消息的指针。一个邮箱只能包含一个这样的指针(邮箱为满时),或者一个指向NULL的指针(邮箱为空时)。从图36可以看出,任务或者中断服务子程序可以调用函数OSMBOXPOST,但是只有任务可以调用函数OSMBOXPEND和OSMBOXQUERY。UC/OSII任务间通讯和同步的设计与实现24图26任务、中断服务子程序和邮箱之间的关系建立一个邮箱,OSMBOXCREATE程序清单L314是OSMBOXCREATE函数的源代码,基本上和函数OSSEMCREATE相似。不同之处在于事件控制块的类型被设置成OS_EVENT_TYPE_MBOXL3141,以及使用OSEVENTPTR域来容纳消息指针,而不是使用OSEVENTCNT域L3142。OSMBOXCREATE函数的返回值是一个指向事件控制块的指针L3143。这个指针在调用函数OSMBOXPEND,OSMBOXPOST,OSMBOXACCEPT和OSMBOXQUERY时使用。因此,该指针可以看作是对应邮箱的句柄。值得注意的是,如果系统中已经没有事件控制块可用,函数OSMBOXCREATE将返回一个NULL指针。邮箱一旦建立,是不能被删除的。比如,如果有任务正在等待一个邮箱的信息,这时删除该邮箱,将有可能产生灾难性的后果。程序清单L314建立一个邮箱OS_EVENTOSMBOXCREATEVOIDMSGOS_EVENTPEVENTOS_ENTER_CRITICALPEVENTOSEVENTFREELISTIFOSEVENTFREELISTOS_EVENT0OSEVENTFREELISTOS_EVENTOSEVENTFREELISTOSEVENTPTROS_EXIT_CRITICALIFPEVENTOS_EVENT0PEVENTOSEVENTTYPEOS_EVENT_TYPE_MBOXPEVENTOSEVENTPTRMSGOSEVENTWAITLISTINITPEVENTRETURNPEVENTUC/OSII任务间通讯和同步的设计与实现25等待一个邮箱中的消息,OSMBOXPEND程序清单L315是OSMBOXPEND函数的源代码。同样,它和OSSEMPEND也很相似,因此,在这里只讲述其中的不同之处。OSMBOXPEND首先检查该事件控制块是由OSMBOXCREATE函数建立的。当OSEVENTPTR域是一个非NULL的指针时,说明该邮箱中有可用的消息。这种情况下,OSMBOXPEND函数将该域的值复制到局部变量MSG中,然后将OSEVENTPTR置为NULL。这正是我们所期望的,也是执行OSMBOXPEND函数最快的路径。如果邮箱中没有可用的消息,OSMBOXPEND的调用任务就被挂起,直到邮箱中有了消息或者等待超时。当有其它的任务向该邮箱发送了消息后(或者等待时间超时),这时,该任务再一次成为最高优先级任务,OSSCHED返回。这时,OSMBOXPEND函数要检查是否有消息被放到该任务的任务控制块中。如果有,那么该次函数调用成功,对应的消息被返回到调用函数。程序清单L315等待一个邮箱中的消息VOIDOSMBOXPENDOS_EVENTPEVENT,INT16UTIMEOUT,INT8UERRVOIDMSGOS_ENTER_CRITICALIFPEVENTOSEVENTTYPEOS_EVENT_TYPE_MBOXOS_EXIT_CRITICALERROS_ERR_EVENT_TYPERETURNVOID0MSGPEVENTOSEVENTPTRIFMSGVOID0PEVENTOSEVENTPTRVOID0OS_EXIT_CRITICALERROS_NO_ERRELSEIFOSINTNESTING0OS_EXIT_CRITICALUC/OSII任务间通讯和同步的设计与实现26ERROS_ERR_PEND_ISRELSEOSTCBCUROSTCBSTAT|OS_STAT_MBOXOSTCBCUROSTCBDLYTIMEOUTOSEVENTTASKWAITPEVENTOS_EXIT_CRITICALOSSCHEDOS_ENTER_CRITICALIFMSGOSTCBCUROSTCBMSGVOID0OSTCBCUROSTCBMSGVOID0OSTCBCUROSTCBSTATOS_STAT_RDYOSTCBCUROSTCBEVENTPTROS_EVENT0OS_EXIT_CRITICALERROS_NO_ERRELSEIFOSTCBCUROSTCBSTATOS_EXIT_
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 最GRE填空解题流程介绍
- 纸制品行业人才需求与职业规划考核试卷
- 《马克思主义哲学原理》课件:辩证唯物主义与历史唯物主义
- 油墨耐高温性能研究考核试卷
- 空中交通管制员技能大赛考核试卷
- 《二年级下册小猪的宝藏课件语》
- 船用生活热水供应系统的设计与安装考核试卷
- 矿山职业健康与安全防护考核试卷
- 2023年集装箱行业洞察报告及未来五至十年预测分析报告
- 《急性心肌梗死》课件
- 社工岗前培训课件
- 监工合同范本合同范本模板7篇
- 山东省青岛市、淄博市2025年高三年级第二次适应性检测英语试题及答案(青岛、淄博二模)
- 2024年新疆额敏县事业单位公开招聘村务工作者笔试题带答案
- 殡葬招聘面试题及答案
- 2025年村镇银行招聘笔试题库
- office职场高效办公知到课后答案智慧树章节测试答案2025年春三亚理工职业学院
- 2025年上海市静安区初三二模语文试卷(含答案)
- 水泥预制构件及建材项目可行性研究报告参考范文
- 建设工程质量检测标准化指南•技术示范文本 检测专项检测报告和原始记录模板 -(九)桥梁及地下工程大类
- 林下经济产业项目可行性研究报告
评论
0/150
提交评论