第5章消息管理_第1页
第5章消息管理_第2页
第5章消息管理_第3页
第5章消息管理_第4页
第5章消息管理_第5页
已阅读5页,还剩29页未读, 继续免费阅读

下载本文档

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

文档简介

1、嵌入式操作系统嵌入式操作系统 与程序设计与程序设计 第5章 消息管理 5.1 消息邮箱 5.1.1 建立消息邮箱 5.1.2等消息 5.1.3 发消息 5.1.4 删除消息邮箱 5.1.5放弃邮箱等待 5.1.6 无等待请求消息 5.1.7查询邮箱状态 5.1.8 消息邮箱的例子 5.2 消息队列 5.2.1 消息队列数据结构 5.2.2 初始化消息队列 5.2.3 建立消息队列 5.2.4发消息到消息队列 5.2.5等待消息队列中的消息 5.2.6删除消息队列 5.2.7取得消息队列的状态 5.2.8消息队列应用举例 习题 在信号量、互斥信号量和事件标志组的内容 结束后,读者对事件之间如何同

2、步,如何根 据不同需要设计同步程序,应该有了深入的 理解和提高。本章的消息管理中包括消息邮 箱和消息队列两方面的内容,适用于任务之 间的信息交流和同步。从原理上讲,消息管 理也应该属于事件管理的范畴 。 5.1 消息邮箱消息邮箱 消息邮箱是C/OS-II中的另一种通信机制,可以使一个任务或 者中断服务子程序向另一个任务发送一个消息。传递这个消息 的媒体是一个指针型变量,该指针指向一个包含了“消息”的 某种数据结构。 5.1.1 建立消息邮箱建立消息邮箱 在系统初始化之后,并不存在一个消息邮箱。这时操作系统中的事件管理数 据结构事件控制块ECB为全空,所有的事件控制块都在ECB空闲链表中 排队。

3、消息邮箱的建立函数OSMboxCreate将使用一个并配置一个ECB, 使其具备消息邮箱的属性。 表5.2创建信号量函数OSMboxCreate解析 1.检查是否这中断服务程序中创建消息邮箱。 同不允许在中断服务程序中创建信号量一样,操作系统C/OS-II同样不允许 在中断服务程序中创建消息邮箱。 2.检查是否有空闲的事件控制块。 将OSEventFreeList赋值给pevent,如果pevent为空指针,表示没有空闲的 事件控制块,函数返回。 3.在事件控制块空闲链表中取下表头。 因为pevent现在已经是用于邮箱的事件控制块,读者可以直接把他理解为一 个邮箱。那么,需要执行的操作显然就是

4、在事件控制块空闲链表中将他 删除,这时候OSEventFreeList应该指向第二个ECB。 4.对事件控制块赋值 假设信号量值为5,则赋值后的ECB应该如图5-1所示 5.返回ECB地址。 5.1.2等消息等消息 等消息也称为请求消息。含义是当消息存在的时候获取消息,等消息也称为请求消息。含义是当消息存在的时候获取消息, 当消息不存在的时候就放弃对当消息不存在的时候就放弃对CPU的占有,直到有消息的时的占有,直到有消息的时 候才被唤醒。当任务后续的操作离不开消息,这时任务就不该候才被唤醒。当任务后续的操作离不开消息,这时任务就不该 死死占着死死占着CPU不让其他的任务运行,就应该去休息,而当

5、消不让其他的任务运行,就应该去休息,而当消 息到来的时候系统会将消息唤醒回就绪态,任务获得消息后继息到来的时候系统会将消息唤醒回就绪态,任务获得消息后继 续运行。续运行。 表5.3等待消息邮箱函数OSMboxPend解析 开开始始 返返回回 参参数数检检查查是是否否通通 过过 是是 是 否否 p pm ms sg g是是否否 不不为为空空 否 置置位位O OS ST TC CB BS St ta at t中中 等等待待消消息息标标志志 调调用用 O OS S_ _E Ev ve en nt tT Ta as sk kW Wa ai it t终终 止止当当前前任任务务,E EC CB B事事件件

6、 表表中中添添加加当当前前任任务务 执执行行一一次次任任务务调调度度 存存储储超超时时时时间间到到 O OS ST TC CB BD Dl ly y 及及等等待待状状 况况OSTCBStatPend 否 这这里里任任务务 又又一一次次被被调调度度 了了!从从阻阻塞塞态态回回 到到就就绪绪态态又又被被调调 度度 这这里里任任务务被被 剥剥夺夺了了C CP PU U! 进进入入阻阻塞塞态态! 等等待待标标志志 是是否否有有效效 是 如如果果是是资资源源满满足足而而 结结束束等等待待,只只需需要要 设设置置任任务务块块的的E EC CB B 指指针针为为空空 返返回回值值设设置置为为 O OS S_

