![]() |
|
||||||||||||||
| | 网站首页 | 文章中心 | 下载中心 | ARM技术交流社区 | 供求信息 | 在线咨询 | 数据手册 | | ||
|
||
|
|||||
| 第2章 实时系统概念(7) | |||||
作者:邵贝贝 文章来源:本站原创 点击数: 更新时间:2006-11-29 ![]() |
|||||
2.22 任务间的通讯(Intertask Communication)
有时很需要任务间的或中断服务与任务间的通讯。这种信息传递称为任务间的通讯。任务间信息的传递有两个途径:通过全程变量或发消息给另一个任务。 用全程变量时,必须保证每个任务或中断服务程序独享该变量。中断服务中保证独享的唯一办法是关中断。如果两个任务共享某变量,各任务实现独享该变量的办法可以是关中断再开中断,或使用信号量(如前面提到的那样)。请注意,任务只能通过全程变量与中断服务程序通讯,而任务并不知道什么时候全程变量被中断服务程序修改了,除非中断程序以信号量方式向任务发信号或者是该任务以查询方式不断周期性地查询变量的值。要避免这种情况,用户可以考虑使用邮箱或消息队列。
图2.16事件标志 2.23 消息邮箱(Message Mail boxes)
通过内核服务可以给任务发送消息。典型的消息邮箱也称作交换消息,是用一个指针型变量,通过内核服务,一个任务或一个中断服务程序可以把一则消息(即一个指针)放到邮箱里去。同样,一个或多个任务可以通过内核服务接收这则消息。发送消息的任务和接收消息的任务约定,该指针指向的内容就是那则消息。 每个邮箱有相应的正在等待消息的任务列表,要得到消息的任务会因为邮箱是空的而被挂起,且被记录到等待消息的任务表中,直到收到消息。一般地说,内核允许用户定义等待超时,等待消息的时间超过了,仍然没有收到该消息,这任务进入就绪态,并返回出错信息,报告等待超时错误。消息放入邮箱后,或者是把消息传给等待消息的任务表中优先级最高的那个任务(基于优先级),或者是将消息传给最先开始等待消息的任务(基于先进先出)。图2.17示意把消息放入邮箱。用一个I字表示邮箱,旁边的小砂漏表示超时计时器,计时器旁边的数字表示定时器设定值,即任务最长可以等多少个时钟节拍(Clock Ticks),关于时钟节拍以后会讲到。 内核一般提供以下邮箱服务: l 邮箱内消息的内容初始化,邮箱里最初可以有,也可以没有消息 l 将消息放入邮箱(POST) l 等待有消息进入邮箱(PEND) l 如果邮箱内有消息,就接受这则消息。如果邮箱里没有消息,则任务并不被挂起(ACCEPT),用返回代码表示调用结果,是收到了消息还是没有收到消息。 消息邮箱也可以当作只取两个值的信号量来用。邮箱里有消息,表示资源可以使用,而空邮箱表示资源已被其它任务占用。
图2.17 消息邮箱 2.24 消息队列(Message Queue)
消息队列用于给任务发消息。消息队列实际上是邮箱阵列。通过内核提供的服务,任务或中断服务子程序可以将一条消息(该消息的指针)放入消息队列。同样,一个或多个任务可以通过内核服务从消息队列中得到消息。发送和接收消息的任务约定,传递的消息实际上是传递的指针指向的内容。通常,先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入消息队列的消息,即先进先出原则(FIFO)。然而μC/OS-Ⅱ也允许使用后进先出方式(LIFO)。 像使用邮箱那样,当一个以上的任务要从消息队列接收消息时,每个消息队列有一张等待消息任务的等待列表(Waiting List)。如果消息队列中没有消息,即消息队列是空,等待消息的任务就被挂起并放入等待消息任务列表中,直到有消息到来。通常,内核允许等待消息的任务定义等待超时的时间。如果限定时间内任务没有收到消息,该任务就进入就绪态并开始运行,同时返回出错代码,指出出现等待超时错误。一旦一则消息放入消息队列,该消息将传给等待消息的任务中优先级最高的那个任务,或是最先进入等待消息任务列表的任务。图2.18示意中断服务子程序如何将消息放入消息队列。图中两个大写的I表示消息队列,“10”表示消息队列最多可以放10条消息,沙漏旁边的0表示任务没有定义超时,将永远等下去,直至消息的到来。 典型地,内核提供的消息队列服务如下: l 消息队列初始化。队列初始化时总是清为空。 l 放一则消息到队列中去(Post) l 等待一则消息的到来(Pend) l 如果队列中有消息则任务可以得到消息,但如果此时队列为空,内核并不将该任务挂起(Accept)。如果有消息,则消息从队列中取走。没有消息则用特别的返回代码通知调用者,队列中没有消息。
图2.18 消息队列 2.25 中断
中断是一种硬件机制,用于通知CPU有个异步事件发生了。中断一旦被识别,CPU保存部分(或全部)现场(Context)即部分或全部寄存器的值,跳转到专门的子程序,称为中断服务子程序(ISR)。中断服务子程序做事件处理,处理完成后,程序回到: l 在前后台系统中,程序回到后台程序 l 对不可剥夺型内核而言,程序回到被中断了的任务 l 对可剥夺型内核而言,让进入就绪态的优先级最高的任务开始运行 中断使得CPU可以在事件发生时才予以处理,而不必让微处理器连续不断地查询(Polling)是否有事件发生。通过两条特殊指令:关中断(Disable interrupt)和开中断(Enable interrupt)可以让微处理器不响应或响应中断。在实时环境中,关中断的时间应尽量的短。关中断影响中断延迟时间(见2.26中断延迟)。关中断时间太长可能会引起中断丢失。微处理器一般允许中断嵌套,也就是说在中断服务期间,微处理器可以识别另一个更重要的中断,并服务于那个更重要的中断,如图2.19所示。 2.26 中断延迟
可能实时内核最重要的指标就是中断关了多长时间。所有实时系统在进入临界区代码段之前都要关中断,执行完临界代码之后再开中断。关中断的时间越长,中断延迟就越长。中断延迟由表达式[2.2]给出。 [2.2] 中断延迟 = 关中断的最长时间 + 开始执行中断服务子程序的第一条指令的时间
图2.19中断嵌套 |
|||||
| 文章录入:armopen 责任编辑:armopen | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| 第4章 任务管理 第3章 内核结构(6) 第3章 内核结构(5) 第3章 内核结构(4) 第3章 内核结构(3) 第3章 内核结构(2) 第3章 内核结构(1) 第2章 实时系统概念(9) 第2章 实时系统概念(8 第2章 实时系统概念(6) |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系我们 | 友情链接 | 版权申明 | 网站公告 | |||
|