Embedded Systems

Loosely, an embedded system is a computer system tailored to perform some very specific function, often some kind of control system. With varying stringency, many embedded systems are subject to requirements for timely performance and are therefore referred to as real-time systems. The DT name comes from the common nomenclature of a time derivative, , due to DTSE's experience with real-time software.

Most modern operating systems as well as most real-time systems implement preemptive multitasking, where a running task can be interrupted and replaced by another without the knowledge or cooperation of those processes. The code that performs this preemption and process scheduling is part of what is referred to as the kernel. In general, a task is preempted when

  • There is something else to be done and
  • The running task has nothing to do (e.g., it is waiting for I/O to complete) or,
  • The running task has exhausted the maximum amount of time that the scheduler allows a task to use.

The real-time performance of a given kernel is determined by the following things.

  • The time slice, or maximum amount of time a task is allowed to run without preemption.
  • How the kernel handles interrupts.
  • How the kernel implements exclusion locks for data protection.
  • How I/O affects interrupt handling.
  • How long the scheduler takes to select and switch tasks.

Real-Time Linux

The “current” Linux kernel (2.6) is not immediately suitable for most real time systems, as it is designed primarily for other purposes. The problem can be illustrated with a simple example.

Some real time system designs can be viewed as a set of software processes that run in a predetermined sequence for fairly well known time periods. For example, consider a system that needs to run a fast allocation process or a control feedback process every 20 ms. One might code such a process using a timer signal to wake the process every 20 ms. In practice, using a standard Linux kernel, the process will not run that often. In fact, setting a timer for 20 ms only guarantees that at least 20 ms (and possibly a lot more) will elapse before the process receives its wake up signal.

Another example appears with I/O latency (or more generally, interrupt response latency) time. While a benchmark may provide useful statistics about a given platform’s aggregate I/O performance, it probably won’t reveal the distribution of inter-transfer gaps, which, with a standard kernel, can have very large variance.

Both of these are a result of the way that the scheduler in the kernel works.

Any scheduler has to balance the overhead of task switching with the time that a process is allowed to run. The Linux scheduler envisions dealing with hundreds if not thousands of processes (or threads), tries to “fairly” allocate execution time to each, and is intended to deal with the majority of Linux applications – such as desktop machines and servers. A good basic description of the 2.6 scheduler is available here.

Real-Time Extensions

One approach to this problem is to provide a lean multitasking executive to schedule time critical tasks. Two well known projects implementing such a system are RTAI - the Real-Time Application Interface for Linux and RTLinux. An introduction to real time systems with a focus on this approach can be found in this article.

Kernel Modules

Another way to implement a high priority task is to make it a kernel module. This gives the process access to high resolution timers, and has it run in kernel memory space, which is not swapped. This approach can solve some kinds of real-time requirements, but does not offer the latency guarantees of a fully real-time kernel, because the native interrupt handling system is still in place.