EMBEDDED SYSTEMS DESIGN -- A SPECIAL CASE?

Integrating tools for real-time systems development calls for more than just glue -- it calls for a systems approach

David Kalinsky and Jim Ready

David Kalinsky and Jim Ready can be reached at Ready Systems Corp., 407 Portrero Ave., Sunnyvale, CA 94086.


Over the past five years, scores of useful tools have been introduced for the development of embedded systems software. Ranging from front-end CASE tools, through host- and target-based implementation tools, to performance analyzers and in-circuit emulators, most phases of software development have been addressed by tools vendors.

Although additional capabilities in each category will certainly advance the state of state-of-the-art in software development, what is sorely needed at this point is integration between this plethora of tools. Currently, developers must move from toolset to incompatible toolset as they progress through the life cycle (see Figure 1 , page 38).

Integration of these toolsets with each other, and with knowledge of the run-time software and hardware environment, will vastly increase the practicality of developing large-scale embedded systems software. Today, vendors are working to integrate traditionally disparate toolsets (CASE tools, microprocessor development systems, compilers, and debuggers) with technologies to provide smooth interfaces between stages of development. Needs include robust sets of tools for each stage and for each transition between stages of the software development life cycle (see Figure 2 and Figure 3, pages 39 and 42). Each must include the extra functionality required to deal with the complexities of embedded systems (such as object-oriented design, multitasking synchronization and communication, multi-processor target systems, timing requirements and analysis, and deterministic response).

This article examines an embedded system software development cycle using typical current tools technology, and highlights where tools integration has historically been neglected. Technology trends that improve integration (thereby reducing software development and maintenance costs) are described.

System Requirements and Design

Embedded systems development projects originate in a systems engineering phase. In this phase, software issues are not yet addressed because the entire system is being thought about abstractly as a "black box." In an application area such as avionics, the "black box" may actually be envisioned as being painted orange or dark green and being connected by ruggedized connectors to other parts of an airplane. In medical instrumentation, another embedded application area, the "black box" may have an attractive man-machine interface at its front panel, and cables to sensors and other medical devices at its rear.

The systems engineer, in close consultation with application area experts, begins work by analyzing system-level requirements. The engineer may want to express the functional requirements by using a graphic modeling technique (such as structure charts or data-flow diagrams). The engineer associates performance requirements with certain functions or chains of functions. For example, a certain stimulus-response path may be assigned an upper limit of time in which it must respond to a trigger. In the system requirements phase, the systems engineer will do modeling and simulation calculations to evaluate the feasability of the requirements.

A second step in system-level activity is called system design or allocation. In this activity, the systems engineer assigns to different technologies the individual function in the system requirements specification. For example, a function may be assigned to implementation in analog electronics, another to digital electronics, and others to perhaps electro-optics, or even to mechanical or vacuum technologies. Yet other system-level functions may be assigned to implementation as software on digital computers or microprocessors.

In a cardiologic system, for example, heartbeat detection may be assigned to an electronic peak detector, ECG presentation to a digital-analog display subsystem and waveform analysis and alarm detection to software running on an embedded microprocessor.

Once an initial allocation has taken place, it must be verified that every system-level requirement has been allocated to one (or more) system components. It also must be verified that there are no superfluous system components that do not work to satisfy some system requirement. These checks are often termed traceability.

Software Requirements Analysis

Once system-level allocation has taken place and computer software has appeared in the system design, the work of the software engineer formally begins. The software engineer, in cooperation with systems engineers, must develop requirements for this software based on those system-level requirements allocated to it, and interface needs that have appeared in the system-level allocation.

The primary activity of the software engineer is to perform a functional analysis of the requirements of the software. This is usually graphically modeled using a data-flow diagraming technique in which functions are shown as bubbles, and their data connections are shown as arrows. Functional bubbles may be "exploded" to show greater levels of functional detail.

Together with the functional analysis, the software requirements engineer may need to describe the control interconnections between functions and perhaps model special "control centers" associated with the data-flow diagrams. Control-flow modeling techniques have recently been popularized by Paul Ward and Stephen Mellor and independently by Derek Hatley and Imtiaz Pirbhai. Both teams advocate the use of State Transition Diagrams and tables to detail the control logic.

CASE tool support is becoming available for these functional control modeling methods.

