一、QNX和微内核 QNX实时操作系统是一个基于"微内核"概念设计的、符合POSIX 1003.13标准的多任务多用户系统,其内核只有8K字节,可装入486芯片的在片高速缓存(CACHE)中。对于33MHz的486和8MHz的ISA总线(不使用外部高速缓存),它达到的基本指标为: ·上下文切换时间为12微秒 ·中断等待时间为6微秒 ·1.8MBps磁盘存取速度 ·1.05MBps网络存取速度 1.微内核概念 传统的UNIX操作系统是分层的操作系统。它在出现之初,就因其内核功能精炼而使人赞叹不已。而新一代"微内核"操作系统,其内核功能之精炼,又使传统UNIX系统无法望其项背。 微内核通常只保留进程间通信(IPC)、进程调度等几项功能。它依据客户-服务者模型概念,把所有其它的操作系统功能都变成一个个用户态的服务器,而用户进程则被当做客户。客户要用到操作系统时,其实就是通过微内核与服务器进程通信而已。微内核仅仅作为一个传递消息的工具,验证消息的有效性,在客户和服务器之间传递它们,并核准对硬件的存取,如图1所示。 @@I1;图1 微内核操作系统@@ 注意,微内核之"微",是指它的内核功能少,而内核尺寸不一定小。例如,著名的微内核操作系统MACH的内核为100~200KB,并不小。 采用微内核有如下优点: ·与CPU有关的硬件方面的细节都包含在小小的内核里,这样,整个操作系统很容易从一个CPU体系移植到另一个CPU体系。 ·如果要扩展功能,仅只是增加相应的服务器而已。 ·在微内核方式下,各个服务器都是独立的用户态进程,有自己的内存保护空间,以标准的IPC方式通信,一个服务器出错,不会导致整个系统崩溃。 ·服务器可以在不同的处理机上运行,适合多处理机系统或分布式处理系统。 2.用于实时的微内核 把微内核机制用于实时操作系统,存在两种担心:一是用户态与内核态切换频繁,会增加上下文切换时间;二是进程之间消息传递的开销要比传统操作系统的系统调用开销大。 对于第一个担心,通常上下文切换时间与执行一项操作系统服务总的时间相比很小,尤其是对上下文切换时间进行优化之后。另外,分立的服务器进程可以使各项操作系统服务并行进行,而且各服务器进程还可以像用户进程一样按优先级处理,这些都带来了极大的优越性。因此从总体来看,微内核的开销比传统操作系统的开销反而要小。 对消息传递开销,我们可以分几点来讨论。首先,大多数消息传输都在20字节的数量级,传输这种消息的开销本来就不大。其次,微内核提供多分部(MULTI-PART)消息传输机制(如图2),在传输大消息时,可将消息从一个进程直接传到另一个进程,免去了为使消息块相邻而要做的多余的拷贝工作。在做磁盘I/O时,也可以使用多分部传输机制直接拷贝磁盘块,不必像传统内核那样,做多余的拷贝操作。在传输大消息时,高优先级进程还可以抢先,不至于被大消息传输所延误。另外,直接传递消息而非消息指针,因此不必使用信号灯来判断哪一个进程"拥有"消息,从而免去了信号灯的开销。最后,消息传递方法使用户的地址空间和系统服务提供者的地址空间完全分开,使它们十分容易地在不同的网络节点上运行。这些都使得消息传递开销不大。 @@I2;图2 用MX控制结构说明多分部消息@@ 3.QNX的微内核 QNX实时操作系统的微内核,无论在功能上还是尺寸上,都可能是最小的。其8KB的微内核只提供三项基本服务,包括14个内核调用。这三项基本服务为: (1)进程间通信 以QNX微内核的进程间通信机制为例,它有三个功能调用:Send(),Receive()和Reply()。一个进程(源进程)向另一个进程(目标进程)作Send()调用后,它就阻塞;直到目标进程作了Receive()调用,处理了消息,又作了Reply()调用之后,源进程才恢复执行。如果一个执行Receive()调用的进程并没有消息悬置着等它,它就阻塞,直到别的进程对它作Send()调用。由于消息传递机制对发送者或接收者的阻塞,它就在进行通信的进程之间起了同步作用。这个最简单的办法,使内核能以尽可能高的效率进行进程间通信。另外,QNX从一个进程的地址空间直接拷贝数据到另一个进程的地址空间,不使用任何中间缓冲区,这就使得消息投递的性能达到所在硬件系统的存储器带宽。所有服务器进程提供的系统服务,都是基于这个高性能消息传递服务的;其它IPC服务(例如管道、消息队列等)也是在这个最基本的消息传递服务基础上实现的。事实证明,这种机制比其它的内核队列系统效率高。 (2)进程调度 在QNX管理下,各进程都可以请求消息按优先级(而不是FIFO)来投递。服务器进程可以要求"消息驱动"的优先级,即根据请求服务的进程优先级高低来安排执行顺序,而且,当有高优先级进程在正在忙的服务器上阻塞时,服务器进程会自动提高自己的优先级。 其结果是,低优先级进程不能请求优先级已变得比自己高的服务器进程的服务,只好马上放弃,使高优先级进程立即得到所要求的服务。 QNX的实时进程调度满足POSIX 1003.4所规定的几个等级的进程调度,也即具有轮转优先、FIFO优先和特定应用的调度算法。 (3)多分部消息 多分部消息传输机制使得从一个进程传向另一个进程的消息不必在内存里占据单一的、相连的区域。发送进程和接收进程可以各自指定一个MX表,在表中指明发送进程和接收进程的消息碎片在内存中的位置,如图2所示。有一种消息,它的首块与其它数据块分别放置在不同位置,用多分部消息机制来传输这种消息,就可以免去先把它们合在一起的拷贝工作。如果要传输消息的数据结构是环形缓冲区型的,还可以用一个三分部消息将其首块和两个不相连的区域作为一个单一的、"原子的"消息来传输。这个概念等效于硬件中的所谓"散-聚(SCATTER-GATHER)"DMA机制。 4.QNX的服务器 QNX提供以下服务器: ·进程管理服务器(PROC) ·文件系统管理服务器(FSYS) ·设备管理服务器(DEV) ·网络管理服务器(NET) 其中,只有进程管理服务器是建立一个基本系统所必不可少的,其余服务器都是可选项,可根据所要求的系统大小而加入。 进程管理服务器提供的服务包括生成进程、进程计数、内存管理、进程环境继承、路径名空间管理等。因为文件管理服务器不是必需的,因此第一级路径名的管理是由PROC负责的。微内核加上进程管理服务器、再加上子程序库所构成的最小系统,大小约80KB。 文件管理服务器是资源管理者,为QNX提供符合POSIX要求的文件系统;建立磁盘结构,使用位图来分配空闲空间;使用数组扩充的方法组织磁盘文件。此外,FSYS还提供一个专门的小型文件系统,供小型嵌入式系统使用;另外还有DOS文件系统。 设备管理服务器提供符合POSIX要求的设备控制,并作了某些扩充以满足实时通讯的要求。DEV和FSYS服务器都可以动态启动并附接上它们的设备驱动器,以后不用时还可从内存中除去。 多分部消息原语可以使DEV服务器把一个应用所做的写操作write()指向由一个中断处理器所管理的环形缓冲区。因为向环形缓冲区的写所要求的数据可以映射在物理上不相连、但逻辑上相邻的内存区域,使用有三个入口的MX表就可以描述环形缓冲区的首部和其物理上不相连的两段。对于read(),来自设备的数据流直接从驱动器进入环形缓冲区,再从环形缓冲区进入应用程序为读操作建立的缓冲区,无须为建立相邻的消息而做多余的拷贝。 通常都把设备驱动器的中断处理器程序放在内核中,而QNX则使中断处理器处在具有足够特权的用户进程中,用户进程用系统调用使中断处理器与微内核内的特定中断向量相联系。这样,用户可以用高级语言写中断处理程序,不必与汇编码打交道。当发生物理中断时,已与内核联系上的中断处理器就能被内核所调用。中断处理器放在用户进程里,可以充分存取用户进程的地址空间。中断处理器运行后,既可以唤醒所在的用户进程,也可以简单地返回内核。 使中断处理器在内核之外的好处是,用户可以在一个运行着的系统里动态地加上或者除去它们(以及包含它们的设备驱动器)。最初步的中断处理由内核完成,然后嵌套进入用户的中断处理器,这样可以使用户的中断处理程序不必处理与硬件有关的细节。这样,微内核资源管理的性能就与单块型的内核资源管理性能具有同等水平,并使嵌入式系统所需的设备驱动器易于在用户进程中实现。这样就使得扩充操作系统和写用户程序在功能上没有什么两样。 5.与DOS的兼容 因为QNX是在与DOS同样的硬件环境下运行,而DOS又支持大量的应用软件,因此,QNX支持DOS应用软件是一项重要的功能。QNX提供了一个称为RUNDOS的程序,使得大部分DOS软件(包括MS WINDOWS)都可以直接在QNX下运行。 二、在PC机上开发实时内核 许多应用软件开发者为了在MS-DOS操作系统的基础上开发实时应用,动了许多脑筋,但实现的功能一般较为简单。首先要解决可重入性问题,通常是利用DOS的可交换数据区SDA和未公开的DOS系统调用,常见的设计方法有两种。第一种方法是把每个与硬件相关的实时任务用一个中断服务程序来处理,使用常驻内存(TSR)的办法来设置这些中断服务程序,并在前台运行管理程序。这其实是实时监控器(MONITOR)等级的应用。第二种方法是在第一种的基础上,在时钟中断服务程序中加入多任务调度功能,只要解决好可重入性问题,就可以实现内核态的抢先。这种具有简单的实时多任务调度和实时中断功能的应用程序,已经是一个实时内核的雏形了。 在实时系统中,实时内核的主要作用就是管理一组按某种顺序执行的、称为任务的应用模块。在由内核确定的原则下,各个任务相互竞争对CPU的使用,内核的功能就体现在为任务提供各种基本服务。包括以下六项功能: 1.任务调度 任务按优先级执行,优先级通常在任务生成时指定,许多内核可以在系统运行时动态地改变任务的优先级。 在一些简单的内核里,只提供多任务的协调功能,每个任务自己负责随时判断是否应该把CPU让给别的任务。此法效率很高,但只适于最简单的情况,即只有少数几个任务、对响应时间要求也不高的情况。通常,此法与实时监控器所实现的功能相当。另一种常用的方法是时间片方法,每个任务按优先级分到时间片。这种方法只能用于实时响应要求低的情况。大多数实时应用都要求具有抢先的任务调度算法。 2.定时 实时应用几乎都要求内核提供对某种精确的时间间隔的管理。内核定时器的时间间隔(即"滴答")应该是可调的,这样就可以根据具体实时应用的最坏情况的定时要求来设置尽可能长的定时间隔。例如,如果一个应用只需要10ms的分辨率,就不要选1ms的定时时间间隔。 此外,内核必须为任务等待提供超时(time out)功能,较好的内核还应为一些内核服务提供超时功能。 3.任务同步 同步服务用来把任务的执行与异步发生的事件相同步,这些事件可能是由其它任务、中断处理器或定时器测到的或产生的。 当今的内核,有一大批任务同步服务方法可用,但并不是每个内核都要用到所有这些同步服务。设计内核时,只需根据需要挑选其中一部分即可。下面列出各种内核用到的同步服务的名称,应注意有些名称的意义可能是重复的,被一个厂商称为mailbox的服务,另一厂商可能称之为message exchange。 ·属于原语类的同步服务 二进制信号灯、计数信号灯(即PV信号灯)、资源队列等。 ·属于消息类的同步服务 邮箱(mailbox)、消息交换、任务交换、队列、管道、列表等。 ·属于信号类的同步服务 事件标志(event flag)、异步信号、同步信号、任务陷井(task trap)等。 4.中断服务 衡量一个实时系统成功与否的重要标志是中断响应的快慢。这方面有两个主要指标,一是中断等待时间,一是中断处理时间。为此,内核的中断处理器的设计颇为重要。对于极高速度中断服务的场合,中断处理器应能绕过内核,避免内核的开销。一般而言,中断处理程序应该写得短小精炼,繁重的工作应该仅由中断处理器起一个头,然后交给任务去完成,为此,内核应提供同步服务来与该任务通讯。 5.PC机外设和文件I/O 在支持PC机外设I/O和文件I/O管理方面,实时内核有很大的选择余地。对性能要求高的情况,可提供"类UNIX"的I/O服务和与MS-DOS兼容的文件管理服务。而一般的情况,只要求内核在保证能做抢先任务切换的同时,能存取MS-DOS文件和进行I/O服务即可。 许多嵌入式PC系统可能会有特定要求的外设I/O服务,这时,内核所提供的通用I/O服务可能不够用,需要加以扩充。 6.诊查 由于事件并发,实时应用的测试是一项困难的工作。因此,在设计内核时加上某些诊查功能是十分有用的。通常是在内核中加入一些出错陷井和调度器的"钩"(hook)。 |