Introduction
Development cycle
System elements
What's prototyping
Goal of prototyping




Forms of prototyping
Prototyping options
Prototyping tools
Viper
Conclusions



product sheet
press release



MIXING THE REAL WITH VIRTUAL: PROTOTYPING IN EMBEDDED SYSTEMS DEVELOPMENT


1. Introduction

here is no clear definition of what an embedded system is — it may vary in size from a single chip to a large multi-processor system and in functionality from a trivial communication port controller to an aircraft guidance system. What is true most of the time is the richness of the mixture of engineering knowledge necessary to successfully complete embedded projects. Unlike may other projects, they usually require fairly broad, if not necessarily very deep expertise, combining hardware and software, from power supplies and analog design, through digital logic design, low-level driver software, to high performance real-time operating systems and communication protocols. As a result, embedded systems present a unique challenge to a developer or a development team. They may have to wear many different hats along the way and sometimes be forced to deal with problems that are not necessarily their most favorite or strongest areas of expertise. Hence it is important for embedded systems developers to try to use the best approaches available within each of the areas they have to deal with during development. Since most systems are developed under realistic (and usually tight!) budget constraints this does not mean going out and buying the best tools in each area. In practice it could mean using some techniques that will produce a reasonably optimal and reliable solution without spending a fortune or becoming a guru in every area.

In this paper we briefly analyze the applicability of prototyping to some of the areas an embedded systems designer might encounter. We will review the development areas suited for prototyping, the prototyping approaches and tools available and their potential benefits and pitfalls. We will also review one user interface prototyping tool — the Viper™ from Signum Systems — in more detail.

2. The Embedded Development Cycle

The development cycle in embedded systems varies. It may be highly structured, with rigidly divided phases, resembling the waterfall model of software development. It may also be evolutionary, developing the new project on the basis of other existing projects. Finally, it may also be completely chaotic, emerging as a result of an extended brainstorming session. All approaches have been known to work very well or produce disasters. Regardless of the methodology, however, all areas of the system will have to be addressed at some point during development. Hence, we will ignore the development methodology used and simply examine a hypothetical system element by element.

3. Elements of the System

In this section we will review the basic elements of an embedded design The elements chosen do not constitute an exhaustive list — that is impossible. They do present, however, a collection likely to cover many of the designs encountered in engineering practice. Given these elements we will be able to discuss prototyping options for each of them.

3.1 Software Elements
Almost every embedded system will have a significant software component responsible for controlling some hardware and providing the onboard intelligence of the product and handling of interfacing with the outside world. The software components of the system are of two general flavors: off-the-shelf and custom. The off-the-shelf portions usually consist of system software components, such as low-level hardware interface layers (e.g. BIOS's), real time operating systems (RTOS's), operating systems (e.g. embedded DOS), and task-specific libraries (e.g. communication or image-processing libraries). The custom portion of the software is usually responsible for tying everything together and supplying any functionality not covered by ready-made components.

3.2 Hardware Elements
The hardware elements of an embedded system are almost as varied as the systems themselves. Certain general categories can, however, be outlined. First, most embedded systems will have some processor (e.g. a microcontroller) responsible for executing on-board software controlling the system. Second, all systems will require some sort of a power supply and an associated power management section, varying from a simple regulator to a smart battery charger system. Third, many systems will require some form of an interface to communicate with other devices, for example serial communication ports or data acquisition channels. Fourth, any system required to interact with human users will require a user interface — be it a single push button and an LED or a set of virtual reality goggles.

In summary, we have distinguished the following basic embedded system elements:

  • Software
    • system components
    • custom components
  • Hardware
    • processor
    • power supply
    • external interfaces
    • user interface

In principle, all of the elements we have just outlined lend themselves to prototyping. In practice, however, not all options may be available. Before we consider these options lets talk a little bit about prototyping.

4. What is prototyping?

The easy answer is something like: “rigging things together so they look like the real thing without actually doing the real thing”. Sounds a bit ad hoc, but it actually covers most of the story. Lets look at the second part of that answer, which addresses a different question:

5. What is the Goal of Prototyping?

