现在的位置: 首页 > 综合 > 正文

isos系统工作笔记5

2017年12月21日 ⁄ 综合 ⁄ 共 7123字 ⁄ 字号 评论关闭

3 基本概念

31 对象(Objects

Quantum使用后端对象数据库以实现对所有系统对象如任务、共享、内存、信号量等,大部分QuantumAPIs都有类似的用法,大部分系统对象的API集有以下格式:

1New – 创建一个新的对象实例

2Delete – 删除一个对象已存在的实例

3Open – 获取一个已存在对象的处理句柄

4Close – 终止一个给定的句柄

5Object – 指定的API回调

所有的对象由系统命名范围的名称指定,对象名具有传统的UNIX文件系统树状结构。对象的类型起源于基本类型,可以使用任何其起源于的类型打开打象名,比如,Message Pool类型起源于Message Interface类型,所以一个Message Pool的对象名可以由Pool打开以获得一个Pool的句柄,或由Message Interface打开以获得Interface句柄,下图所说这种关系:

调用的API如下所示:

可以看到,两次打开操作都基于相同的对象,然而,这两次调用都返回了不同的对象,第一个返回了Pool句柄,可用于执行Pool指定的相关操作,第二个返加了message interface可用于申请或释放消息。

这意味着在Quantum的系统软体服务层是没有办法显示地找到大部分API的,Pool消息、任务交互消息和中断处理都使用interface对象类型消息,后者可以产生大部分的系统对象类型。

对象的处理可以使用类型指定的API或通用的属性机制,当建立一个新的对象或某些指定类型时通常使用属性机制。如下所示为创建一个新的全局的Pool对象:

Pool对象将接受Pool对象指定的属性及Pool所起源的其它任何对象类型的属性,比如,Pool对象同时也提供所有Interface对象类型的属性。

上例中,对象使用了绝对名称“/pool/magic”,同时也可以使用相对路径名,比如有一个任务名为alpha(全名为“/task/alpha”),使用以下代码:

则将建立名为“/task/alpha/private”的对象。

32 任务(Task

Quantum系统服务API定义了应用的基本结构,建立了在一个完整系统中应用代码与软/硬件交互的方式。

Quantum基本的执行单元是任务。

Quantum的架构里面并没有传统的进程与线程之分,取而代之以一个单独的对象类型以实现两者,这有效地降低了API的数量以及到别的平台移植的效率,从而有利用任务处理的优化以获得更好的性能。

321 任务特性

Quantum任务是轻量级执行体,类似于很多OS的用户模式的线程,根据主机的实现,Quantum的任务可运行于内存保户模式或共享内存模式。

任务有以下基本的操作:

1.创建一新的任务对象

2.开始/停止任务对象

3.配置/删除任务对象

系统大部分任务在系统启动(start-up)时自动建立,如果动态创建任务,应用程序只需正常调用任务API即可(如多线程设计)。

322 任务属性(Properties

不同的操作系统支持不同的任务属性,但有些是一定需要的:

1Main进入点

任务的Main进入点是任务第一次启动所调用的函数,属性“main”用于指定该程序,如下所示为传统UNIXC编程风格:

返回值kASEOK表示任务成功完成,其它任何返回值对应于不同的出错条件,任务退出将被系统记录用做症断目的。

进入点必须在源代码中以如下宏进行声明:

通过以下API调用,即可创建一任务实例:

2.任务参数表

      参数属性用于在首次启动时向任务传递一些参数,比如:

     

该参数表将通过argcargvbunmain函数传递参数,在该例中,argv将包括以下两参数:

3.栈空间

      任务的栈空间大小可以通过任务的“stack”属性指定,比如:

如果栈属性没有指定,将使用系统自定义的缺省值,对大多数的平台而言,典型的缺省值为8K

4.任务服务级别

      任务所占用的CPU时间由任务的service属性决定。

  Service的级别由系统架构建立的/taskqos对象目录中的对象名所指定,任务服务级别属性是平台相关的,但不同的操作系统所用的级别大体上相关的,给定的典型级别取决于任务的通用类别。

      为所有的平台定义以下服务级别:

      Adefault – 缺省级别

      Bmaxwait – 提供处理器所许可的最大反应时间

      Cminwait – 提供最小的反应时间

      Dmaxcpu – 提供最大占用处理器的时间

      Emincpu – 占用处理器最少时间

      同时提供以下使用类别的服务级别:

      Awhatever – 通用型应用

      Bcontrol – 控制及管理应用(如SNMP

      Cdata – 通用数据传输(如FTPWEB流)

      Dvideo – 视频流

      Evoice – 音频流

      在本地(native)模型中,服务级别对象有一个枚举型的优先级属性priority1为最小值,比较而言,较大的值具有优先调度权),在其它主机模式中,可以有更复杂的调度参数或不同的优先类型。

           比如,以下代码定义了一个新的data用户类别的服务级别:

33 消息及接口

消息以信息块方式通过接口在任务间传递,通常消息传递的目的是传送数据或请求执行函数。每个任务都具有主/从两种消息接口。

331 消息使用

消息可以同步或异步进行交换,与同步交换比较而言,单向的异步交换更为有效,常用于数据传输,但只能用于消息的发起方无需清楚了解消息内容的情况(比如,流控制)。消息可能携带网络数据包、控制消息或请求执行某些动作。

下图说明Quantum不同任务间所使用的异步消息传输:

重要的是,在这三个接口间,无论是对象名还是使用的方式,各任务间都没有明显的区别,交换消息的基本操作是独立于消息接口类型的,任务通过在其主接口等待从而异步地接收发送给他们的消息。

同步的消息交换是同步的,常用于控制操作,下图更完整地说明同步消息交换的顺序:

在发送完同步消息后,任务将在其从接口等待发送给它们的响应,因此,该接口只能有一个消息。

很多BUN设备使用ATMOSCYAN代替消息,所以必须使用Quantum消息提供CYAN抽象。

332 消息结构

消息用来将数据净荷转化为两个重要的数据区,对一个给定消息类型的消息,这些大小不定的区域是:

1.固定区域 应用于每一种消息类型实例

2.动态区域 大小不等,应用于不同的类型的消息实例,一旦指定消息,其大小将不可改变

下图说明消息的结构:

消息变量部分可在头尾间扩展直到预先定义的最大值,为了使用不同的消息传送机制,没有定义保存这些数据的消息结构,比如,数据可能分布于不同内存区的不同地方,或者储存于当前任务不可仿问的内存区域(但提供当前任务可仿问的函数将消息内容储存于连续的内存区域,同样地也提供执行消息数据读写操作的API)。

消息体包含一类型码以表明其用途及内容,类型码由应用程序分配,而不是由Quantum分配,消息内容的格式取决于其消息码。

333 消息管理

所有的消息都从消息接口获得,Quantum提供了一个消息接口类型,称之为Pool,即为此目的。

新消息通过在Pool消息接口等待进行分配,并将该消息发向源消息接口进行释放。所有的消息都包含一个由Pool设置的域以标明它们的源消息接口。

Pool由一些具有相同类型的消息创建,如以下Pool属性所示:

1Prefix – 消息数据的最大前缀大小

2Size – 消息数据的最大大小

3Extramsg – 消息数据固定部分的大小

Pool中新收的消息有一个长度为0的可变长的消息数据区,在其前后可以分别加上PrefixSize字节的数据。

函数as_MessageAlloc()、as_MessageAllocData()及as_MessageAllocControl()使用了三个不同的Pool,相对应地分别返回一般性的消息、适合于数据传递的消息及适合于控制目的的消息。一旦某消息不再需要的话,可以使用函数as_MessageFree()将其返回到其主消息指口中。

特别地,当收到一个消息,如果需要回复的话,可以使用该消息以携带回复信息发送到回复接口,这样对接收方来讲,并不需要重新分配或释放消息,如果收到一个消息既不回复到其回复接口也不向其它地方传递则通常都要释放,除非它想保存以重复使用。

334 消息对列

Quantum提供消息对列以保存挂起的消息,因此,消息可以进队列以便处理器稍后处理或给任务重新使用。

消息对列是本地数据结构,可用于提供简单的消息链表,除仅由本地任务所使用外,队列与接口很类似,它们都非常快并可能使用静态分配的数据而不是动态地储存。

在下列情况中需要使用消息对列:

1.消息只有一个任务使用时

2.需要比接口更快的处理性能时

3.静态储存比动态分配更好时

对列与接口互相作用,允许从一个接口中原子地收发对列内容,如下节接口与消息指口所示。

消息对列提供的基本功能是as_QueueInitialise()与as_QueueFinalise()以初始化一对列结构或丰应地终止一消息结构。

为了向一对列中增加一消息,可以使用接口as_QueueAddHead()将消息增加到已存对列的开始处,as_QueueAddTail()用于将消息增加于对列的结尾。

从一对列中返回消息,使用接口as_QueueHead从已存对列的开始处返回消息,而as_QueueTail从对列的结尾返回消息。

为了从对列中删除消息,使用接口as_QueueRemoveHead从对列的开始删除一消息,而as_QueueRemoveNext从对列的指定位置删除消息。

使用函数as_size_t as_QueueLength()可发现对列消息的长度。

335 接口与消息接口

接口是用户可定义的结构,由以下两部分构成:

1.代表消息使用的通道句柄

2Put – 使用该函数向沿着消息通道的最初目的转发消息

类似于Quantum的其它数据结构,接口由对象所表示,然而,接口通常作为消息接口的基本类型使用。

消息接口提供的基本功能如下所示:

1Put – 向一接口发送一消息

2Get – 从一接口以非阻塞(non-blocking)的方式取得消息

3Wait – 以阻塞方式在接口上等待数据包的到达

所有的消息接口都接受这些基本的操作,通过格式化的消息回复及同步的发送/等待调用,AS API提供了API扩展的框架,但所有的这些操作并须基于以上三种基本的函数。

消息接口的对象类型是从接口对象类型获取。

消息接口可能代表系统基它任务的可供分配的空闲消息Pool,或者是在Quantum下实现传统中断处理的中断对象。当所有的消息接口以相同的API方式响应时,应用程序所使用的方式则是习惯的问题,很大程度上由接口名所引起。

任务通常是执行消息的循环,从别的任务或硬件收到请求后执行相应的响应,以下代码的结构对ATMOS编程者来说是熟悉的。

336 内存

Quantum支持保存及虑拟内存配置,以限制不同任务间内存的使用。

每一个根任务都有一个私有内存资源,任何其创建的子任务可以继承接入父任务的内存空间,以及任务父任务拥有的系纺对象句柄(如信号量)。

下图说明Quantam下运行的典型的任务集合间内存使用的方式:

任何任务所申请的内存空间都可由其本身及其所创建的子任务所使用,但系统别的任务是不可使用的,因此:

1.任务alpha所使用的内存是其私有的

2.任务beta所申请的内存可由其所有子任务使用

3.任务beta1申请的内存不能由alphabeta使用

可以看到,规则是你申请的内存只能由你自已或子任务所使用。

可以通过AS内存API创建及使用共享内存,共享内存区是由名为“/memory”的系统文件区所标明,AS API包含一些函数用于将任务所使用的地址映射到这些区域,对于本地申请的空间,任何一任务可以使用的共享区都可由其子任务使用。

34 任务同步

Quantum提供两种任务同步的方式,分别是信号量及调度控制。

341 信号量

Quantum提供信号量以便任务间进行同步,一个信号量有一个整形的“control”属性由postas_SemaphorePost)、waitas_SemaphoreWait)、tryas_SemaphoreTry)进行操作。

