POSIX和Linux POSIX是标准化类Unix操作系统必须具有的特征和接口的运动。POSIX的 思想是为了促进为Unix编写的软件的可移植性,使Unix程序员的工作更 容易。有些实时性的扩展,象POSIX.1b或IEEE 1003.1b已经加入到标准 中。这些扩展中包括一些工具,比如信号灯、内存锁定、时钟和计数器 、消息队列以及优先级抢先调度。
以POSIX为基础来标准化实时操作系统已经受到指责。这个标准又大又 笨,包含了许多适合台式Unix工作站但无助于嵌入式系统的特征,因而 显得很臃肿。标准制定群体被工作站制造商控制,他们不愿对RTOS供应 商和用户让步。还有,POSIX系统调用反映了Unix系统调用的复杂和笨 重,在VxWorks或pSOS+中仅需一两个调用即可完成的操作可能需要十几 个POSIX调用。Unix程序员已经习惯了这种麻烦事,但是嵌入式系统程 序员却觉得很难受。
许多Linux开发者正在为了在Linux中实现POSIX.1b的特征工作。这个活 动已经初见成效并且仍在继续。POSIX内存锁定工具和决定调度算法的 函数已经实现。另外,计数器函数和POSIX.1b信号仍未完成。也许最糟 糕的是,对任何真正的RTOS都至关重要的信号灯和消息队列也未实现。
定义于POSIX.1c(或IEEE 1003.1C)中的POSIX线程保证会为POSIX路线 的Linux开发实现。一个进程内可以有多个线程,共享相同的地址空间 。这很符合我们熟悉的嵌入式系统中任务的概念。Linux已经部分实现 了POSIX线程。
虽然POSIX路线对实现一个实时Linux做了保证,当前和可预见的将来只 有“软”实时的应用能用POSIX.1b函数来实现。移植POSIX.1b函数到L inux上时要面对的根本问题是Linux的内核是不可抢先的。因此,要想 不对内核大动干戈而实现“硬”实时特性恐怕是不可能的。 通向实时Linux的低层路线 Low-level Approach to Real-time Linux
比POSIX路线更有意思的是实现硬实时Linux的努力,其中最有前途的要 数新墨西哥技术学院的实时Linux(RT-Linux)项目。注意到Linux是一 个为台式电脑用户设计的操作系统,研究者们断定,要想把实时功能移 植到为分时设计的OS上是不会有好结果的。取而代之的是,他们在操作 系统的下面实现了一个简单的实时内核,而Linux本身也仅作为那个内 核上的一个任务来运行。Linux运行的优先级最低,随时可以被更高优 先级的任务抢先。
RT-Linux的设计理念是,对Linux作最小的改动,仅提供为了实现实时 应用必不可少的东西。这样就使RT-Linux比较容易移植到新版本的Lin ux上。同时,RT-Linux依赖于Linux来提供所需的几乎所有服务,而RT -Linux仅提供低层任务创建、安装中断服务例程、并为低层任务、ISR 和Linux进程之间的通信排队。
这种设计的结果之一是,一个RT-Linux应用可以看作有两个域:实时和 非实时。放在实时域的函数能满足其实时要求,但是它们必须比较简单 ,因为可用资源很受限制。另一方面,非实时功能可以利用整个Linux 资源,但不能有任何实时要求。两个域之间的通信工具已提供。但是使 用RT-Linux之前,嵌入式系统设计者必须确保所有需要实现的功能适合 两个域之一。使用RT-Linux并不能变戏法似的使已经存在的Linux功能 具有实时性。例如,假设设计者有一个串口的Linux驱动程序,当串口 接收一个字节序列之后,在一个固定时间内,由实时任务打开并口输出 一行。这个驱动程序不能用,因为在非实时域内你不知道什么时候串口 驱动程序会唤醒实时任务驱动并口完成工作。因此,串口和并口驱动都 必须在实时域内,这就要求重新设计串口驱动程序。
RT-Linux的任务处理工具是基本的。rt_task_init()用来创建并开始一 个任务,能指定堆栈的大小和优先级。Linux本身以一个最低优先级的 实时任务运行。rt_task_make_periodic()以一定间隔周期性地设置任 务运行。rt_task_wait()阻塞任务。使用简单的抢先调度运行任务。 实时任务与Linux进程之间通信的主要方法是FIFO。rtf_create()创建 一个一定大小的FIFO。用rtf_put()将数据送入FIFO,如果FIFO满则返 回一个错误。类似地,rtf_get()从FIFO中取出数据,如果FIFO空则返 回一个错误。
FIFO最显著的应用是数据流。例如,在一个数据采集应用中,可以用r t_task_init()和rt_task_make_periodic()设置实时任务使其以固定的 间隔从I/O板采样。这个任务用rtf_put()将数据发送到Linux进程。该 Linux进程应该是一个循环,不断从FIFO读出数据,也许还要写数据到 磁盘、或者通过网络发送、或者显示在一个X窗口中。FIFO象一个缓冲 ,因此Linux进程不必非有实时性不可。 实现数据流系统看起来成为RT-Linux设计者的主要动机。但是FIFO机制 提供了一个实现信号灯的很好方法。两态信号灯可以通过创建一个大小 为1的FIFO来实现,V操作即为rtf_put(),数据内容无所谓,同时忽略 返回的错误。P操作为rtf_get()。计数信号灯可以通过创建大小足够容 纳所期望V操作个数的FIFO简单地实现。由此可见,FIFO机制提供了实 时应用中任务同步所需的大部分功能。当前的实现在RTOS用户习惯的某 些功能上仍有欠缺,比如优先级禁止(防止优先级反转)和任务安全删 除。但是仔细设计几乎总能避免这些问题。此外,虽然FIFO操作可以在 没有数据(读FIFO)或没有空间(写FIFO)时阻塞,语法却相当复杂, 阻塞能力看来不是设计的重点。然而,至少有一个提供FIFO阻塞操作简 单语法的努力正在进行,同时还实现了阻塞超时,这是许多嵌入式应用 的重要特征。RT-Linux简单、开放的设计允许用户相当容易地实现类似 的附加功能。