This article is the first in a series on software development and particularly programming for embedded systems and real-time applications. Future articles will naturally refer to XMOS technology from time to time, so to start things off it makes sense to look at the world of software that XMOS fits into.
Software is an amazing thing. Programming languages are immensely expressive, compilation is quick, there are lots of abstractions and tools for development, and it is quick and easy to update the function of a device. This means that any part in your system driven by software is the most flexible thing in your system – a wonder part.
However, there is one place that software really stinks: fast real-time processing. This is the kind of processing when a task must be completed before some external event, for example, manipulating image data between screen refreshes of a display, or supplying data to external I/O pins based on some fast clock.
Of course, software can be used for this, but all the wonderful ease-of-use and flexibility seems to fall away. Software development becomes hard and difficult to maintain. The problems
So, why does software have problems when faced with real-time or interface driven applications? The problems can be characterized into categories. Problem 1: Multi-tasking
Naturally, a processor is likely to be trying to do more than one task, even for the simplest problem. However, processors cannot generally do more than one thing at once. Even multi-core processors with traditional architectures may be able to do only two or four things at once in hardware.
The problem is that multi-tasking on a naturally single-threaded processor involves the software scheduling tasks in and out of the processor in chunks. From the viewpoint of a single task, scheduling means you do not know when you are in and when you are out making it hard to meet real-time constraints. Problem 2: Interrupts
Even for a “single-threaded” application, the processor is likely to be doing more than one thing at a time. Interrupts provide an implicit form of multitasking. An interrupt firing (to service an I/O handler for example) is the same as a scheduler switching out a task.
Figure 1: Interrupt vs. event.
Problem 3: Lack of Predictability
It seems that software really lacks predictability with regard to timing. Tasks need to run in a certain number of microseconds but there is no guarantee they will. Scheduling and interrupts are only part of the problem. Some microprocessors have a cache for memory access and the time a memory access takes varies depending on the state of that cache. Also, some microprocessors are superscalar so each instruction takes a variable amount of time to execute. This all means that you cannot just count the number of instructions and know how long that instruction sequence is going to take. Problem 4: Lack of resources
When real-time software is used in embedded applications, there tends to be another problem: lack of resources. Memory and clock cycles cost money so there is a drive to get as much as possible from low resource devices. This is a problem for modern software abstractions that tend to view resources as plentiful, for example, memory as an infinite resource. Solutions
One option to avoid the problems of real-time software is to implement it in a hardware solution. If a fixed function part exists with the functionality you want, there is really nothing to do. Alternatively, a re-programmable hardware part like an FPGA may do, providing you have the skills to program it. Even if you do, it is likely that some software tasks are required so you have to integrate the FPGA with a microprocessor, either on the FPGA or on a separate part. This hardware/software division gives multiple design flows and tools, and lacks the tight integration of disparate functionality that software development can provide.
Are there any solutions that provide all the benefits of software development but without the issues that occur when trying to do real-time programming?
One option is to use a real-time operating system (RTOS) – conventional operating systems with extra different features for real-time applications. Firstly, the scheduling of multiple tasks is prioritized and time-aware so the scheduler tries to guarantee that tasks meet their timing constraint. Secondly, the OS is designed so that the worst-case execution time of all system tasks is known, enabling you to do some worst-case execution time (WCET) analysis.
RTOSs on traditional microprocessors, however, provide a pretty heavyweight solution. It is trying to bend something not naturally real-time into a real-time framework. Even if the scheduling is real-time aware and WCET is performed on system tasks, the non-determinism of the processor (cache, superscalar execution) is still there. The upshot of this is that even with a reasonably fast microprocessor, it is hard to do tasks with sub-microsecond constraints due to the overhead of the OS. These kinds of tasks are still traditionally handled with ASICS or FPGAs.
XMOS devices provide a brand new solution that combines the benefits of software with the real-time performance of hardware solutions. XMOS: Designed for real-time
XMOS processors are built from the ground up for real-time processing with fast external I/O constraints. They are designed to combine the best of hardware design with the best of software design. Solution 1: Hardware multi-tasking
XMOS devices handle multi-tasking in hardware, with a set of tasks running on different software threads. Every clock cycle a different thread swaps into context in a round-robin style. This means that you do not have to worry about a scheduler – you can view each thread as an independent entity running at a set speed. It is also a naturally multi-core architecture so adding more cores means that more independent tasks can be run. Solution 2: Event-driven architecture
There is no OS layer on XMOS devices. Instead of interrupts, each thread explicitly responds to events. This approach means that there are no hidden tasks that can jump in and upset the timing of your software. Solution 3: Predictable execution
The lack of OS and software scheduler combined with memory that has no cache (each memory access takes 1 thread cycle) and the use of independent resources for each thread, means that with XMOS you have the predictability required for real-time applications. You know how long an instruction sequence will take statically. Furthermore, XMOS provides a Timing Analyzer (XTA) tool, which accurately gauges the worst-case execution time between two points of code (taking into account multiple paths of control flow, function calls). Solution 4: Managed resources
XMOS devices are designed for embedded applications and, as such, are low-cost and low-resource. The key for the software programmer is managing those resources. The software development tools (standard C compiler based tools with extensions) keep track of resource usage so you know you are not going to run out at run time. If you need more memory, processing power or I/O, simply add another core, as resources are fully scalable.
The tools also ensure that each thread uses only its own resources and cannot interfere with others. Conclusion
This article shows the difficulties of software programming for real-time applications and the motivation behind the design of the XMOS family of devices. The next time you design a system that requires real-time processing and I/O programming, check out XMOS and see how you can combine the benefits of software development with real-time performance.