Post操作逐一地增加control值,waittry尝试对control进行减一的操作,如果control值为0,则try会失败并返回错误代码,而wait将挂起当前的任务直到另一个任务使用post操作将该control变为正值。

例如,下面提供一个如何使用信号量的例子,其要求是函数work()的运行不能超过N次,N是使用者的个数。

342 调度控制

Quantum提供as_TaskSychnronize()以及as_TaskDesynchronize()这两个函数以确保在访问一区域时可以独占CPU资源,这可应用于Quantum所支持的驱动及应用(对于其它独立于Quantum系统的代码如主机操作系统或高优先级的中断处理则可能不一样)。

由于这种排它性阻止了Quantum所有的其它所有操作,因此会增加系统的时延,使用信号量会是更好的方法。然而,在中断文境中执行的中断处理可能是从其它较旧的平台留下来的(在这种情况下,不能使用信号量wait),因此会需要这些函数,同时,这些函数也仅使用在这些情况,也许将来会丢弃它们。

35 中断

Quantum不允许使用一些传统的在ATMOS或其它系统(非LS仿真层)使用的中断处理函数,事实上,并没有为低层硬件中断提供应用API

Quantum里面,中断服务请求由消息系统处理,并与指定的中断消息接口连结。

向中断接口发送第一个消息以开启中断源,当中断发生后,回复消息向源发送者返回,如果该消息是所等待的唯一的消息,则关闭中断。