7、 _T TI IM ME EO OU UT T任任务务仍仍 不不能能使使用用资资源源 是 返返回回值值设设置置为为 O OS S_ _N NO O_ _E ER RR R任任务务可可 使使用用资资源源 p pe er rr r中中填填写写对对 应应的的出出错错信信息息 是是 将将邮邮箱箱中中的的消消息息 地地址址送送p pm ms sg g 是是否否是是等等待待 超超时时 调调用用O OS S_ _E Ev ve en nt tT Ta as sk kR Re em mo ov ve e 清清除除任任务务块块相相关关等等待待标标志志 和和任任务务块块O OS ST TC CB BS St ta

8、 at t 清清除除任任务务块块相相关关等等待待标标志志 返返回回值值设设置置为为 O OS S_ _E ER RR R_ _P PE EN ND D_ _A AB BO OR RT T任任务务仍仍 不不能能使使用用资资源源 否 5.1.3 发消息发消息 当一个任务因为等待消息而被阻塞的时候,只有当其他 任务发出了消息,被阻塞的任务才能被恢复到就绪态, 从而获得消息后继续运行。阻塞的函数在前一节分析过 了,发消息的函数为OSMboxPost,参数是消息类型的 ECB的指针,以及消息的地址。 表5.4发消息函数OSMboxPost解析 开开始始 返返回回 参参数数检检查查 是是否否通通过过 否

9、否否 将将消消息息放放入入邮邮箱箱 是是 是是否否有有任任务务等等待待 该该信信号号量量 是 调调用用 O OS S_ _E Ev ve en nt tT Ta as sk kR Rd dy y 使使等等待待该该消消息息的的 最最高高优优先先级级任任务务 就就绪绪 执执行行一一次次任任务务调调度度 返返回回值值进进行行相相 应应设设置置,提提示示 出出错错 返返回回值值设设置置为为 O OS S_ _N NO O_ _E ER RR R 邮邮箱箱是是否否是是满满的的 否 返返回回值值设设置置为为或或 O OS S_ _N NO O_ _E ER RR R 是 返返回回值值设设置置为为 O OS

10、 S_ _E ER RR R_ _M MB BO OX X _ _F FU UL LL L 5.1.4 删除消息邮箱删除消息邮箱 当消息邮箱不再使用了,就应该尽快归还给系统,即将消息占 用的ECB归还给ECB空闲链表以备它用。消息邮箱的删除函数 是OSMboxDel。删除一个消息也要涉及方方面面,因为可能 有任务正在等待这个邮箱中的消息。 表5.5删除消息邮箱的函数OSMboxDel解析 开开始始 返返回回 参参数数检检查查 是是否否通通过过 若若有有任任务务等等待待该该邮邮箱箱 T Ta as sk ks s_ _w wa ai it ti in ng g= =T TR RU UE E 否否

11、则则为为F FA AL LS SE E 是是 OS_DEL_NO_PEND 其其他他值值 否否 设设置置该该E EC CB B属属性性为为 未未用用 空空闲闲E EC CB B链链表表表表头头 插插入入该该E EC CB B 无无任任务务等等待待 该该邮邮箱箱? ? 根根据据o op pt t值值进进行行 分分支支转转移移 是 否否 OS_DEL_ALWAYS 使使所所有有的的等等待待该该 信信号号量量的的任任务务就就 绪绪 设设置置该该E EC CB B属属性性为为 未未用用 空空闲闲E EC CB B链链表表表表头头 插插入入该该E EC CB B 若若有有任任务务等等待待该该 信信号号量

12、量执执行行一一次次 任任务务调调度度 5.1.5放弃邮箱等待放弃邮箱等待 同放弃对信号量的等待类似,放弃等待邮箱也绝对不会是放弃本任务对邮箱 的等待。放弃等待邮箱函数将放弃的是所有等待某邮箱的任务对该邮箱 的等待或等待某邮箱的优先级最高的任务对邮箱的等待。 表5.6放弃等待邮箱函数OSMboxPendAbort解析 流程如下: 1.检查事件控制块指针是否有效及事件控制块类型是否有效。 2.如果pevent-OSEventGrp为0说明没有任务等待消息邮箱,取消等待的任 务数是0,返回0。 3.否则根据参数opt(选项)进行分支转移,如为 OS_PEND_OPT_BROADCAST,使用whil

13、e语句循环地将等待该邮箱的 每个任务用OS_EventTaskRdy来取消等待并使其就绪(除非任务还被挂 起);如果为其他值则只将最高优先级的任务取消等待并就绪之。 4.返回取消等待信号量的任务数。 5.1.6 无等待请求消息无等待请求消息 在中断服务程序和有些用户任务中,需要无等待的请求消息 邮箱。也就是说,到邮箱中取邮件,如果有邮件就获得邮件, 如果没有并不阻塞自己,而是继续执行其他代码。 OSMboxAccept就是无等待的请求消息邮箱函数,参数是请求 的消息邮箱的ECB指针。该函数的返回值是指向邮箱的指针, 如果没有取得消息,那么就返回空指针。 表5.7无等待地请求消息邮箱函数OSMb