The goal of prototyping is to achieve a system functionality identical to the desired system or as close to it as necessary in key areas determining system performance and cost prior to committing to a final solution. What this means is that during prototyping we modify the design to get a decent approximation of the real system at (hopefully) a fraction of the cost. This approximation may be a goal in itself, for example for the purposes of evaluating a design. The design modifications (or shifts) performed during prototyping can take on different forms, each leading to a different form of prototyping.

6. Forms of Prototyping

  • A prototype may implement a limited functionality of the final project (a functionality shift).

  • A prototype may implement the desired functionality, but use a method different from the one available in the final project (a domain shift). An example of a domain shift prototype is implementing the system software on a PC instead of the microcontroller.

  • A prototype may implement the full functionality of the design without meeting the final performance criteria (a performance shift).

Given event the most rudimentary dissection of an embedded system into its components performed above and these three basic forms of prototyping it becomes immediately clear that we have quite a few choices. Any form of prototyping could potentially be applied to any of the software and hardware components of a system. Later on we will review the choices available for each element in more detail. Now, however, we will examine what issues should be considered when choosing elements to be prototyped.

  • First, we would like to get maximum effect at minimum cost, i.e. we should prototype the most critical elements first, i.e. the elements that will contribute most to the overall feasibility of the project, its cost and its performance.

  • Second, most of the time parts of the system are not entirely independent — modifying one part may result in modifications elsewhere. Ideally, we would like to avoid starting at the end of a chain of dependencies, where a later change in some element at the beginning of the chain will render our results irrelevant. Hence, we should try starting with most independent elements first.

  • Third, we want to prototype, not to end up doing the same thing twice. This means that whatever prototyping decisions we make we should try to keep a fairly smooth transition path from the prototype to some final solution. Above a certain effort a prototype stops being a prototype — we must keep the cost in mind!

Having reviewed prototyping basics we can now discuss the specific options available for each of the components of an embedded system.

7. Embedded System Component Prototyping Options

Each element of an embedded systems could potentially be prototyped, using any of the forms described above. We will now consider each element of the system and review its potential for prototyping. In each case we will provide a few examples of various prototyping approaches. They are by no means exhaustive and we expect our readers will have many examples from their own experience to relate to.

7.1 Software

7.1.1 Software Elements

  • Functionality shift prototyping

  • A different implementation of a system software layer could be used. For example, to test the basic functioning of a file transfer protocol we may not need that fiber-optic interface driver — a simple serial port driver might do the same job. We may also forgo some of the non-essential functions and initially substitute "stub" implementations.

  • Domain shift prototyping

  • It may be possible to use a proven implementation running on a different platform. For example, instead of fighting somebody's unfinished TCP/IP stack on a new microprocessor we can try our interface module using a well-tested UNIX or PC implementation. In some cases it may be worthwhile to introduce a "redirection" layer intercepting all requests in our domain and forwarding them to another one.

  • Performance shift prototyping

  • We may use a software layer with a similar functionality but different performance. If, for example, a bi-directional parallel port driver for our target platform is not yet available we may be able to proceed with the development using a serial port instead.

7.1.2 Custom Components

  • Functionality shift prototyping

  • There is almost no limit when it comes to reducing the functionality of custom software components. Since we have complete control over the software we can easily control what functions get implemented and how. Commonly used prototyping approaches include "stubbing" of certain functions, forwarding requests to other, similar components or functional simulation. The functional simulation approach can provide the added advantage of turning a non-deterministic system (e.g. one reading a variable analog signal) into a deterministic one (e.g. one returning simulated readings from a prepared table or disk file) for the purpose of testing and validation. Oftentimes functional simulation options are left in the final design.

  • Domain shift prototyping.

  • Many custom components can be successfully implemented and tested on a different platform, for example a PC. This approach may give us the ability to work with better, faster tools. It also has the added benefit of forcing us to avoid introducing direct system dependencies unless absolutely necessary and thus keeping the code "cleaner" and more portable.

  • Performance shift prototyping.

  • Performance shifting is a trivial yet often overlooked aspect of prototyping. How many times have weeks been spent trying to get that DMA controller going at its supposed full-blast X megabytes-per-second only to later find out that the system never really sends more than a few hundred bytes per second anyway? Whoever said, "make it work right first, then make it work fast," had a point worth remembering.

