Cover V10, I01
Article
Figure 1
Sidebar

jan2001.tar


Open Source Real-Time Operating Systems

Rafeeq Ur Rehman

A real-time operating system performs its functions and responds to external events, such as interrupts, within a specified period of time. The term "real-time" means that the system responds to events as they occur. Real-time systems play a very important role in daily life. Common applications of these systems include air traffic control systems, telecommunication equipment, routing and switching products, and medical imaging systems. In manufacturing industry, real-time systems control robots used in various automatic processes.

In real-time system terminology, a deadline is a time interval during which a real-time system must respond to an event. Deadline requirements for different real-time systems may vary. In some circumstances, results produced after deadline are not only considered late but are also considered wrong. In other systems, these may be tolerated. Depending upon the strictness of their timing requirements for meeting deadlines, systems are categorized as hard or soft real-time systems. A real-time task is hard if that inability to meet a deadline results in catastrophe. A real-time task is soft when meeting the deadline is desirable, but missing a deadline does not result in incorrect system behavior or catastrophe. Operating systems that can handle hard real-time tasks are hard real-time operating systems. Real-time systems designed to handle soft real-time tasks are considered soft real-time systems. In general, any real-time system must be predictable and must implement some preemptive, priority-based scheduling so that higher priority tasks can be completed while keeping others aside.

General Properties of Real-Time Operating Systems

A real-time operating system should be able to quickly respond to external events. Different techniques are used to carry out this functionality, but more or less all real-time systems have the following properties:

1. Interrupts generated by external devices are served immediately. Interrupt service routines are kept as short as possible so that no interrupt is missed. For example, an interrupt from a serial port usually shows an event of incoming data. If the data is not copied to a buffer immediately, new incoming data may overwrite it.

2. Real-time systems should be small, because they are often used as embedded systems. Small systems are usually more efficient, predictable, easier to maintain, and less buggy.

3. Real-time systems should be predictable and should also be preemptive. A preemptive system immediately suspends a task when a higher priority task needs to be executed. Generally, available commercial UNIX systems, as well as Linux, are not preemptive. I shall describe preemption later in this article.

4. Real-time systems should implement task-priority levels so that important tasks may be executed at a higher priority. Real-time systems should allow changing a task priority during run-time.

POSIX Standard for Real-Time Systems

Portable Operating System Interface for Computer Environments (POSIX) has published a standard for real-time computing as ANSI/IEEE Standard number 1003.1b, which is derived mostly from various versions of the UNIX operating system. POSIX.1b (also known as POSIX.4, Draft 14) is the IEEE-approved standard. It provides a set of real-time extensions to the POSIX.1 basic operating system standard and was approved by IEEE in 1993. POSIX 1003.4, Draft 9, is the 1989 version of the IEEE standard that defines a set of real-time extensions to the POSIX.1 basic operating system standard. This draft is an intermediate draft that has led to the approved POSIX.1b standard.

Why is the Traditional Linux Kernel not Real-Time?

Linux is not designed to be a real-time operating system. The main reason is the non-preemptive behavior of Linux kernel. By non-preemption, I mean that in certain cases, the Linux kernel will not execute a higher priority task even if it is required to do so. This situation arises when a low-priority task is being executed in kernel mode.

There are many tasks or processes running in a Linux box at one time in a time-sharing manner. A task is being executed either in user mode or in kernel mode. For example, when a user task requests some system resource using a system call (such as reading data from disk), it is running in the kernel mode. No process can be interrupted in the kernel, even if a high-priority task needs CPU for an urgent matter. Also when a process enters in the kernel mode, it disables interrupts. As a result, interrupts from external devices may be lost during the processing of a task in kernel mode. This is highly undesirable in systems where time is critical, such as data acquisition, rocket motion, high-speed network appliances, and so on. To make the Linux kernel behave as a real-time kernel, major changes would be required. In fact, it would require nearly a complete rewrite of the Linux kernel, which is neither needed nor desirable.

Linux supports dynamic loading and unloading of pieces of code known as kernel modules. A module, once loaded, becomes part of the kernel. If we could load a magic kernel module that could take over the system and run all Linux native processes as lowest priority tasks, we could make Linux a real-time operating system. This is the approach used by Real-Time Linux (RT-Linux) and Real-Time Application Interface (RTAI). These solutions install modules that take over the system and implement their own task schedulers. Under this new task scheduler, Linux itself (and all other Linux tasks like X-Windows) run at the lowest priority. Now we can run real-time tasks under this newly installed scheduler, which supports preemption. All user programs are scheduled to run only when no real-time task is scheduled.

In a non-preemptive system, interrupts are disabled when a task enters into kernel mode. Now, when a non-real-time user task running under Linux goes into kernel mode, it still disables interrupts using cli macro. It enables interrupts using sti when it enters back to user mode. The RT-Linux installation process includes installation of a patch to the Linux kernel that changes the definition of the cli and sti macros. Although non-real-time tasks think that interrupts are disabled, they actually are not. RT-Linux still responds to interrupts as soon as these arrive. If an interrupt is for a real-time task, it is passed on to it immediately. If the interrupt is for a non-real-time task, it is queued for later processing. This gives us a clean scheme where user processes still run as they were running before, and the kernel responds to real-time tasks in a timely fashion.

