任务及其通信
任务就是目的明确的半独立程序段。大多数现代实时应用都要求多任务。另外,这些任务的重要等级经常变化。管理这些竞争、实时任务的运行是Nucleus PLUS 的主要目的。
任务状态
每个任务都有五种状态:运行、就绪、挂起、中止、完成。下列列表描述了每个任务的状态:
见表一所示
表一任务状态列表
状态含义
运行任务正在运行
就绪任务就绪,但其他任务正在运行
挂起等待服务请求完成之前任务休眠状态。当响应结束,任务转入等待状态
中止任务被禁止。一旦进入这种状态,任务直到复位之前不能运行。
完成任务完成并返回到初始入口子程序。一旦进入这种状态,任务直到复位前都不能运行
优先级用户分配,范围0~255,用来定义NulceusPLUS 任务的重要性,数字越小优先级越高
任务通信
Nucleus PLUS 为通信目的提供邮箱(mailbox),队列(queues),管道(pipes)。邮箱,
队列,管道是独立的公共设备。任务之间和其他系统设备之间的联系由应用程序确定。这些通信设备之间主要的差别是数据通信的类型。
邮箱
邮箱为传输简单数据提供低消耗方案。每个邮箱可以保持4 个32 位字大小的单一消息。消息以(数)值方式发送和接受。一个发送消息要求拷贝消息到邮箱,一个接受消息要求从邮箱中把消息拷
贝出来。
队列
队列提供了传输多个消息的机制。消息以数值形式发送接受。一个发送消息要求拷贝消息到队列,一个接收消息要求从队列上拷贝消息。消息可以放在对列的前端或队列的后端。
消息尺寸
一列消息包括一个或多个32 位字。固定的和长度可变的消息都支持。消息类型的格式在队列创建的时候定义。长度可变的消息队列需要为队列中的每个消息消耗一个附加的32 位字。另外,接收消息要求在长度可变消息队列指定最大消息尺寸,在固定长度消息队列指定合适的消息尺寸上有同样的要
求。
管道
管道提供了传输多个消息的机制。消息以数值形式发送接受。一个发送消息要求拷贝消息到管道,一个接收消息要求从管道上拷贝消息。消息可以放在管道的前端或队列的后端。
消息尺寸
一列管道消息包括一个或多个32 位字。固定的和长度可变的消息都支持。消息类型的格式在管道创建的时候定义。长度可变的消息管道需要为管道中的每个消息消耗一个附加的32位字。另外,接收消息要求在长度可变消息管道指定最大消息尺寸,在固定长度消息管道指定合适的消息尺寸上有同样的要求。
任务同步
Nucleus PLUS 提供信号量(semaphores),事件集(event groups)和信号(signals)
解决信号同步问题。信号量和事件集都是独立的,公用的设备。任务和其他系统设备的联系由应用程序决定。信号(signals),换一种说法,与指定任务关联。
中断介绍
中断是为外部和内部事件提供立即响应的机制。当中断发生时,处理器挂起当前运行的程序,并且转移控制权到适当的中断服务子程序(ISR)。中断的强制运行是固有的、处理器指定的。
保护
中断对所有的实时内核造成了一个有趣的问题。Nucleus PLUS 也不例外。主要问题从中断服务子程序需要访问Nucleus PLUS 这个事实滋生。表面上看好像不像是一个问题。然而,在被一个ISR同步访问的服务调用期间操作的数据结构需要得到保护。最简单的保护方法就是把服务期间的中断关在外面(关中断)。中断的快速响应是实时系统的基础。因此,关中断来保护数据结构不是个好办法。
Nucleus PLUS 通过把应用程序的ISRs 区分为低级到高级组件来处理保护问题。
低级中断
低级中断服务子程序(LISR)和正常的ISR 一样运行,包括使用当前堆栈。Nucleus PLUS在调用LISR 之前保存上下文,在LISR 返回之后恢复上下文。因此,LISRs 可以用C 来写,也可以被其他的C 子程序调用。然而,只有很少的一部分Nucleus PLUS 服务可以被LISR 访问。如果中断处理需要附加的nucleus PLUS 服务,一个更高级的中断服务处理子程序(HISR)必须被激活。NucleusPLUS 支持多个LISRs 的嵌套。
高级中断
高级中断支持动态创建和删除。每个HISR 由它自己的堆栈空间和控制块。每个的内存由应用程序提供。当然,HISR 必须在LISR 激活之前被创建。一旦HISR 有自己的堆栈和控制块,如果它试图进入一个已经被访问Nucleus PLUS 数据结构时就会被临时封锁。
HISRs 允许访问大多数的Nucleus PLUS 服务,除了自挂起服务(self-suspension)。另外,一旦HISR 不能在Nucleus PLUS 服务时挂起,挂起参数必须总是设置为NU_NO_SUSPEND。
HISR 有三个优先等级。在一个低优先级的HISR 处理期间,如果一个更高优先等级的HISR被激活,低优先级的HISR 以与任务抢先方式相同的方式抢先。相同优先级的HISR 以他们最初激活的顺序运行。所有激活的HISR 在正常任务调度恢复之前运行。
一个激活的计数器维护着每个HISR。这个计数器用于确保每个HISR 为每次激活运行一次。注意一个已经激活的HISR 的每次附加触发都通过连续调用HISR 来处理。