7.2 Hardware

7.2.1 Processor Section

  • Functionality shift prototyping

  • The functionality tradeoffs available in the processor section of a design are highly design-specific. They may involve forgoing the use of some of the important but easily separable features, such as watchdog timer support or sleep modes — both very useful but prone to cause debugging headaches. It may be much easier to get the kernel software running before we start debugging that banked memory database system. In some cases it may be possible to use an in-circuit emulator (ICE) to provide some of the resources not yet functional in the design. Most better in-circuit emulators will provide mappable data and code memory, so that all or selected areas of the memory can be made to reside in the ICE instead of our target. Similarly, a ROM emulator, such as Grammar Engine Inc.'s PromICE may provide the functionality of a ROM chip with the added benefit of easy content modification via an external interface.

  • Domain shift prototyping

  • Domain shifting of the processor section is not limited to simply porting the code to another CPU. There may be many variations of the same CPU that could be used to develop our system. They may range from a functional simulator through a cycle-level simulator, a simple evaluation board, an in-circuit emulator to the actual hardware. Using this approach may help avoid resource bottlenecks (everybody trying to share the same prototype) and allow for different parts of the system to be worked on at the same time. The biggest obstacle to applying this approach is oftentimes the lack of tools handling all these incarnations of a single CPU. The Chameleon Debugger™ from Signum Systems effectively addresses this issue by being able to work with all types of targets.

  • Performance shift prototyping

  • Performance shifting of the processor section is likely to be helpful in isolating hardware and software problems. We do not want to delay the development of the software just because we have a timing problem with some of our memory-mapped I/O. Reducing the clock speed by half may allow the software development to go on and let us finish the project on time.

7.2.2 Power Supply Section

  • Functionality shift prototyping

  • Functional prototyping of the power supply section may involve simulation of functions related to battery monitoring and charging.

  • Domain shift prototyping

  • The power supply section is usually very heavily prototyped — that's what we do every time we use a laboratory power supply instead of the real thing!

  • Performance shift prototyping

  • The required performance of the power section may be hard to predict without prior knowledge of the characteristics of the rest of the system. It may be necessary to start with an oversized design, test the complete system and modify it as needed.

7.2.3 External Interface Section

  • Functionality shift prototyping

  • External interfaces may vary widely in their complexity. It may be possible to use a simpler version of an interface or forgo some of the complex feature during early stages of development.

  • Domain shift prototyping

  • In case of external interfaces domain shift prototyping may involve what the interface is intended to communicate with as opposed the interface itself. It may be worthwhile, for example, to develop a simple PC-based digital-to-analog conversion system to simulate the voltage output of a pressure transducer observing a particular pressure wave instead of trying to generate the right pressure wave. This approach may also provide better testing and validation opportunities. Some debugging tools may provide an interface option not available in a standard system. An example of such a system is the Analysis Interface channel of Grammar Engine Inc.'s PromICE — a virtual serial communication channel accessible as a memory-mapped window within the address space of an emulated ROM chip. Such an interface may be used as a temporary substitute for an unimplemented portion of the final system or a debugging and testing communication channel.

  • Performance shift prototyping

  • Reducing the performance of an external interface may allow for it to be effectively simulated. Instead of reading an analog-to-digital converter in real time we may be able to feed simulated readings from another source over a serial communication line.