14、oxAccept解析 首先参数检查ECB是否有效,如果有效,将消息邮箱中邮件 的地址OSEventPtr赋值给pmsg,然后清邮箱内容,返回获得的 邮件的地址pmsg。这样,如果邮箱中有邮件,那么返回邮件的 地址,如果没有,返回值就是空地址。 5.1.7查询邮箱状态查询邮箱状态 消息邮箱状态查询函数OSMboxQuery的参数是ECB地址和 一个指向OS_MBOX_DATA类型的地址。ECB地址指向邮箱, OS_MBOX_DATA类型的地址指向返回结果的一个 S_MBOX_DATA类型的对象。 表5.9查询消息邮箱状态函数OSMboxQuery解析 Example5_1: task1任务每任务

15、每1秒记录运行次数,发送到消息邮箱;秒记录运行次数,发送到消息邮箱; task2任务每任务每1秒从消息邮箱接收消息并打印。秒从消息邮箱接收消息并打印。 消息邮箱例程消息邮箱例程 5.1.8 消息邮箱的例子消息邮箱的例子 假设有任务TaskMessageSen和TaskMessageRec, TaskMessageSen在事件片1创 建一个邮箱,如果邮箱中已没有邮件,每秒向邮箱发送一个消息,消息内容为从0 开始的计数值,该计数值每秒加1。任务TaskMessageRec从时间1开始,做的事情 就是查看邮箱,然后把邮件打印出来。 现在我们采用邮件管理完成这两个任务的设计。 5.2 消息队列消息队列

16、 消息邮箱中只能存放一则消息,太少了,能不能像电子邮件一样,管理多 条消息呢? C/OS为实现这一目的,设计了消息队列管理。使用消息队列管理,就允 许使用可以容纳多条信息的大邮箱,按照先进先出(FIFO)的原则,发送和 接收邮件。需要注意的是,这样的邮箱不是操作系统提供的,而是要由用户 任务来提供。操作系统提供的是对其进行管理的程序。另外,邮箱中的内容 仍然是邮件的地址。 消息队列的代码单独存放在os_q.c中 5.2.1 消息队列数据结构消息队列数据结构 1消息队列及其控制块消息队列及其控制块 typedef struct os_q /* 队列控制块队列控制块QCB*/ struct os_

17、q *OSQPtr; /*在空闲在空闲QCB链表中,指示下一个链表中,指示下一个QCB*/ void *OSQStart; /*队列数据的首地址队列数据的首地址*/ void *OSQEnd; /*队列数据的末地址队列数据的末地址*/ void *OSQIn; /*指示下次插入消息的位置指示下次插入消息的位置 */ void *OSQOut; /* 指示下次提取消息的位置指示下次提取消息的位置*/ INT16U OSQSize; /*队列的最大容量队列的最大容量*/ INT16U OSQEntries; /*队列中当前的消息量队列中当前的消息量*/ OS_Q; 2消息控制块实体消息控制块实体

18、OS_Q OSQTblOS_MAX_QS; 3空闲消息队列链表 消息控制块QCB中OSQWaitList用来指示空闲消息控制块QCB链表中的下一个消息 控制块QCB。 5.2.2 初始化消息队列初始化消息队列 消息队列初始化函数在操作系统初始化时被调用,主要用于 初始化消息队列使用的数据结构。消息队列初始化函数的名称 为OS_QInit 表5.13消息队列初始化函数OS_QInit解析 1. 将所有QCB全部清为全0。 2. 使用for循环将除最后一个消息控制块 OSQTblOS_MAX_QS - 1之外的所有消息控制块初始化,构 建了单向的消息队列空闲链表。 3.初始化最后一个QCB,将消息

19、队列空闲链表完善。 5.2.3 建立消息队列建立消息队列 创建消息队列就是将从ECB空闲链表中取下一个事件控制块ECB来,将其用于 消息队列管理。并从QCB空闲链表的表头取下一个消息控制块QCB,将其各种属 性进行设置,用于指示消息的位置以及提取和插入消息的位置。 创建消息队列的函数名称为OSQCreate。 表5.14消息队列创建函数OSQCreate分析 1. 判断是否在中断服务程序中调用本函数,如果是就返回。 2. 取得消息队列的链表首地址送pevent。 3. 判断pevent是否为空指针,如果是则说明是系统已经没有空闲的ECB可供使用, 填写错误信息,返回空指针。 4. 从空闲ECB

