By Dmitri Khijniak, Embedded Software Engineer, Visteon Corp., Dearborn, Mich., Chirag Shah, Software Engineer, Electronic Data Systems Inc., Detroit
Model-based development that puts more emphasis on the design and refinement of a design model, as opposed to software code, is gaining support among software developers. Essentially a well-developed functional design, the design model becomes a single common artifact developed and refined along the evolution of a software project.
The design model can capture all essential high-level design decisions without being bogged down in elementary details of a programming language. In addition, it can be used not only to develop and analyze the software design but also to validate requirements and automatically generate production code.
But to be useful for analysis and code synthesis, the design models must be developed and refined to a fairly detailed level-a task that demands a developer with a solid programming background. In fact, programmers in many cases must actually start creating models in the early phases of a software project.
State transition diagrams have long been used for the design and representation of a certain class of systems called reactive systems, which includes many embedded and deterministic real-time designs. These systems are termed "reactive" because they spend a majority of the time waiting for an external or internal event and then react to it with a short burst of activity.
The state chart notation is a design formalism that is ideal for describing the behavior of a reactive system. The method overcomes the scalability issue that arises when state transition diagrams are used to characterize a complex system, and it's well-suited to represent both high-level functional design assumptions and implementation details of the system.
In fact, the state chart is a notation of choice in many automotive-system-related embedded-software projects.
The genesis of almost any software project lies in its requirements. Requirements are recorded to define and document the functional behavior that a customer expects and to note the functional constraints of the system. Often, requirement specifications are written in natural language.
For a reactive system, the requirements essentially consist of a descriptive list of the modes and features of the system and the actions of the system in response to external or internal stimuli. After requirements are completed and the customer has signed off on them, designers and programmers use them to develop a system design and to write software code.
Because state charts describe the system behavior in terms of states, events and actions, they are a good vehicle for describing the behavior of the reactive system and may be readily used to document requirements. State charts tend to be compact and precise when used to specify behavior. The simplicity of the notation does not cause misunderstandings for the nonprogramming audience.
More important, state chart design tools support the simulation of a state chart model that can effectively demonstrate the behavior of the prospective system very early in the design process, even before the coding begins.
Use of state charts does not mean the demise of the written specification. Written requirements are still a useful communication tool. In fact, having defined written high-level requirements is very helpful for a system overview and may well assist in designing a state chart model.
Ideally, requirements and state charts should be developed in parallel since the latter could give a better visual perspective on the system behavior, and help to verify completeness and precision of the written specification.
Before the design of a state chart model commences, we recommend determining the scope of the model-in other words, how far the modeling will proceed. For a simple application, the entire software can be represented in a state chart model. For a more complex system, an architecture that divides the total software into manageable pieces would be needed.
In developing the architecture, one could consider identifying the reactive portion of the system and modeling it using state charts, while stateless continuous logic could be programmed directly in the code. It would also be necessary to consider that some portion of the software code may have already been developed and is being reused for the project. It may be easier to call this code from state charts, rather than develop an equivalent state chart model.
States provide the current, unique context while the reactive system is waiting for an event or a specific set of conditions. States in state charts are graphically represented as rectangles with rounded corners. They can have a hierarchy in which a "superstate" can enclose one or more "substates."
For better readability, the states and transitions inside a superstate can be extracted to a different "page" that can be accessed by "opening" the superstate to get at the details. States at the same level can be either mutually exclusive or concurrent.
Requirements for reactive systems usually involve a list of high-level modes, along with a listing of events and related actions that need to be executed. The highest-level states may not be specified directly in the requirements, but are implied. Looking to identify an initial hierarchy of the high-level states, we suggest following the hierarchy of modes specified in the requirements and designating states for each implied mode and submode.
A state chart diagram may be viewed as a graphical map of the possible values that a set of key, controlling variables can hold. Those controlling attributes define the main operating modes of the system and control its functionality. Particularly for high-level states, we recommend using a graphical state chart notation to represent the logic.
Requirements describe behavior that can be observed from the outside of the system. They don't capture specific details on how the system logic is implemented. For the initial system model, it may be sufficient to develop and simulate a model without much detail.
However, to show more realistic behavior of the system internals, designers need to go a step further and define how a system actually performs its functions by specifying the detailed logic.
Hierarchy is commonly used in state charts to simplify design and reduce the number of states that have common transitions. If several states have identical transitions and actions ending on a single state, then all these states could be enclosed by a superstate and all separate transitions collapsed into a single, common transition connecting the superstate and the destination state. This is a state aggregation, or bottom-up, approach.
Hierarchy and concurrency are two additions that made state charts much more useful than their predecessor, finite state machine diagrams. Hierarchy allows for the creation of nested states that transformed flat, state transition diagrams into multilayer hierarchical state charts. Concurrency cured the combinatorial explosion of states and made state charts much more compact and scalable.
Concurrency in state charts refers to a situation where more than one substate is active at the same time. Concurrency can be used when common logic is required in different parts of the system. The common logic becomes a concurrent virtual subroutine (subtask) consisting of two high-level states, idle and active. When the system needs to execute the functionality in the subtask, it triggers an event to push the concurrent state chart from the idle to the active state.
Whenever the system changes its active state, it has to go through a transition. In state charts, transitions are shown as directed lines connecting states. Transitions are set off by events, or triggers; the names of these triggers are shown next to the transition lines.
Besides events, transitions may also specify a Boolean condition that, if valid, would allow the transition. If both an event and condition are listed, then both are required for the transition to take place.
A transition could be simple or complex. A simple transition is drawn as a single arrow from its origin state to its destination state, whereas a complex transition is made up of a sequence of arrows with what are called "conditional connectives" in between.
In reactive systems, events are the most frequent triggers of transitions. External signals or triggers may include user events associated with button presses and knob rotations; or system events, such as timer events or exceptions. Besides external events, the state chart model may also use internal events that are not associated with physical triggers. Such events are used for synchronization and communication between states in the model.
States and transitions discussed so far determine the behavioral layout of a system. They describe main modes of the system and how those modes can change via transitions caused by events or conditions.
There are several places where the actions can be entered in state charts. One type is transition actions, or actions performed during a transition. Also, actions could be performed on entry to or exit from a state. Finally, while the system is idle, it could perform an "activity." Some state chart tools represent activities as "during" actions, which run repeatedly.
Most of the tools available to designers today make it possible to specify actions in text or pseudocode. Designers who consider doing state chart simulation or who plan to autogenerate code from the design must specify actions to a fairly detailed level.
For some tools, like Betterstate or Rational Rose, designers write code snippets using a programming language. In the case of Stateflow, the tool translates its own special action language into one of the target languages.
See related chart
See related chart