下图说明任务与中断对象间交互进行的中断处理:

中断对象是非常简单的,它们并不知道与它们进行交换的消息的格式与内容,有没有收到消息对于开启或关闭中断或表明中断是否被激发是足够的。

下图说明了简单的中断任务处理的实现:

然而,请注意,该任务仅使用了一个消息,这意味着硬件中断将被频繁地开启与关闭,这种策略可能会导致损失某些设备工作量的,一种更为有效的方法是,保存一个小的中断消息对列,尽管这对于在中断重启前必须完成某些工作的场合并不合适。

为一给定的中断源仔细选择消息代码,单任务即可外理多个中断源并处理从别的任务收到的消息。

中断对象保存在“/interrupt”全局对象名下,中断源的名称及逻辑名称由BSP的整合者分配,例如,硬件平台提供的API可用于创建名为“/interrupt/phy”的中断,它映射到特定的GPIO管脚。

36 对象数据库

Quantum提供一个系统对象库,以支持安全动态实时的输入,并使用单个或集合体实现构建新的对象类型。

对于Quantum的很多系统对象,目前其数据库大都使用后端系统,比如任务或信号量。这些数据库同时支持对对象的用户进行跟踪,极大的简化了嵌入式系统中动态对象的创建及删除的问题(注意,目前这些功能仅在Quantum内部使用)。