7.2.4 User Interface Section

  • Functionality shift prototyping

  • User interfaces are oftentimes the most visible portion of an embedded system and they may end up being responsible for the end user's perception of the entire system. User interfaces are likely to evolve as system development progresses. In many cases the initial incarnations of the system may not have all the elements necessary to implement the user interface. The initial user interface may consist of just a few LED indicators and the RESET button.

  • Domain shift prototyping

  • Two common approaches of domain shift prototyping of user interfaces are substitution and simulation. Substitution of a user interface by that of another system, for example another device's front panel, provides the developer with an easy way of getting some form of an interface very quickly. It may not be a perfect match, but it does provide the opportunity to test some basic ideas and the overall flow of user interaction. Simulation of a user interface may provide a better approximation of the final appearance of the final interface. The interconnection of the simulated interface to the actual system hardware and software may, however, be tricky. The Signum Systems Viper system addresses provides a comprehensive solution to the problem of user interface prototyping and will be discussed later on.

  • Performance shift prototyping

  • Some performance limitation of user interfaces may occur during simulation. We will discuss it more detail while reviewing the Viper system.

8. Prototyping Tools for Embedded Systems

Having described some of the prototyping options available to embedded systems developers we will now consider the tools that he or she might use during this process. There are some tools specifically aimed at prototyping — we will examine one of them in more detail. Many of the general embedded systems development tools, however, can be successfully applied to prototyping.

8.1 Software Elements

Some debuggers are capable of supporting different code execution environments — from simulators to in-circuit emulators. Such a capability allows the system development to proceed more smoothly. Software development can begin before any actual hardware is available, using a simulator or an inexpensive evaluation board. Once hardware is available, development can shift to an in-circuit emulator. Once completed, the designers may have the option of incorporating a debug monitor into the final product allowing the debugger to communicate with the final system for testing purposes. The Chameleon Debugger from Signum Systems provides all of the above capabilities.

8.2 In-Circuit Emulators

In-Circuit Emulators (ICEs) are natural prototyping tools. By their very design they are intended to allow a developer to access and manipulate objects that cannot be accessed in a standard system. An ICE provides an excellent software development vehicle — it is the ultimate processor simulator. It executes native code, at real speed while providing real-time trace information and specialized hardware for the purpose of tracking down critical or erroneous code sections. Most good ICEs are capable of executing code without a target — they can provide their own memory, power and clock. Sections of memory can be mapped to reside in either the ICE or the user's target (if one is connected). Some ICEs, such as Signum Systems USP-51 series, provide dual-ported memory, which can be modified while the target processor is running. ICEs can be used to prototype other system elements, besides the CPU and memory. The dual ported memory can be used to simulate memory-mapped peripherals. The real-time trace buffer in combination with the debug logic can be used to capture the values written to a certain memory location, which, again, can act as a memory mapped peripheral. Even the simplest system without dual ported memory capable of a single breakpoint can be used to stop the CPU just before it is about to read a prototyped (i.e. nonexistent) peripheral register, place the desired value in that memory location and restart the CPU. The above three-step transaction can be automated by using a command macro — a simple yet powerful facility available in many systems.

8.3 ROM Emulators

ROM emulators, while much more limited than ICEs, can also provide rudimentary prototyping functions. Some ROM emulators, for example the NetROM from Applied Microsystems or the PromICE from Grammar Engine Inc. provide a serial communication channel (a "virtual UART") mappable within the address space of the device being emulated. This channel can be used to simulate a future hardware channel or as an additional debugging channel.

9. Viper

In this section we will examine in more detail the Virtual Interface Panel Environment (Viper) prototyping tool from Signum Systems. Viper is a tool that allows embedded systems developers to quickly develop custom user interfaces for embedded applications and embedded development tools.

The primary goal of a user interface is to provide a human operator with a way of visualizing and manipulating the internal state of the system. In order to accomplish this task a user interface must (obviously) have a way of communicating with the system. This is where user interface implementations become time consuming — they have to take care of all the details of reading and writing I/O ports, scanning keyboards, multiplexing displays etc. During development, however, most systems work with some sort of a debugger — be it a simple monitor or an in-circuit emulator (ICE). The debugger provides an excellent communication channel to the system. Moreover, it usually supports source-level debugging, hence it is aware of source-level data objects, i.e. it knows the location of data structures and variables in the user's code. Knowledge of the source code and the ability to manipulate the corresponding physical memory objects makes a debugger an excellent user interface communication channel. Instead of the struggling with a keyboard-scanning section of code the developer can presume that the code (not yet written) somehow places the value of the key being pressed in a variable and concentrate on the rest of the code. The Viper tool takes care of the rest by eliminating the need for hardware prototyping of user interfaces and using Signum Systems' Chameleon debugger to connect the users' actual hardware and software with virtual user interface objects.

