QNX中微内核RTOS的主要目的是提供一种健壮的、可裁剪的基于POSIX API开放系统,这种系统广泛适用于从小型、资源受限的嵌入式系统到高端的分布式计算环境。该操作系统支持多种处理器架构,包括x86和ARM。
实时应用程序开发的一个常见问题是,每个实时操作系统都有自己的专用API。在没有行业标准的情况下,这对于一个竞争激烈的市场来说并不是一个不寻常的状态,因为实时市场的调查经常显示大量使用内部专有操作系统。POSIX代表了一个统一这个市场的机会。在许多POSIX标准中,嵌入式系统开发人员最感兴趣的是:
•1003.1定义了用于进程管理、设备I/O、文件系统I/O和基本IPC的API。这包括UNIX操作系统的基本功能,作为许多应用程序的有用标准。从C语言编程的角度来看,ANSI X3J11 C被假定为一个起点,然后管理进程、文件和tty设备的各个方面的详细信息超出了ANSI C所指定的。
•Realtime extensions -定义了一组基于1003.1标准的实时扩展。这些扩展包括信号量、优先级进程调度、对信号的实时扩展、高精度的定时器控制、增强的IPC原语、同步和异步I/O,以及对实时连续文件支持的推荐。
•线程——进一步扩展POSIX环境,包括在给定的地址空间中创建和管理多个执行线程。
•额外的实时扩展——定义了实时标准的进一步扩展。描述附加中断处理程序等工具。
•应用环境概要——定义POSIX环境的多个AEP(实时AEP、嵌入式系统AEP等),以适应不同的嵌入式功能集。这些概要文件表示包含/不包含文件系统和其他功能的嵌入式操作系统。
除了采用行业标准的任何“潮流”动机外,将POSIX标准应用于嵌入式实时市场有几个具体的优点:
支持多个操作系统
硬件制造商不愿选择单一操作系统源设计硬件组件,因为如果该操作系统源停止生产,就会产生潜在的风险。出于同样的原因,制造商不应该仅仅因为他们的应用程序源代码无法移植到其他多个操作系统而被绑定到一个单一的、专有的操作系统上。通过构建应用程序到POSIX标准,开发人员可以使用来自多个供应商的操作系统。应用程序源代码可以很容易地从平台移植到平台,从一个OS移植到另一个OS,只要开发人员避免使用特定于OS的扩展。
开发人员的可移植性
使用一个用于嵌入式开发的通用API,经验丰富的程序员可以直接将他们应用到其他涉及其他处理器和操作系统的项目中。此外,拥有UNIX或POSIX经验的程序员可以轻松地在嵌入式实时系统上工作,因为实时操作系统API的非实时部分已经是我们熟悉的领域。
开发环境
即使在跨平台的开发环境中,API也与嵌入式系统上的API基本相同。无论特定的主机(Linux、Windows、…)还是目标主机(x86、ARM),程序员都不需要担心特定于平台的大小端对齐或I/O问题。操作系统的主要职责是管理计算机的资源。系统调度应用程序中的所有活动、向磁盘写入文件、跨网络发送数据等等应该尽可能无缝、透明地协同工作。
有些环境需要比其他环境更严格的资源管理和调度。例如,实时应用程序依赖于操作系统来处理多个事件,并确保系统在可预测的时间范围内响应这些事件。操作系统响应得越快,实时应用程序就越需要满足它的最后期限。
QNX中微内核RTOS是嵌入式实时应用的理想选择。它可以被扩展到非常小的尺寸,并提供多任务、线程、优先级的抢占式调度和快速上下文切换——这是嵌入式实时系统的所有基本要素。此外,操作系统用posix标准API来实现这些功能;为了实现一个小的系统,没有必要放弃posix标准。
QNX中微内核也非常灵活。开发人员可以轻松地定制操作系统以满足他们的应用程序的需求。从微内核的“最基本的”配置(只有几个小模块)到全面的网络系统(可以为数百个用户提供服务),可以自由地设置系统,只使用需要的资源来处理手头的工作。
QNX中微内核通过两个基本原则实现了其独特的效率、模块化和简单性:
•微内核体系结构
•基于消息的进程间通信
流行词经常是流行和过时的。供应商们往往会热情地将当天的流行语应用到他们的产品上,不管这些术语是否适用。“微核”一词已经变得流行起来。尽管许多新的操作系统被称为“微内核”(甚至是“纳米粒子”),但如果没有一个明确的定义,这个术语可能就没有什么意义了。让我们来定义这个术语。微内核操作系统是一个很小的内核,它提供了一个可选的协作过程所使用的最小服务,而这又提供了更高级别的操作系统功能。微内核本身缺乏操作系统通常需要的文件系统和许多其他服务;这些服务是可以配置的。
设计微内核操作系统的真正目标不是简单地“使它变小”。微内核操作系统体现了实现操作系统功能的基本方法。模块化是关键,大小只是一个辅助作用。将任何内核称为“微核”,仅仅是因为它很小,就完全忽略了这一点。
由于微内核提供的IPC服务用于将OS自身“粘合”在一起,这些服务的性能和灵活性决定了所得到的OS的性能。除了这些IPC服务,一个微内核几乎可以与实时管理系统相提并论,无论是在提供的服务还是在它们的实时性能方面。
微核的区别在于IPC服务是如何将内核的功能扩展到额外的服务程序。由于操作系统是作为一个由微内核管理的协作过程的团队来实现的,用户编写的进程既可以作为应用程序,也可以作为扩展特定于行业应用程序的底层操作系统功能的进程。操作系统本身变得“开放”并且易于扩展。此外,对OS的用户写扩展不会影响核心OS的基本可靠性。
实现POSIX 1003.1标准的许多实时管理人员遇到的一个困难是,他们的运行时环境通常是一个单进程、多线程的模型,线程之间没有保护的内存。这种环境只是POSIX假设的多进程模型的一个子集;它不能支持fork()函数。与此相反,QNX中微内核充分利用了MMU在受保护的环境中提供了完整的POSIX进程模型。
如下图所示,一个真正的微内核提供了完整的内存保护,不仅用于用户应用程序,还包括OS组件(设备驱动程序、文件系统等):
图1:传统的系统没有提供内存保护
图2:在单内核操作系统中,系统进程没有保护
图3:微内核提供了完整的内存保护
QNX中RTOS由一个小型的微内核组成,它管理着一组协作过程。如以下图示所示,与层级相比,该结构看起来更像是一个团队,因为几个相同等级的“玩家”通过协调内核彼此交互。
图4:QNX中微内核RTOS体系结构
QNX中微内核充当一种“软件总线”,它可以让你在需要的时候动态地插入/输出OS模块。
内核是任何操作系统的核心。在某些系统中,“内核”包含了许多功能,无论从什么角度来看,它都是整个操作系统!但是我们的微内核是真正的内核。首先,就像实时管理的核心一样,它非常小。其次,它是致力于只有几个基本服务:
•线程服务通过POSIX线程创建原语;
•通过POSIX信号原语提供信号服务;
•消息传递服务——微内核处理整个系统中所有线程之间的所有消息的路由;
•通过POSIX线程同步原语进行同步服务;
•调度服务——微核程序使用各种POSIX实时调度策略调度线程;
•定时器服务——微核提供丰富的POSIX计时器服务;
•进程管理服务——微内核和进程管理器组成一个单元(称为procnto)。进程管理器部分负责管理进程、内存和路径名空间。
与线程不同,微内核本身永远不会被调度执行。处理器只在微内核中执行显式内核调用、异常或响应硬件中断的结果。
除了强制性的微内核/进程管理器模块(procnto)提供的服务外,所有OS服务都通过标准进程处理。一个配置丰富的系统可以包括以下内容:
•文件系统管理
•字符设备管理
•本机网络管理器
•TCP / IP
系统进程与任何用户编写的程序本质上是不可区分的——它们使用对任何(适当特权的)用户进程可用的相同的公共API和内核服务。正是这种架构赋予了QNX中微内核RTOS无与伦比的可扩展性。由于大多数OS服务是由标准的系统进程提供的,因此扩展OS本身非常简单:只需编写新的用户进程来提供新的OS服务。实际上,操作系统和应用程序之间的界限可能会变得非常模糊。系统服务和应用程序之间真正的区别是操作系统服务为客户端管理资源。
假设已经编写了一个数据库服务器——如何对此类进程进行分类?正如文件系统接受打开文件和读写数据的请求(通过消息)一样,数据库服务器也是如此。虽然对数据库服务器的请求可能更复杂,但这两个服务器都非常相似,因为它们提供了一个API(由消息实现),客户端使用该API访问资源。两者都是独立的过程,可以由最终用户编写,并在需要的基础上启动和停止。
一个数据库服务器可能被认为是一个系统进程在一个安装,和一个应用程序在另一个。它真的不重要!重要的一点是,OS允许干净地实现此类进程,不需要修改OS本身的标准组件。对于开发定制嵌入式系统的开发者来说,这提供了扩展操作系统的灵活性以对他们的应用非常有用,而不需要访问操作系统源代码。
设备驱动程序允许操作系统和应用程序以通用的方式使用底层硬件(例如,磁盘驱动器,网络接口)。虽然大多数OSs都要求设备驱动程序紧密地绑定到OS本身,但是QNX中微内核的设备驱动程序可以作为标准进程启动和停止。因此,添加设备驱动程序不会影响操作系统驱动程序的任何其他部分,可以像开发其他应用程序一样开发和调试。
当几个线程同时运行时,比如在典型的实时多任务环境中,操作系统必须提供允许它们彼此通信的机制。进程间通信(IPC)是将应用程序设计为一组协作进程的关键,其中每个进程处理整个一个明确定义的部分。操作系统提供了一组简单但强大的IPC功能,大大简化了开发应用程序的工作。
QNX Neutrino是第一个利用消息传递作为IPC基本手段的商业操作系统。操作系统的强大、简单和优雅主要归功于在整个系统中对消息传递方法的完整集成。
在QNX Neutrino中,消息是从一个进程传递到另一个进程的字节包。操作系统对消息的内容没有特殊的意义——消息中的数据对消息的发送者和它的接收者有意义,但对其他任何人都没有。
消息传递不仅允许进程相互传递数据,还提供了同步多个进程执行的方法。当他们发送、接收和回复消息时,进程会经历各种“状态的变化”,这些“状态变化”会影响到运行时间。了解它们的状态和优先级,微内核可以尽可能高效地调度所有进程,以充分利用可用的CPU资源。这种单一的、一致的方法——消息传递——因此在整个系统中一直有效。
实时和其他关键任务应用程序通常需要一种可靠的IPC形式,因为组成这些应用程序的过程是如此紧密地相互关联。QNX Neutrino的消息传递设计强加的规则有助于为应用程序带来秩序和更高的可靠性。
在它最简单的形式中,本地区域网络提供了一种机制用于在多个互联的计算机中共享文件和外围设备。QNX Neutrino远远超出了这个简单的概念,并将整个网络集成到一个单一的、同构的资源集合中。
在它最简单的形式中,本地区域网络提供了一种机制用于在多个互联的计算机中共享文件和外围设备。QNX Neutrino远远超出了这个简单的概念,并将整个网络集成到一个单一的、同构的资源集合中。网络上任何机器上的任何一个线程都可以直接使用任何其他机器上的任何资源。从应用程序的角度来看,本地或远程资源之间没有区别——不需要在应用程序中构建特殊的设施,以允许它们使用远程资源。用户可以在网络上的任何地方访问文件,利用任何外围设备,并在网络上的任何机器上运行应用程序(只要他们有适当的权限)。进程可以在整个网络的任何地方以相同的方式进行通信。同样,操作系统中无处不在的消息传递IPC也解释了这种流畅、透明的网络。
QNX Neutrino是作为一个全网操作系统而设计的。在某些方面,一个原生的QNX Neutrino网络感觉更像是一台大型计算机,而不是一组单独的微处理器。用户简单地知道可由任何应用程序使用的大量资源。但与大型机不同的是,QNX Neutrino提供了高度响应的环境,因为可以在每个节点上提供适当的计算能力,以满足每个用户的需要。
例如,在关键任务环境中,控制实时I/O设备的应用程序可能比其他不那么关键的应用程序(如web浏览器)需要更高的性能。网络的响应能力足以同时支持这两种类型的应用程序——OS允许您将计算能力集中在硬实时系统中的设备上,在需要的地方和时间,而不会牺牲到桌面的并发连接。此外,实时计算的关键方面,如优先级继承,在QNX Neutrino网络中无缝运行,而不考虑使用的物理介质(交换结构、串行等)。
QNX Neutrino网络可以使用各种硬件和行业标准协议。由于这些对应用程序和用户是完全透明的,因此可以随时引入新的网络架构,而不会干扰操作系统。网络中的每个节点都被分配一个唯一的名称,作为它的标识符。这个名称是确定操作系统是作为网络运行和作为独立操作系统运行的惟一可见方法。
这种程度的透明性是QNX Neutrino的消息传递体系结构的独特力量的又一个例子。在许多系统中,网络、IPC、甚至消息传递等重要功能都是建立在操作系统之上的,而不是直接集成到内核中。结果通常是一个笨拙的、低效的“双重标准”接口,在这个接口中,进程之间的通信是一回事,而穿透一个神秘的整体内核的私有接口则完全是另一回事。
与单片系统相比,QNX Neutrino是基于有效通信是有效运行的关键。因此,信息传递形成了我们的微内核体系结构的基石,并提高了整个系统的所有过程的效率,无论是跨越PC底板还是跨过双绞线。