The major advantage of this scheme is that the critical part of a real-time application may be installed as a real-time task using the kernel module while the standard Linux GUI can be used to display non real-time data generated by the real-time task, plot graphs in the X Window GUI, and so on. If a new real-time operating system is written, all of the utilities that are available on Linux will never be available on the new system, or at least will take a long time to be ported.

Currently Available Open Source Real-Time Solutions

Many real-time solutions are available as Open Source now. Most of these are based upon Linux. I shall discuss only some of the well-known ones.

RT-Linux

Real-Time Linux, or RT-Linux, was initially developed as an educational project. Basically, it patches the Linux kernel by replacing the cli and sti macros. These macros are used to enable and disable interrupts when a task goes to kernel mode and comes back to user mode, respectively. The cli macro disables all interrupts, and the sti macro enables them. RT-Linux is then installed as a loadable module that takes over the system and installs its own scheduler. The Linux kernel runs as a lower priority task under RT-Linux. Real-time tasks run under the RT-Linux scheduler, while all other user applications still run the same way under Linux as lowest priority tasks. When an ordinary task goes into kernel mode, it clears all interrupts using cli. But the interrupts are not actually cleared, because of the kernel patch mentioned earlier. Instead these are services by the RT-Linux. If the interrupt is for a real-time task, it is passed on to the task, immediately suspending native Linux task. If the interrupt is for an ordinary Linux task (such as movement of mouse in a window), it is queued for the non-real-time task for processing. This scheme guarantees that interrupts are not lost because of a task running in kernel mode.

Version 2.2 of RT-Linux is the most stable version. It provides POSIX Application Programming Interface (API) and supports symmetric multi-processing (SMP). A beta version of RT-Linux 3.0 is also available, which is based on a pre-release test version of Linux kernel 2.4.0. This beta version includes some new features like support for PowerPC, a GDB-like source code debugger, and user-level real-time code using POSIX API. I shall discuss RT-Linux installation later in this article.

RTAI

Real-Time Application Interface, or RTAI, is a plug-in to Linux, according to its Web site. Conceptually, it is the same as RT-Linux. In fact, it is considered an RT-Linux variant. It has the same approach of running the Linux kernel as a lower priority task as RT-Linux does. However, it provides a much richer API for real-time programmers. There have been long debates on real-time mailing lists about which system is better. It depends upon how you think a real-time system should be implemented. Many people think that the real-time system itself should provide absolutely necessary functions in an effort to keep the system simple, small, and easy to maintain. Others think that a rich and well-designed API reduces development time, which is the RTAI approach. More information about RTAI can be found from its Web site mentioned in the resources section of this article. You can download RTAI under the GNU Public License (GPL). Installation instructions are also available on the Web site.

Microcontroller Linux or µClinux

Embedded Linux/Microcontroller Project (www.uclinux.org) is a Linux variant specially designed for microcontrollers. This is a full-featured, Linux-based system for microprocessors without memory management units (MMU). You can download µClinux under GPL or purchase the official µClinux CD from www.uclinux.org or Lineo (www.lineo.com).

Important features of µClinux are:

  • POSIX compliant
  • Supports many file systems including Flash ROM
  • Runs on many processor families
  • Already being used in commercial embedded systems
  • Sample code for Web server and graphic LCD-based GUI available
  • Common network protocols like TCP/IP, PPP are also available
Embedded Configurable Operating System (eCOS)

This is the only Open Source system discussed in this article that is not Linux. Red Hat distributes eCos as an Open Source real-time system under their Red Hat eCos Public License (RHEPL). This license allows you to freely develop and distribute eCos applications. You can also modify the source code according to your needs, but these modifications must be made public under the license. Red Hat also provides Red Hat GNUPro and GNU Open Source development tools. The configuration system enables a user to remove all unnecessary parts of eCos, making its footprint a minimal one; thus, it is suitable for embedded systems. It is royalty free, and you can distribute any number of copies with your system without any cost. eCos supports many platforms: including ARM, Hitachi SH3, Intel x86, MIPS, Matsushita AM3x, PowerPC, and SPARC. Its architecture is based upon a hardware abstraction layer (HAL) that makes it easy to port from one target architecture to another. Key features of eCos are:

  • Full preemptability
  • Implementation of different scheduling policies
  • Tools for embedded applications
  • Development tools like compilers, assemblers, linkers, debuggers, and simulators
  • POSIX compatibility
  • Support for SNMP
  • PCMCIA support
  • Flash support
  • Available on a wide range of processors

If you plan for your real-time system to be an embedded system, eCos may be a good choice.

Lineo's Embedix Real-Time Linux