As part of the software-requirementsspecification phase, all interfaces between computer software and its surrounding hardware must be fully specified. Such a specification becomes a detailed "contract" between the software developer on the one hand and the hardware developer on the other. Details down to the level of individual bits, interrupt addresses, and timing constraints must be specified. If these are not specified, the software to be developed will not integrate with the hardware to be developed in parallel.

The "interface control" specifications are being computerized at present. Typically, their computerization is not linked with the CASE-supported functional and control modeling methods. In the future, this link between tools will be vital in order to ensure that complex interfaces are specified consistently and completely and that they are kept stable and visible for all developers.

When the software requirements engineer finally presents the software requirements specification document, the systems engineer must be convinced that the software requirements specification addresses all issues allocated to it in the system-level allocation. The engineer must also be sure that the specification does not contain extraneous requirements that can not be traced back to system-level needs. Thus, traceability is again an issue at the software-requirements specification phase. Satisfactory tools for demonstrating this traceability have yet to emerge. When they do, these tools must be intimately linked to functional and control modeling tools. The components of functional and control models must be traced. Backward tracing is needed to link software requirements to system-level requirements and design models. Forward tracing is needed to link software requirements to design, implementation, and testing work further along the software life cycle.

Software Design

Once software requirements have been established, the software design process may begin. In embedded-systems real-time software development, the structure of the requirements model developed earlier is not the same as the structure of a design model that provides an implementation solution. Constraints such as timing requirements and special hardware-software interrelationships (such as interrupts and DMA interfaces) are typical reasons for the differences in structure of requirements and design models. The phase of high-level software design for real-time systems is an activity of major restructuring or even creating a new structure for the software solution.

This software-solution model typically includes the identification of concurrent tasks within the software and the selection of the appropriate mechanism for regulating each instance of intertask communication and synchronization. Data might be passed, for example, between tasks by way of mailbox, a queue, or an Ada rendezvous. Certainly data can not be passed freely between concurrent tasks because this would cause random-appearing errors of mutual exclusion violation. Control might be passed between tasks by using mechanisms such as semaphores, event flags, or an Ada rendezvous.

Today, most software designers mistakenly use requirements modeling tools and techniques such as data and control flow diagrams for software design modeling. With such methods, much critical real-time design information (such as identification of tasks and identification of intertask communication and synchronization mechanisms) can only be noted as informal comments. Or worse yet, they remain as decisions stored only in the mind of the designer.

In the near future, the advent of real-time software design tools will occur. Such tools explicitly capture these sorts of real-time design decisions in the form of visual formalisms, which are both well-defined and easy to absorb because of their graphic expressions. Eventually these tools will also make it possible to perform timing analyses of these visual depictions of high-level real-time designs. The basis for these analyses will be intimate knowledge of the underlying executive or run-time software, as well as the hardware environment, built into the design/timing analysis tool. Early design tools will provide the ability to do static timing calculations on these diagrams in order to evaluate whether a software design will meet real-time constraints. More advanced design tools will eventually perform dynamic simulations, which may even be viewed as animations of the tasking diagrams.

Such tasking diagrams may be constructed and detailed by using either hierarchical or object-oriented methods. Tools today provide strong support for object-oriented methods. What the software designer really needs is a toolset that allows selection of a method as it is most appropriate for each section of the project, and even mix-and-match alternative methods.

Also important is the issue of continuity between the software design phases and other life cycle phases--in other words, traceability. Every entity in a design must be justified by a firm tie to a need (or needs) expressed in the requirements models. The entity must be devel ped into a specific piece of code that it specifies.

Code and Debug

Today's implementers manually translate individual pieces of a software design into source code. This is not only tedious but inevitably leads to a rift between the software design and the software code implementation.

As software design tools progress toward higher levels of integration (for instance, between high-level structural models such as task diagrams and low-level detailed specifications such as program design language), it is becoming possible to envision automatic translation of design specifications into source code. In the sequential-programming world of data-processing applications, this dream is close to reality. In the highly constrained world of real-time software, this dream is only beginning to be partially realized in code frame generators.

Such code frame generators must not only translate designs into code, but they must remain tightly tied to software design tools in order to assure that changes made directly in source code do not violate design specifications.