361 何谓之Quantum对象

Quantum对象是任务具有以下特性的数据块:

1.基于CAPI,使用对象指定的handle做为参数

2.一通用的基于属性的系统接入,便于获取无性能要求的重要的配置及状态信息

3.一潜在的多任务共享的需求

4.一潜在的可从其它任务获取的需求

下图说明用于构建一对象的不同结构间的关系:

根据数据结构,对象句柄是一个简单的整型或指针值,用于指定对象的实现。该对象句柄将返回到一个应用以响应创建或打开一个对象类型的实例的请求,并传递到为响应查询或属性设置的请求的指定对象的实现。

继承的对象可能用或不用与它们基本类相同的句柄,as_ObjectHandle()函数可用于为一给定的对象找出其使用的句柄。给定句柄,即意味着可能使用所有基本对象类型的API。对一继承对象类型,并没有一种机制可以重写由基本对象类型提供的方法(对象方法属于C函数调用)。

对下代码提代一个在相同的代码中使用接口与任务句柄的例子:

在很多情况下,在基对象与继承对象句柄间,对象的实现简单地共享相同的句柄地址指针,在这些实现中,从C的观点来讲,某种类型的句柄理论中是可以给另一个使用的,这就意味着继承类的数据是附于父类的数据区的:

362 对象属性

Quantum对象使用一个属性机制以提供以下功能:

1.参数初始化

2.以不影响性能的方式接入

3.接入状态消息

RWI代表接入属性的不同类型,R代表属性可读,W代表属性在初始化后可写(管理目的),I表示属性在初始化阶段可写(初始化目的),但初始化完成后不能进行该操作。

363 对象命名系统

对象由全局的命名系统组织,很像传统的UNIX文件系统,但主要有以下两点不同:

1“files”简单地包含内存中对象相关信息,而非数据部分本身

2.任何“file”都可能同时是对象本身或包含其它对象

通常,文件系统的顶层结构包括:

1/task – 任务所创建的任务和对象

2/taskqos – 任务调度参数预设置名称集

3/memory – 全局命名共享内存

4/region – 内存区域

5/pool – 全局消息池

6/interface – 全局的共享接口

7/interrupt – 硬件中断源

8/semaphore – 全局共享信号量

9/var – 用于属性值的变量

抱歉!评论已关闭.