20、链表取下表头。 5. 空闲QCB链表首地址送pq。 6. 如果没有有效的空闲QCB链表,恢复空闲ECB链表,返回空ECB指针。 7. 在空闲QCB链表中取一个pq指向的QCB,对其进行初始化。设置OSQStart为消息 指针数组的首地址start。OSQEnd值为&startsize即消息指针数组(消息队列)中 最后一个指针后面的一个地址。OSQIn和OSQOut也设置为start。OSQSize的值为 size。OSQEntries为0表示该队列中还没有消息。 8. 接下来对pevent指向的ECB进行初始化。OSEventType为OS_EVENT_TYPE_Q 表示用于消息队列管理。OS

21、EventCnt在这里没有用,设置为0。OSEventPtr指向 QCB,即设置为pq。调用OS_EventWaitListInit初始化ECB中的事件等待表和事件等 待组。 9.返回ECB指针。 5.2.4发消息到消息队列发消息到消息队列 发消息到消息队列的函数名称为OSQPost。参数是事件控制块ECB的地 址pevent和消息的地址pmsg。 表5.15发消息到消息对列函数OSQPost分析 1.首先进行参数检查,如果参数检查失败则返回。 2. 如果有任务等待消息队列中的消息,那么消息队列现在必然是空的。不 需要将消息存入队列,而直接将消息给在等待的优先级最高的消息,并将 其就绪。执行一

22、次任务调度然后返回。 3. 如果没有任务等待消息队列中的消息,那么就需要将该消息加入消息队 列。如果消息队列是满的,不能容纳更多的消息,返回出错信息。否则, 在消息控制块QCB的OSQIn所指示的消息指针数组位置存入该消息,然后 将OSQIn 指向下一个单元以便下次使用。判断OSQIn是否到超过了表尾, 如果超过了,将其指向队首。然后返回。 5.2.5等待消息队列中的消息等待消息队列中的消息 等待消息队列的消息是消息队列管理中的又一核心函数。如果消息队列中有消息, 那么就取出消息,然后返回;如果没有消息,只有在ECB中标记自己的等待,然后 阻塞。 等待消息队列的函数的名称为OSQPend,参数

23、是ECB的指针、等待超时时间和返 回函数执行信息的指针的perr。函数的返回值是指向消息的指针。 表5.16消息队列等待函数OSQPend分析 1.首先进行参数、ECB类型、中断、调度锁检查,失败则返回。 2. 取得ECB中的QCB指针,查询消息队列中是否有消息。如果有消息,那么请求 直接成功,取得消息队列中OSQOut所指的消息,将OSQOut指向消息队列中的下 一个元素以备下一次的消息提取。如果OSQOut指向了消息队列之外,就指向消息 队列的首地址。将OSQEntries减1表示消息数量减少了一个。然后返回消息的指针。 3. 如果没有消息,那么任务就只有被阻塞。首先在TCB中的STCBS

24、tat中添加消息 队列等待标志,任务延时时间,初始化等待状态,然后调用OS_EventTaskWait 添 加等待标志和取消就绪标志,接着调用OS_Sched执行一次任务调度。 4. 任务恢复运行后,根据TCB中的等待状态OSTCBStatPend决定程序走向。如果 获得了消息,进行一些处理后返回该消息。如果是退出等待,或是等待超时,分别 填写没有取得消息的原因,然后返回空指针。 5.2.6删除消息队列删除消息队列 当消息队列不再使用了,就应该尽快归还给系统,即将消息占用的 ECB归还给ECB空闲链表以备它用,将QCB也归还给空闲QCB链表。 删除消息队列的函数的名称为OSQDel,参数是EC

25、B的指针、删除操作的 选项opt和返回函数执行信息的指针的perr。 其中opt的值为 OS_DEL_NO_PEND 表示只有当没有任务等待该消息队列的时候才允 许删除,opt的值为OS_DEL_ALWAYS 表示无论如何都删除。 如果成功删除,返回空指针;否则返回ECB的指针。 表5.17消息队列删除函数OSQDel解析 1.首先进行参数的检查。 2. 根据选项opt决定程序的分支 3. 如果opt不是这两个值当中的一个,那就是说明是错误的选项,也属于参 数检查失败。因此,标记错误信息perr为OS_ERR_INVALID_OPT后, 直接返回原来ECB指针pevent。 5.2.7取得消息队列的状态取得消息队列的状态 消息队列数据OS_Q_DATA是为返回消息队列信息而提供的,因此用户 程序如果想了解消息队列的信息,要先创建OS_Q_DATA的实例。然后以 消息队列所在ECB地址及该实例的地址为指针为参数调用获取消息队列的 状态函数OSQQuery 表5.19获取消息队列的状态函数OSQQuery解析 5.2.8消息队列应用举例消息队列应用举例 假设有任务假设有任务TaskQSen和和

温馨提示

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

评论

0/150

提交评论