Code frames are manually filled out to complete source code which can be compiled. Languages and their compilers are among the best understood technologies in the software life cycle. Even in this area, real-time applications pose special problems in terms of the interrelation of programs with executive or run-time services, so that program tasks can run concurrently and can communicate and synchronize with one another. For example, the Ada language has compilers implement the rendezvous mechanism in such a manner that it is sometimes impossible to rely on an Ada run-time system to provide rapid and deterministic real-time response. Special executive kernels or run-time systems are being used to solve this problem. Their characteristics must be evaluated in the timing analyses provided by real-time design tools.

Once code has been compiled and linked, and its relations to an executive kernel or run-time system have been established, the software engineer would like to execute the code in order to begin debugging it. In embedded systems development, the target hardware is typically also early in its development and can not be used as a reliable platform for software execution. The software engineer demands simulation capability on the host computer on which software development is taking place.

Such simulation capability should not be restricted to the application code itself but must extend to a simulation of the underlying executive kernel or run-time system services in order to assess the real-time interrelations of concurrent tasks. For instance, a software engineer should at this stage reevaluate adherence to timing constraints, processor loading, and intertask communication and synchronization mechanisms usage.

The convenience of a source-level debugger is needed in order to make the software engineer's job easier at this stage. Such a debugger must not only be conversant in terms of application code, but it also must be "knowledgeable" of the executive kernel run-time system mechanisms (and their status) at all times.

As tools evolve and integrate, software engineers in the future will debug software directly from their high-level design graphic representations, coming in and out of levels of design detail and source-level implementation detail.

Integration and Test

Hardware development on the embedded system project eventually will progress to the point where it is feasible to attempt to integrate the software with the newborn hardware. This demands a high-speed link for efficient downloading of the software from the host to the target software. Efficiency in this connection is critical since many downloads will be needed as integration tests proceed and problems must be corrected. A slow downloading mechanism would force the software engineer into making changes by direct patching into the executable code on the target hardware. This would create an irreparable rift between target code and source code, and contradictions with design and perhaps requirements.

To combat these dangers, the high-speed link should also be used as the access channel for a host-based source-level debugger of target-based code, which would complement any target-based debugger. This host-based debugger would tie the executable code back to design and requirements specifications so that the code could be viewed from these various high-level perspectives and kept consistent with them. For example, a target-based timing performance analysis could be tied back to design-based analyses and requirements-level constraints. A change in code should be tied back to the appropriate design component and to the corresponding requirements. In this way, the impact of any proposed change can be assessed, and an implemental change can be properly documented back through all the life cycle stages it affects.

Installation and Maintenance

As the development life cycle comes to its conclusion, system testing is performed to evaluate the degree to which a system meets its requirements. In order that these tests be as formal and complete as possible, they must be tied directly back to requirements. In other words, formal test plans and test results must trace to requirements. Few tools are available today to manage this traceability connection, and fewer yet can tie requirements-test traceability to requirements-design-code interrelationships. The ability to relate high-level test results to design and code components (by way of their tie-ins to requirements) would be a powerful technique for localizing errors and needed corrections.

This same connection, used in the same way, would be equally powerful for reducing the effort and cost involved in software maintenance.

Formal, consistent, up-to-date documentation, automatically generated from requirements and design and code information, is another leg upon which an efficient maintenance phase must stand.

Summary and Conclusion

Today's real-time embedded systems software engineer is faced with a project life cycle strewn with disparate, noninterconnecting tools. Starting with system and software requirements CASE tools, the developer must transfer the model to a toolset (or toolsets) more suited for software design. After that, the developer must manually translate the design into source code for a compiler. After compilation, the developer must find host-based debugger and simulation tools compatible with the object code generated by a particular compiler. Next, the object code must be quickly downloaded (by using a network) onto the target system and analyzed there for performance, efficiency, and bugs. Suitable, compatible download and analysis tools must be selected.

Today, coding is only a small fraction of the software engineer's effort. The engineer's main activities are modeling, testing, and documentation throughout the life cycle. While doing all of these activities, a significant proportion of the engineer's time is spent bridging rifts between the various tools that support these various activities. These bridges are jerry-built, hand-made improvisations that are totally unproductive efforts.

As methods and tools for more and more steps in the life cycle are better understood, an integration process is now taking place in the software engineering tools and industry. This integration will soon replace those unproductive bridges and provide the real-time embedded systems software engineer with a seamless set of software development tools.