9.1 A Sample Session with Viper
Here is a typical Viper scenario: we have just started a new project. We are not yet sure about the user interface, but we already have some running hardware and software. We are developing software in C, debugging it using Signum Systems' USP-series ICE. George, our boss has come up with the following sketch of what the user interface might look like:

We are not terribly impressed, but we go ahead and write the software to support it. We do not worry, however, how the value to appear on the display actually gets there, how the progress indicator gets activated or how the power switch is read. We just assume that they are read from and written to from some variables, as they will be once our hardware is completed. For now, however, we want to concentrate of WHAT the system does, not HOW it does it. Lets assume that values to be displayed and read are declared as follows:

    int displayVar;   /* display value */
    int progress;     /* progress (0/1) */
    int powerOn;      /* read-only switch position */

Instead of spending time building a mockup of a hardware interface panel we use Viper. We start by creating a blank Viper panel:

 

 

 

 

The icon in the lower-right corner indicates that the panel is still under construction. We drag-and-drop the controls we need and place them on the panel roughly where George wanted them:

 

 

To make him even happier we take his sketch, digitize it and use it as a background for the panel:

 

 

He can't say we don't use his ideas! Now all that is left is connecting each control to the appropriate variable. To do that for every control we open its property window. It allows us to set a number of appearance-related parameters, such as font, color, optional titles, etc., as well as the source-level expression each control is connected to. For display controls there is a single expression used to obtain the value to be displayed. For user-activated controls, such as push buttons or switches the expression is evaluated whenever the control is activated. Here is the property window for the display control:

 

 

 

 

We have specified that the variable displayVar is to be displayed once every second. Similarly, we set the properties of the switch control:

 

 

Whenever the switch is toggled to the ON position the "powerOn = 1" expression will be evaluated, whenever the switch is toggled to the OFF position the "powerOn = 0" expression will be evaluated. All that remains to make our panel functional is connecting it to a Chameleon debugger session. Each Viper panel can communicate with a different debugger session — to connect we simply specify the network address of the debugger session we want a given panel to communicate with. Once activated, the panel is constant communication with the debugger, and through it with the target system. In our example, the LED display request the value of the displayVar variable from the target system via the debugger once a second. Whenever the power switch gets toggled, an appropriate expression is sent to the debugger resulting in the powerOn variable being set to the appropriate value.

To complete our story, we should also mention that Jack, one of our engineers, had a different vision that he also chose to express using Viper:

 

 

For some reason, however, our customer didn't care for either vision and chose the following solution instead:

 

 

Using Viper we were able to show our customer the interface in action and modify it on-the-fly, without having to touch any hardware or software.

The sample scenario we have just described is somewhat simplistic, yet it demonstrates many of Viper's applications and its strengths. Viper provides a rich set of user interface objects, including digital LED and alphanumerical LCD displays, toggle switches, push buttons, text logs and 2-D data plotters.


 

 

 

Since Viper operates by sending commands to a debugger, it is not limited to the display and setting of user variables — it has access to all functions of the debugger. It can be used to develop a completely custom debugger user interface, including CPU start, stop and reset controls or controlling the real-time trace buffer of an in-circuit emulator:

 

 

This can be useful in testing applications, where only relevant controls and feedback information need to be provided, without exposing the operator to the complexities of a source-level debugger or an ICE.

We haven't explored all of Viper's features and applications. If you would like more information, please visit the Signum Systems web page at http://www.signum.com.

10. Conclusions

In this article we have discussed some of the prototyping options available to embedded systems designers. We didn't hope to exhaust the subject — that wasn't our goal. We have tried to bring to our readers' attention the possibilities for reducing the development effort through prototyping — a generally simple yet often overlooked alternative.



• • •

Viper and Chameleon Debugger are trademark of Signum Systems Corporation. Other brands and products are trademarks of their respective holders.



Hop to top.