News & Analysis
Successfully Using Linux and Open Software in an Embedded System Design
Greg Rose
6/10/2002 12:00 AM EDT
Fueled by time-to-market pressures and the need to reduce overall system cost, many developers are migrating to Linux and open-systems software in their embedded systems designs. This open-systems approach allows developers to leverage freely available software, and spend their resources on their specific area of expertise to add value to their products. Embedded systems present unique design challenges such as: memory restrictions, booting from flash, diskless operations, and requirements for deterministic operation. There are some real challenges that face an embedded designer who wishes to use Linux in his product. This article presents questions developers should ask while planning embedded designs, how Linux stacks up, and how to overcome some of those challenges.
Is the operating system available for the desired microprocessor?
There are several criteria used to evaluate and choose an operating system for an embedded system or product: availability, resource usage, software available, feature set, reliability, and performance. Simply whether the operating system is available for the chosen embedded microprocessor can be the major decision factor. Because of the short time-to-market of many of today's embedded products, a port of an operating system to a new CPU or processor board may take too long. Having an operating system that already runs on the board saves the time and the expense of porting it.
The good news is that Linux has been ported to many different embedded microprocessors including the PowerPC, MIPS, ARM, StrongArm, and SH. The bad news is that these ports of Linux do not yet enjoy the amount of third-party software that the x86 port of Linux has. Now that there are vendors for embedded Linux making periodic releases of their Linux distributions for non-x86 platforms, the situation should improve. A growing number of third-party software vendors have pledged support for Linux on a variety of embedded processors. But customers provide the strongest motivation. Inquiries about the availability of an application, or protocol stack, for Linux on a specific processor may speed the porting processes.
Can the operating system support headless and diskless operation?
Embedded systems rarely have a computer operator and most run as headless systems, meaning that there is no operator interaction required to start and run the system.
Making a headless Linux system is not too hard. The console device can simply be a null device. There is no operator interaction required if the startup scripts simply start the application programs instead of login processes. Monitoring can be done remotely if needed by setting a pseudo TTY as the console once a remote login is established. Linux does support graphical user interfaces with X-windows. But X is strictly optional and not required for the operating system to run.
The problem of running without a disk can be solved in a few ways. There exist Flash memory devices that emulate IDE disk drives. These devices can be physically very small, not much bigger than the IDE connector itself. Linux also includes a RAM disk driver. This is a device driver that uses some amount of available system memory to emulate a disk drive. A RAM disk can be used for data files that do not have to be persistent across a system reboot. It is also possible to use the RAM disk driver to access a file system in ROM. If the embedded system has Flash memory that does not emulate an IDE drive, a flash file system can be used to treat the flash memory like a disk. A good flash file system will use wear leveling to keep flash block erases to a minimum.
Can the OS Operate With Limited Memory?
All operating systems require some resource usage in order to operate. The main resource required is computer memory. Some operating systems have a larger memory "footprint" than others. In embedded systems where both RAM and ROM is a precious resource, an operating system with too large a footprint must be ruled out.
The solution to the memory footprint issue of Linux is through careful configuration of the Linux kernel. The Linux kernel is modular, and to a certain degree unused kernel facilities can be configured out. Also, kernel resources can be configured such as the maximum number of processes or open files on the system. By configuring the operating system modules and resource, the size of the ROM and RAM footprint can be reduced. It is possible to configure an "off-the-shelf" x86 Linux kernel to be 259K uncompressed. A minimal ROM disk to provide a file system for this kernel can be as small as 102K. The total RAM usage can be under 4 Mbytes. A Linux capable of TCP/IP networking is larger. The kernel with networking configured is about 370K, and the required ROM disk is 740K (both uncompressed). RAM usage in this configuration of Linux is under 8 Mbytes. This is not as small as an embedded RTOS can achieve but small enough for many embedded devices.
Are there software development tools for embedding the operating system? Is the operating
system compatible with other application software needed?
When developing embedded applications, developers must use software tools such as compilers and debuggers and these tools cannot commonly run on the embedded target due to resource constraints. Embedded development requires running the software development tools such as a compiler, assembler, and linker on a host computer then downloading them to a target computer for execution. The host and target may have different CPU types. In such case a compiler and assembler intended for native use cannot be used as a cross compiler and assembler. A cross compiler will have to be built or acquired that can run on the host and create machine code for the target.
Embedded operating systems, like desktop and server operating systems, are many times chosen not for their feature set but for the software available to run on them. Many people run the Windows operating system on their desktop computer because they can get the word processors or spreadsheet programs they need to use for Windows. Embedded systems designers need software beyond the operating system. They require protocol stacks, middleware, device drivers for special hardware, and sometime the actual application software. Whether or not this software is available for the embedded operating system they are considering without the need of porting is a very strong factor in their operating system choice. The feature set of an operating system becomes an important factor if the application software is going to be developed for the embedded system and is not already available. The availability of a certain feature may reduce the software development time. Of course, software that needs to be ported has been written assuming some set of features of the underlying operating system. If those features are not available, it may mean a long and costly port.
For cross development, the popular GNU compilers can be used. If the host and target CPU byte order is different such as an x86 host and a PowerPC target, sometimes bugs will surface. When using cross development, some method of downloading a kernel image to the target must be chosen. If the target can access a disk drive (and can boot from disk), the drive can be mounted on the host computer to write the kernel and file system and then moved to the target for booting. If the target can boot an operating system over a network interface, the host computer can simply run a boot server and a file server and the target can do a network boot. However, if the target can only boot from ROM or Flash memory, a special utility may be required to create a single load image given a Linux kernel and a file tree.
The easiest way to get a workable cross development environment for Linux is to pick up one of the Linux distributions designed for embedded use. These distributions have pre-built cross tools for several embedded processor types. Any byte order related bugs have usually been fixed. These distributions typically include booting code for the target as well as tools to configure and build Linux runtime images that can boot over the network or from Flash.
Cross development also requires cross debug support. In a cross debug environment the debugger runs on the development host. The debugger included on Linux distributions is GDB, the GNU debugger. GDB can run native or cross. In native mode GDB executes or attaches to the executing application to be debugged. GDB then can examine the variables and data structures of the application program or library through the /proc interface. GDB can also trace the program, be notified of signals being sent to the executing program, and send signals itself. GDB reads the symbol information from the executable file of the program and can also display the source from the programs source file. In a cross debug environment the debugger executes on the host development computer, and the application program runs on the target computer. The debugger reads the source and executable file on the host to get source code and symbol table information. The debugger communicates to an agent running on the target in order to examine variables and data structures and to control the process being debugged. The agent for GDB is the GDB Server and it is a lot smaller than GDB itself. GDB communicates to the GDB server either through a TCP/IP connection or through a raw serial connection.
The Linux kernel and device drivers cannot be debugged the same way as a user application. Setting a breakpoint in the kernel or otherwise stopping execution of a process while it is running in the kernel would cause the debugging agent to stop. Complete debug ability for the Linux kernel and device drivers is not supported in most desktop distributions of Linux. Some embedded distributions do support full kernel debugging. In this case GDB attaches to a debugging agent in the kernel usually through a low-level serial connection. This way the kernel or a device driver can be single stepped or breakpoints used even in interrupt routines. The only thing that cannot be debugged this way is the kernel debug agent itself.
Not only is the source code to Linux free, but runtimes of Linux are royalty free. For high volume embedded systems with tight per unit cost constraints, having no royalty payments for the embedded operating system is very attractive. It saves money that would go to royalty payments and eliminates the overhead for keeping track of the number of runtimes shipped.
The programming interface for Linux is UNIX. A major reason Linux has so much software available for it is that Linux uses the UNIX application programming interface as well as UNIX object and executable file formats. Much of the public domain and open source software of the last two decades has been written for UNIX and is now available for Linux. Also, third-party software developers have been providing products for flavors of UNIX for years such as AIX from IBM, Solaris from Sun Microsystems, and HP/UX from Hewlett-Packard. It was a simple matter for these software vendors to port their products to Linux. This also means that there are programmers experienced on writing UNIX software that already have the expertise to write Linux software.
Because of the popularity of Linux, there are already several software vendors that provide releases of Linux aimed at embedded systems. These vendors typically offer technical support programs for Linux that is geared toward embedded system development. This support includes bug fixes for Linux versions that may be years old and help with ports to embedded devices.
Is the operating system reliable enough and does it meet performance requirements?
Reliability and performance are two features of an operating system that usually cannot be augmented with application or library level software. Running reliable application software on an unreliable operating system simply makes the application unreliable. The reliability of an operating system is based on how well it was conceived, designed, and coded. Most embedded systems require a higher level of reliability than desktop systems. So choosing a reliable operating system is important. Of course, all operating system vendors claim that their operating systems are reliable, so an evaluation is often necessary to discern the facts. Performance can also be benchmarked. It is usually straightforward to determine if the operating system can meet the embedded systems throughput requirements. What is harder to determine is will the operating system meet the real-time requirements. Real-time performance can be benchmarked, but usually the difficulty lies with determining the real-time requirements of the embedded application. The real-time characteristics of system software can vary greatly as the system is put under load. All too often it is discovered that an operating system was the wrong choice because it could not meet real-time requirements that are not discovered until near the end of product development.
There are several ways to deal with the problem that Linux has poor real-time performanceignore the problem, or run real-time applications under an RTOS with Linux itself as a separate task as in the case of RT-Linux, or run a Linux compatible RTOS kernel instead of the Linux kernel. The most popular approach is to ignore the problem. In most cases embedded developers have a problem identifying their real-time requirements at the beginning of a project anyway. This method my work if the application has extremely loose real-time requirements. If it is discovered that Linux is not meeting a real-time requirement then one of the other approaches can always be taken.
There is certainly a set of real-time applications that can benefit from the RT-Linux approach. Machine control, process control, and instrumentation applications where the real-time application code is a small part of the entire application software should run under RT-Linux fine. Using RT-Linux is a much better approach than ignoring real-time requirements.
Some real-time applications do not fit the RT-Linux model well. Data acquisition to mass storage, telephone call setup or any requiring a real-time database, any application where the real-time part of the software is large or not easily separated from the code that needs a Linux environment. The problem is that tasks running under the real-time executive do not have access to the Linux facilities, device drivers, etc. And tasks running under the Linux kernel and can access the facilities are not real-time. As programmers apply the RT-Linux type dual kernel approach to applications where it is not a good fit the number of facilities in the real-time kernel will undoubtedly increased. At some point the real-time executive will no longer be small and simple, and as it adopts more of the facilities of the non-real-time kernel the question of whether the non-real-time kernel is required comes into doubt.
The advantage of the replacement kernel approach is that there would not be a limit on the size or complexity of the real-time application code. Third party software not originally envisioned for real-time use could be invoked by real-time tasks. Programmers who understand Linux would already be experts in the real-time environment because the programming interface would be the same.
What does GPL mean to the embedded Linux developer? If you take the Linux kernel or any Linux utility and modify it, port it, or add features to it, you must post your source to the Internet or ship the source to anyone who asks for it. If you are not careful you may give up the rights to your proprietary software unintentionally. It is best to consult your attorney on all open-source copyright issues.
It is OK to ship Linux in a hardware device being sold. If any modifications to the Linux kernel, libraries, or utilities were required, the sources for the modified version must be made available free. Application programs that run under Linux may remain proprietary. Just be sure no part of the application is GPL (or other open source license) code. Device drivers can also be kept proprietary. They must be shown to be separate and distinct from the Linux kernel. This is most easily done if the device driver is written as a loadable kernel module. If it is linked as part of the base kernel it is in the gray area of whether it becomes GPL or not. If in doubt consult your intellectual property attorney.