Lineo provides real-time and embedded solutions. Embedix real-time by Lineo is not a different type of real-time Linux. Embedix combines RTAI with development and debugging tools that can help decrease development time. The current version of Embedix is 3.0, which is based upon standard Linux kernel and RTAI. If you order the Embedix CD from Lineo, you get the following in addition to the general features of RTAI:

  • R2D2 -- Lineo's run-time debugger, which can be used for local and remote debugging. The debugger supports user space and real-time tasks
  • Step-and-trace debugging of kernel modules using gdbstubs.
  • Linux Trace Toolkit -- providing time tracing and graphical display of both non-real-time as well as real-time tasks
  • Embedix real-time Programming Guide, which may be useful for beginners
  • COMEDI -- a toolkit for developing real-time Linux device drivers
  • RTnet real-time networking for Linux
Getting and Installing RT-Linux

RT-Linux can be downloaded from its Web site: www.rtlinux.org. The RT-Linux installation process includes two basic steps:

1. Patching the Linux kernel and recompiling it

2. Compiling and loading RT-Linux modules

Patches for Linux kernel are available on RT-Linux Web site. You can also download a pre-patched kernel from this Web site. After patching the kernel, compilation and installation of the kernel are standard procedure. You can download a clean copy of Linux kernel from www.kernel.org and patch it with the RT-Linux patch. However, I would suggest to download a pre-patched kernel from the RT-Linux Web site to avoid extra effort. The following procedure is for a pre-patched kernel and can be easily modified if you want to patch a clean version of the Linux kernel yourself.

1. Download the pre-patched kernel and untar it after moving to the /usr/src directory. This will create a directory /usr/src/rtlinux-2.2.

2. Remove the existing /usr/src/linux link and recreate it using:

ln -s /usr/src/rtlinux-2.2/linux /usr/src/linux
3. Move to the /usr/src/linux directory using cd command.

4. Build new kernel using "make menuconfig", "make dep", "make clean", and "make bzImage" commands. During the interactive session of "make menuconfig", you should enable kernel loadable module support, because RT-Linux will be used as loadable modules.

5. Use the commands "make modules" and "make modules_install" to build and install modules.

6. Copy the new kernel to /boot directory using:

cp /usr/src/linux/arch/i386/boot/bzImage /boot
7. After the kernel is rebuilt and copied, install it using lilo. Add the following lines to the /etc/lilo.conf file and run "/sbin/lilo", which will enable lilo to boot from the newly compiled kernel.

image=/boot/bzImage
label=rtlinux
root=/dev/hda1
read-only
Note that you must change /dev/hda1 to the partition from which Linux boots on your box. After this step, the first part of the installation process is complete, and you can reboot from this patched kernel by typing "rtlinux" at the lilo boot prompt.

To compile the RT-Linux modules and install these, go to the /usr/src/rtlinux-2.2/rtl directory and use the following command sequence:

make
make install
This will install the RT-Linux modules. To verify the installation process, reboot the system and use lsmod to find the loaded modules. The output of lsmod will show you modules, such as rtl_fifo.o and rtl_sched.o. Refer to the resource sidebar where a link is provided for more details on RT-Linux installation. Detailed instructions for installation are also available on the RT-Linux Web site.

Programming Considerations under RT-Linux

Programs written for RT-Linux are run as loadable modules. RT-Linux provides pipes that can be used to communicate between a real-time process and a non-real-time user process running under native Linux. If a real-time process does not require any storage or processing of data, it can be implemented as a kernel module only. However, if a real-time task does need storage or processing of real-time data, it can be passed to a user process using RT pipes. For example, if you want to plot and save real-time data received from some external source, you can split it into two parts. The data acquisition part may be implemented as a real-time task that gets data and copies it to pipe. A user task running under native Linux can read data from this pipe and plot it in the X Window GUI and store it to disk. This process is shown in Figure 1.

While writing real-time code for RT-Linux, keep the following considerations in mind.

  • Use of memory allocation functions like malloc() is not recommended in hard real-time systems programming. These functions need a memory manager that may spend a large amount of time in copying data from one place to another if the desired amount of contiguous memory is not readily available. The memory manager moves already allocated memory to create a contiguous memory space that may result in unpredictable behavior of the system. All memory needed for a real-time task should be statically allocated at the time of creation of the task.
  • All real-time tasks, and especially higher priority tasks, should be as small as possible.
  • A programmer should try not to have multiple tasks with the same priority. In this case, there will be time sharing between these tasks that may affect the predictability of the system.

You can find examples of real-time code with the RT-Linux distribution. Some of these programs are written to test correct installation of RT-Linux.

RT-Linux Applications

Linux is already being used in a number of real-time data acquisition systems. The wide popularity of Linux makes it suitable for modern networking and telecommunications products. In fact, some companies already have Linux-based routing and switching products on the market. Linux can be reduced to a very small footprint (as small as 1.44 MB floppy disk) that makes it suitable for embedded real-time applications. The royalty-free nature of Linux real-time solutions makes them suitable for mass production. The future of Linux-based real-time products is bright, as companies don't have to pay expensive royalties to commercial real-time vendors. Now people do have an alternative to commercial and expensive real-time solutions.

Rafeeq U. Rehman received Bachelor's and Master's degrees in Electrical Engineering from the University of Engineering and Technology, Lahore. He is author of many articles on Linux and a book on HP-UX system and network administration. His interests are network management, security and C programming. He can be reached at: rurehman@yahoo.com.