When design engineers step into the embedded world for the first time, they may feel like a country boy entering downtown New York City. They’re not in Kansas anymore. The embedded programming landscape can be as intimidating to the design engineer as Gotham City is to Toto.
There are scores of locals (experienced developers), tourists (journeymen programmers), and country boys (beginners) creating all sorts of embedded applications such as engine controllers, signal processing systems, game consoles, industrial automation systems, and so on.
Of course, all embedded developers, experienced and green, are working with New York-minute time constraints, trying to get their products or prototypes done faster and with higher quality. At the very least, experienced developers look for computational and programming models – and software tools – that don’t get in the way.
At most, beginners pin their hopes on the rapid development and code generation features of a tool to provide a competitive advantage. Just as the farm boy might find solace in a country radio station, new embedded programmers with other types of expertise look for familiar ways to translate their expertise into embedded ones and zeros.
It turns out that some very smart people are investigating ways to help designers use familiar methods to go from concept to embedded reality. University of California at Berkeley researchers are studying which “models of computation” are best for representing real-time embedded systems (see http://ptolemy.eecs.berkeley.edu).
“Model of computation” is an academic term for a particular way of representing the behavior of a system, such as the finite state machine seen in Figure 1, below, or a dataflow representation. A particular model of computation may better reveal execution characteristics of the system.
|Figure 1. A Finite State Machine|
Practically speaking, embedded developers can use the models of computation concept in a broad fashion to span multiple ways of representing and programming an embedded system. To frame this discussion, consider the definition of a model of computation as containing aesthetic properties (i.e., how it looks) and execution properties (i.e., how it runs).
Different programming models are valuable to engineers approaching an embedded design from different perspectives. For example, mobile phone designers benefit from a programming representation that can demonstrate concurrent operations such as signal processing, filtering, user interface event callbacks, and so on. Likewise, an engineer designing a control unit for a dynamic system such as an engine benefits from a programming model that simulates continuous time during execution.
The two designers could even use the same hardware in their designs because multiple models of computation help the phone designer and control designer use programming representations that emphasize the system characteristics with which they are most familiar.
Examples of Programming Models
An extensive discussion of the various models of computation is beyond the scope of this article; instead, consider some of the basic types of models that apply to embedded development.
For example, for an embedded safety system designer, a finite state machine (shown in Figure 1) offers a valuable representation of the system. The designer can define exactly what state the system is in depending on various inputs to the system and previous state information. Finite state machines represent sequential logic in an intuitive way that makes it easier to avoid unintended behavior.
While finite state machines are helpful to the safety system designer, signal processing engineers typically think of their systems in terms of data. For this reason, these designers can use dataflow programming models as intuitive representations. Dataflow programming models specify execution according to when data is available to a particular function.
Shown in Figure 2, below, in the LabView diagram of the data flow for an FPGA, where the I/O function acquires data from an external I/O line, wires represent the flow of data from the I/O function to the filtering function. The dataflow programming model in this example specifies that the filtering function does not execute until the data input is available.
|Figure 2. LabVIEW Data Flow for FPGA|
Conversely, a mobile phone embedded system designer must implement parallel signal processing and user interface interaction simultaneously. In this case, the designer would benefit from a programming model that can represent concurrency. Whereas a text-based implementation would require a substantial amount of code to implement multiple threads for concurrent processes, graphical programming models can represent parallel operations in a natural fashion.
Figures 3 and 4, below, show two programming models that represent concurrency well, a dataflow model with parallel loops, and a Unified Modeling Language (UML) statechart.
|Figure 3. LabVIEW Parallel Loops|
A statechart is a programming model that expands on the finite state machine to enhance its value. By adding special states such as an and-state, a statechart can represent parallel tasks with a state machine.
|Figure 4. UML Statechart with Orthogonal State Machines|
A control designer needs a programming model that simulates continuous time to accurately represent physical systems. To simulate continuous time, the model must be able to find sets of linear equations that approximate system response within a give time constraint.
The most common representation of dynamic system behavior is the control block diagram, such as is used in the The MathWorks Simulink tools and the LabVIEW Simulation Module. As shown in Figure 5, below, this programming model displays the mathematical relationships between inputs and outputs as a designer would see them during development.
|Figure 5. Control Block Diagram|
Going from Concept to Zeros and Ones
For high-level programming models to be truly useful, they must eventually make their way onto hardware. This notion is becoming reality as more software tools offer the ability to generate code that engineers can deploy to an embedded prototype or even the production system.
While this ability is not completely new, there is significant momentum that is improving the performance and footprint of the embedded code generated by high-level tools. Additionally, with the right software tools, engineers can now take their designs to alternative hardware targets, such as DSPs and FPGAs, that offer compelling features and performance.
A Multiple Models of Computation Vision
Bridging the gap between designers and the embedded world isn’t an easy task, but multiple models of computation in a software tool are the key.
As the examples of state machines, data flow, and continuous time models show, a software development tool can mix and match models to generate the right embedded solution for any application and hardware target.
The vision of one software tool flexible enough to provide many models of computation to designers is tantalizing. Imagine a world where designers with different expertise can use their favorite models of computation to generate code that can seamlessly integrate with code generated by their counterparts using a different model of computation.
Gerardo Garcia is real-time product manager at National Instruments, Inc.