周全 ES体系结构的研究及其应用
内核还包含一些一般性的任务和机制,这些任务和机制可使Linux 内核的各个部分有效地组合在一起,它们是上述系统高效工作的必要保证。
3. 微内核操作系统QNX[13,22,23]
QNX是一个实时、嵌入式、微内核操作系统。QNX区别于传统的没有内存保护的内核或单一结构操作系统,它是一种有内存保护的微内核系统。
操作系统是由一组进程构成。内核(kernel)是操作系统的“核心”。QNX认为“kernel”不应该包含太多功能,如果包含太多功能就不是内核,而是整个操作系统。
QNX内核非常小,仅仅提供一些基本的服务:线程服务、信号服务、消息传递服务、同步服务、调度服务、时间服务、进程管理服务。 所有的OS服务,除了强制性的微内核和process管理模块(procnto),其他都按照标准的进程处理。一个配置齐全的系统可以包含以下部分:文件系统、字符设备管理器、图形用户接口(Photon)、本地网络管理器、TCP/IP。
进程间通信(IPC)是一个由多个进程组成的应用设计关键。
操作系统提供一个简单而强大的IPC能力,简化开发由协作进程构成的系统的难度。 对QNX的评价:
QNX是一个成功的商业化微内核操作系统。它的体系结构最大的特点是由一个“准微内核”和一系列OS服务进程构成的实时操作系统。说它是“准微内核”是因为一个“纯微内核”仅仅包含消息、线程和同步机制(如OS L4)。
QNX的内核将进程管理服务捆绑到微内核,构成了支持CPU时间资源和Memory资源管理的“主机支撑模块”。其他OS服务,如文件系统、字符设备等等,作为普通进程处理。
这种结构是权衡效率和灵活性的结果。虽然将进程管理(包括内存映射服务)放到内核空间执行,不完全符合微内核的特点,但是,解决了内核和进程管理进程之间频繁IPC带来的巨大负担。
4. 微内核操作系统OSE[14]
OSE是基于消息的操作系统。OSE实时内核符合实时系统开发人员对强大的功能和简单易用的需求。大部分的开发应用需要做的是使用8个强大的系统调用(system call)。还有70多个用于特殊用途的另外调用。这样,使得OSE的代码容易编写,容易和小组其他的开发人员分享,并且容易维护。除了它的强大功能,内核特别的小,它小于100KB的内存。
OSE的特点具有以下特点: ⑴ OSE进程
OSE中最基本的元素是进程,进程共享CPU时间。OSE的进程有不同的categories和types。每一个categorie和type有特殊功能。 OSE进程有4种类型:
① 中断进程(Interrupt processes)
这是中断处理程序。中断进程拥有和普通进程一样的上下文,并且总是在进程类型中具有最高优先级。
② 时钟中断进程(Timer interrupt processes)
它与中断进程有相同的工作方式。它们是根据特定的时间间隔,被周期性地调度。 ③ 具有优先级的进程(prioritized process)
这是最普通的进程类型,它进行大量的处理,并且写成一个无限循环。在没有中断进程和更高优先级的进程运行时,这一类进程不间断地运行。
④ 背景进程(Background processes )
它以严格的时间片轮转(round robin time slicing)模式在一个比所有优先级进程低的优先级运行。背景进程可以被优先级进程或者中断进程在任何时间抢占。
⑵ 进程目录(Process Categories)
31
扬州大学硕士学位论文
进程可以是静态的或者动态的。静态的进程在系统开始的时候由内核创建。静态进程在系统存在的所有时间都存在。
动态进程可以在系统运行时创建和中止,用来支持相同代码的多个实例和保留系统资源。通过提供进程的两种类型,OSE使应用优化到最佳性能和灵活性。
⑶ OSE中的块和段(Blocks and Segments)
OSE实时内核除了进程,还有高级对象用于组织程序和它们的资源。这些附加的对象是blocks 和 segments。
OSE允许若干进程归成一组到一个block中。一个block可以有它自己本地和堆栈内存区,并且blocks可以当成是一个进程。Blocks可以通过一条消息直接创建、中止。
映射blocks到OSE Memory Management System (MMS) segments,和映射OSE pools到MMS regions 可以得到完全的内存保护和程序隔离。
Blocks和pools可以放到相同的或者不同的MMS segments。 ⑷ 进程间通信
在OSE中,进程可以通过不同的途径实现通信或者同步,包括许多传统操作系统提供的机制。OSE的直接消息传递机制提供强大的能力。消息是进程间通信最强大和安全的方法,并且可以用于相同CPU或者远程的CPU之间的进程间通信。
⑸ 消息
OSE 消息由一个进程发出到另一个进程。一个消息,也被叫做一个信号,包含一个ID、发送者地址、接收者地址和数据。一旦一个消息发送到另一个进程,发送进程就不能再访问它。一个消息的所有权永远不被分享。这个重要的特性可以杜绝传统操作系统容易发生的内存访问冲突的错误。更进一步,OSE中消息传递的非常高效,并且直接消息传递在概念上比其他非直接模型更快。
在任何特定时刻,接收进程可以定义它要接收的消息类型。进程可以对一个特定的信号、一组信号或者任何信号,等待或者轮询消息队列。进程也可以定义一个信号的超时时限。
对OSE的评价:
OSE是新兴嵌入式微内核操作系统的代表。OSE具有很多早期操作系统不具备的优点。OSE最吸引人的地方在于进程管理和进程间通信。
进程管理引入了block和segment的概念,这个概念可能是从Oracle数据库借鉴来的。在同一个block或者segment的进程集合运行于同一个进程空间,对于性能有限的嵌入式系统,这种同一地址空间的进程管理有助于提高系统的运行效率和安全性。
OSE第二个特点是基于指针的消息传递,避免了数据拷贝开销。这种基于指针的消息传递的实现,离不开智能化的内存管理。这种内存管理,和Java的动态对象管理比较相似。 5. 不同操作系统比较的总结
从不同的嵌入式操作系统的特点,可以概括出嵌入式操作系统的基本特点: ⑴ 好的嵌入式操作系统是一个完整的解决方案和集成化的开发系统 现代的嵌入式操作系统有的商业化开发系统将RTOS和BSP集成到一起,提供商提供集成的开发环境。源代码的编辑、管理,版本控制,编译器,链接器,库文件,调试器,仿真接口等等紧密地集成到统一的开发环境中。 ⑵ 高可靠性、高性能、高实时性 可靠性、高性能和实时性成为嵌入式操作系统的标准要求。由于操作系统理论的成熟,现代的嵌入式操作系统绝大多数都具备实时性或者准实时性。不具备实时性的嵌入式系统已经很少了。
这些具有实时性的嵌入式系统,同时具备高性能和高可靠性。高性能和实时性主要是通过操作系统设计和体系结构设计以及设计优化过程达到的。高可靠性依赖于合理的设计
32
周全 ES体系结构的研究及其应用
和大量的测试验证。 ⑶ 内核小,体系结构清晰
现代嵌入式操作系统含有性能优秀的内核。内核一般分为硬件抽象层和服务层。驱动程序运行于用户态,这是典型的微内核体系结构。但是,有些操作系统(如Win CE.NET[15])线程可以运行于用户态或者内核态,给系统实现提供了更大的选择余地来权衡性能和可靠性。
合理的内核和驱动程序模型为嵌入式系统的驱动程序开发提供了便利,使操作系统很容易支持新的硬件。 ⑷ 功能丰富,具有网络模块、图形界面
现代嵌入式操作系统一般都具有网络模块和图形界面这些复杂的模块支持。这些模块对于整个系统的实时性有很大的影响,必须经过优化、配置,才能在嵌入式系统中得到很好的利用。 ⑸ 系统资源的运行监测和实时性验证
现代嵌入式操作系统提供功能强大的内核监测工具(profiling)和统计工具。这些工具一般具有图形化界面,开发人员可以清晰地观察每个进程的内存分配、内存泄漏情况,CPU运行时间分布等系统状态,对于调试程序很有帮助。
3.3.2.8 如何构建自己的嵌入式操作系统
通过对不同的EOS的分析研究,初步掌握了EOS基本体系结构和新的设计思想,为下一步开发自己的实时操作系统内核打下基础。 1. 单一内核 vs. 微内核
单一内核的服务运行于内核地址空间,效率高,灵活性差。微内核的服务运行于用户进程空间,通过IPC实现操作系统服务,结构清晰,稳定性高,一个服务的错误不会使整个系统崩溃,但是效率比较低。
Linux基本属于单一内核体系结构,通过模块(Module)可以将驱动程序加载到内核空间,兼顾了效率和灵活性。
Win CE的服务运行在内核地址空间,允许所有的用户进程可以运行在用户空间或者内核空间,让用户可以根据要求选择性能优先还是可靠性优先。
现代嵌入式操作系统,应该是单一内核和微内核之间的折衷,是一种动态内核。这种内核支持驱动程序动态链接到内核地址空间,也支持驱动程序运行在用户进程。同样,对于用户进程,既可以运行于内核地址空间,也可以运行于用户地址空间。
在这样的操作系统中,驱动程序和应用程序没有本质的区别。它们的区别是驱动程序为操作系统提供服务;而应用程序是使用操作系统提供的服务。
有的操作系统,在动态链接的基础上更进一步,使用面向对象和组件技术,将系统服务封装成组件,实现处理器级的可移植性。“和欣”[16]操作系统就是基于组件系统构建的。
2. 内核态
操作系统内核的作用是捕捉和处理例外:硬件中断和软件中断。硬件中断产生以后,CPU自动调转到中断向量,执行中断服务程序,然后返回。软件中断是应用程序执行过程中,执行软中断指令产生的中断。软件中断产生后,CPU像硬件中断一样,自动调转到中断向量,执行中断服务程序,然后返回。不论是软件中断还是硬件都会使CPU进入“内核态”。
所以,操作系统的实质是由外部或者内部“例外”触发,CPU进入内核态处理相关例
33
扬州大学硕士学位论文
外的程序。
3. 系统服务 系统服务是针对相应的“例外”处理程序。这些程序,构成了操作系统服务,构成了整个操作系统。 内核的作用是将内部例外和外部例外(软件中断和硬件中断)与系统服务连接起来。内核应该保持简单,只实现例外到服务程序的映射,而不要将系统服务添加到内核。 这不意味着内核和服务必须运行于不同的地址空间。这样做的结果是效率低下,微内核就是片面强调服务运行于独立的地址空间。 最好的方式是将系统服务与内核在逻辑上分离,根据不同的需要运行于内核空间或者用户空间。
4. 虚拟内存和实时性
高端的处理器一般都具有MMU,支持这种结构的操作系统需要具备管理虚拟内存的能力,才能够很好的发挥处理器的功能。
虚拟内存通过虚地址到硬件地址的转换,使不同地址空间的进程独立地运行。程序运行时,不必全部加载到内存中,而是通过映射部分程序到内存中,当访问的地址不存在,产生缺页中断,将缺页部分的程序映射到内存。
实时系统最关键的要求是尽可能短的中断响应时间和执行的可预测性。对于实时进程,加载缺页到内存中影响系统的响应时间和可预测性。因此,设计EOS时候必须考虑虚拟内存对实时性的影响。
3.4 应用软件的设计 3.4.1 模块化设计
应用软件的模块化设计,是一个软件工程学的问题。模块化设计是将系统划分成若干个模块进行设计、实现的方法。模块化设计有以下优点: ① 有利于团队开发
② 有利于设计复用(reuse) ③ 便于调试
模块化设计虽然有很大的优点,但是有一些不足: ① 增加代码量 ② 接口关系复杂
通常,一个系统被划分成几个模块。各个模块内紧耦合,不同模块之间松耦合。例如,一个嵌入式系统有键盘、LCD、A/D、无线通信等部分。这些部分可以构成独立模块。在应用软件设计阶段将他们分成不同的模块实现。
模块化设计的原则就是模块内联系紧密,而模块之间联系尽量的松疏。
模块化设计可以通过Resourcing(代码重构),将没有模块化的代码改造成可重用的模块。一般可以开始写一段可以跑起来的代码,然后再修改它,把它添加到整个应用中去,这就是最基本代码重构。
3.4.2 面向对象设计
目前嵌入式系统面向对象设计不是非常流行。面向对象的设计,依赖于面向对象的设
34
周全 ES体系结构的研究及其应用
计工具和实现语言。设计和验证工具中,UML(Unified Modeling Language)成为事实的标准。UML不仅适用于商业应用的建模,也适用于嵌入式系统的建模。Embedded C++是专用于嵌入式系统的C++语言[17]。
面向对象的设计对于某些场合非常合适。例如,图形界面(GUI)有很多是用面向对象的方法实现的,因为图像界面一般都具有面向对象的特征。
操作系统的对象,比如进程、线程、信号量等等同样具有对象的特征。Amoeba 、Java是面向对象的操作系统和语言。
3.4.3 低功耗设计
便携式设备和一些需要长期使用电池的固定设备对系统功耗有很高的要求。低功耗设计主要指系统功耗尽可能的低。
解决低功耗的途径是智能化的电源管理(PM)。在不工作的时间内切断系统大部分的供电,停止脉冲输入,只留下核心部分的供电,使整个系统进入待机状态。
35