On Modelling Guidelines: Flowchart Patterns for STATEFLOW

Transcription

On Modelling Guidelines: Flowchart Patterns for STATEFLOW
On Modelling Guidelines: Flowchart Patterns for STATEFLOW
Daniel Buck
Advanced Development
DaimlerChrysler AG
71059 Sindelfingen, Germany
email: [email protected]
ABSTRACT
In recent years, graphical modelling and simulation environments have become increasingly popular for the development of automotive control systems. However, the
power and high degree of freedom offered by these tools
can also lead to problems if not used properly, especially
in large projects. Guidelines can help to establish a consistent modelling style throughout a project and thus improve
readability, understandability and maintainability of the resulting product. This paper presents general considerations
about guidelines and presents a collection of patterns for
modelling control-flow in STATEFLOW.
KEY WORDS
Modelling, Guidelines, Control-Flow, Patterns
1. Introduction
The number and importance of embedded systems in the
automotive industry has increased dramatically over the
last few years. In this process, the complexity and criticality of these systems has reached a level that has become
difficult to handle with classical development methods. As
a consequence, the industry is currently in the process of
switching to a new graphical model-based development approach. This approach is promising considerable gains in
productivity through an increased level of abstraction and
through the support for simulation and code-generation offered by the corresponding tools. However, the power and
degree of freedom offered by those tools can also have negative side-effects: Since there is usually “more than one
way to do it”, it is necessary to estabilish a common style
within a large project team in order to achieve consistent
appearance of the final product and ensure mutual understandability and maintainability of artifacts. Moreover, the
misunderstanding or misuse of advanced features can easily lead to quality problems. Finally, for safety-critical systems such as “by-wire systems it might be necessary to restrict the use of the tools to a subset of features to avoid
certain risks. Such a restricted set of features would be
equivalent to the safe subset of a classical programming
language such as “C” (see [1]).
Andreas Rau
Systems Engineer
STZ Softwaretechnik
73730 Esslingen, Germany
email: [email protected]
2. Guidelines
Guidelines can help to address these problems and can
be used as a constructive measure to assure quality, i.e.
prevent errors rather than fixing them when they have
been made which is usually more expensive. Standardized
guidelines already exist for specific problem domains, e.g.
from MISRA [2]. For large and critical projects, guidelines
should be an integral part of the development process and
can serve many different purposes:
• Prevent Errors: Restrict use of constructs that are
buggy, easy to misuse, intrinsically dangerous or undesired (for the given application).
• Achieve Common Appearance: Common appearance and style can be achieved via rules for arrangement (e.g. indent), formatting, naming, decomposition (interfaces) and documentation.
• Increase Productivity and Quality: Offer timetested solutions for recurring tasks through libraries,
algorithms and patterns.
As a warning note, it should be pointed out that the
success of guidelines largely depends on their acceptance
by the developers who are expected to use them. It is essential, that they see them as a means of support rather than
a burden or evil management scheme to limit their freedom
and suffocate their creativity. Therefore, too few guidelines are better than too many, especially to begin with. As
soon as they have proven useful, more guidelines can be
added. In order to facilitate their acceptance, guidelines
should meet the following requirements:
• Clarity: The meaning and motivation of all guidelines must be understandable for all developers.
• Minimality: Each guideline should only cover one
aspect to facilitate conformance testing and limit the
rippling effect of guideline-changes.
• Consistency: The whole set of guidelines must be
consistent, i.e. adhering to guideline A must not lead
to breaking guideline B. Where mutually exclusive
guidelines exist they should be clearly marked as such.
• Consensus:
Guidelines must not be imposed as
laws from upper management. Instead, the developers should be involved in their definition and/or the
tailoring process (see “Adaptability”).
• Flexibility: Guidelines can only try to capture “best
practices” that apply to the majority of cases. Thus, it
must be possible to deviate from them in well-justified
cases1 .
• Adaptability: Every project has slightly different
needs. Therefore, it must be possible to tailor projectspecific guidelines from a generic set. To facilitate
this, the scope, priority2 and dependencies between
guidelines must be documented.
• Stability:
Guidelines must not be changed frequently. Otherwise developers will need to spend excessive time to keep up with the changes and update
their work and eventually become frustrated.
• Testability: Like requirements, guidelines are useless if conformance with them can’t be tested, either
manually in a review or automatically using tools.
In order to address these requirements, a template
for the description of guidelines with dedicated fields for
the description of the guideline itself as well as additional
information for tailoring, change-management and crossreferencing has been devised. It is shown in table 1 in the
appendix. However, the template is only an aid. It will not
lead to a perfect set of guidelines by itself. The writing of
good guidelines still requires good judgement, especially
with respect to flexibility and level of detail. Too much
or too little flexibility can render a whole set of guidelines
useless, because developers will stretch it in all directions
or drop it because they feel they cannot adhere to it anyway. The reaching of consensus can sometimes be tiring,
too. As with all other qualitity-related measures, management support is essential for success..
3. Patterns
At DaimlerChrysler, an extensive set of over 100 guidelines spanning more than 150 pages has been defined and
successfully used over the last couple of years. A fair share
of these guidelines are patterns. Patterns, although a rather
vague type of guideline, have proven themselves most useful during practical application. They are a matter of interest also in other areas, such as object-oriented programming (see [3]). Other than a library, a pattern is not an
off-the-shelf solution but more of “an approach to solve a
problem”. It is not a detailed algorithm, though, but merely
points out the overall architecture or layout of a solution.
Thus, a pattern usually scales well to different sizes, similar problems, etc., while library components are usually
implemented with a strictly defined interface and are therefore more limited. The following sections describe a set of
patterns for modelling control-flow in STATEFLOW.
1 The
justification for all such exceptions should be documented.
may be mandatory and therefore excluded from tailoring.
2 Some
3.1 Goals of the patterns
STATEFLOW allows creating Statecharts and Flowcharts
from a mimimum of elements: states, transistions and junctions. For Flowcharts in particular, this leads to a tremendous amount of flexibility. On the other hand however,
the resulting “onion-style”3 diagrams are often hard to read
(see figure 12). Thus, there is a need for structured modelling, a graphical way of structured programming. Looking back on structured programming, there are a number of
corresponding graphical notations, such as Flow-Diagrams
[4, 5] and Nassi-Shneidermann Diagrams [6]. Even though
those notations do not fit into STATEFLOW, the principles
behind them can be adopted for Flowcharts. As it turns out,
the basic elements of structured programming, sequence,
decision and iteration can easily be constructed from junctions and transitions. However, there are many ways to do
so, and not all of them scale well. So rather than letting
developers invent their own ways to do it, we have defined
a set of patterns which meets the following requirements:
• Completeness: There are patterns for sequence, different kinds of decisions (if, if-else, case) and different
kinds of loops (for, while-do, do-while)
• Easy Recognition: Every pattern has a unique shape
that can be recognized even at a high zoom level.
• Space Economy: The patterns are designed not to
take up excessive space. For large diagrams, the preferred direction of growth is in length, not breadth for
easy viewing (by scrolling) and printing.
• Extensibility: The action-part of any pattern can be
replaced by a sub-pattern, e.g. for a sequence of decisions or nested loops. An existing diagram using the
patterns can easily be extended by horizontal or vertical stretching and adding more patterns.
• Scalability:
The patterns can be combined to
build large diagrams without loosing the possibility of
recognition inside a compound of patterns.
• Consistency: The elements of each pattern are oriented in the same way: conditions left to right, actions
top to bottom. The flow of control is downwards.
• Determinism: The patterns do not rely on implicit
built-in priority rules for transitions for resolving conflicts. There is always exactly one way to proceed.
STATEFLOW also allows using Flowcharts and Statecharts in one diagram, which is often more concise and
natural than separate diagrams. This seamless integration
is actually one of the main advantages offered by STATEFLOW. During-Actions for example, can often easily be
expressed with a Flowchart. Other tools require switching
to a different notations here. But the Flowchart notation
can also be used in state transitions. To the user, this offers
3 Named after the shape forming when many curved transitions
start/end at one junction.
additional flexibility without the need to switch to another
notation. However, this should not be overdone, because
it clutters the diagram. From our experience, branches in
transitions should only be used for the reuse of complex
conditions or actions. This usually requires no more than
one junction (see figure 1).
order of cases in the pattern implies a priority! Therefore,
non-exclusive conditions must be checked in the right order. If the conditions are (thought to be) exclusive or when
no priority is intended, the pre-processing pattern shown in
figure 7 can be used to assure uniqueness or detect any conflicts and explicitly handle them at runtime. This is especially important for safety-critical systems where runtimeerrors or implicit resolution of conflicts are not tolerable.
Reuse
Figure 1. Reuse of conditions in transitions
Figure 3. If/If-Else Pattern
3.2 Description of the patterns
In this section every pattern is presented with a screenshot.
The most simple pattern is the sequence. As shown in figure 2, it can be implemented either as textual or a graphical
sequence of actions. Usually, the textual form is preferred
and used to form blocks of actions, and the graphical form
is only used for the sequencing of patterns.
Figure 2. Sequence Pattern
Next there are decisions, which are represented by a
branching control flow with the condition on the horizontal
and the action(s) on the vertical branch. As shown in figure
3, there can either be only an if-action or an if- and an elseaction, both oriented vertically. Of course, decisions can
also be nested (see figure 4). Note though, that this results
in horizontal growth of the diagram. Limiting the level of
nesting to, say, 3 prevents this unwanted growth and also
reduces the complexity of the diagram. Note also, how the
nested if’s can still easily be recognized.
The problem with nesting also limits the use of ifelse-if cascades as the one shown in figure 5. Therefore, as
in many programming languages, there is also a pattern for
selection. Its basic form is shown in figure 6 on the next
page. Other than the nested if-patterns, it grows only downwards while still following the orientation rules for conditions and actions. However, just like in a nested if-else, the
Figure 4. Nested Patterns (If-If)
Figure 5. Nested Patterns (If-Else-If)
Figure 8. for-loop Pattern
Figure 6. Case Patterns for Integer Cases and Conditions
Figure 9. while-do-loop Pattern
Figure 10. do-while-loop Pattern
Figure 7. Case Pre-Processing Pattern for Conditions
Finally, there are patterns for loops, which are shown
in figures 8 through 10. Note, that all the loop patterns have
the same characteristic triangular shape that makes them
easy to recognize. The main difference between them is
their initialization and the location of the body with the action and the exit condition.
All the patterns have extra empty transitions and junctions on each end. These serve as connectors and prevent the patterns from melting together when sequencing
or nesting them, thus preserving recognition. You might
have also noticed, that all the patterns use condition actions
rather than transition actions. The reason for this is that
there are no (state-)transitions in a Flowchart. It is also
more natural and leads to generation of better code to execute all actions on-the-go.
In Statecharts on the other hand, the use of condition actions can easily lead to confusion because of the
side-effects they can have even when no transition is taking place. They should therefore be used with care (or not
at all). Finally, it is important that in all the patterns there is
never more than one conditioned transition from a junction
and that every junction has at least one outgoing unconditioned transition. Since unconditioned transitions are only
taken when no valid conditioned path exists4 , this ensures
both determinism and complete execution of the Flowchart.
As a final example the function listed in figure 11 is
implemented in figures 12 and 13 to show the difference
between onion-style and patterns. The difference in readablity should speak for itself. Please note, how the break
from the loop is easier to spot in the pattern example.
4 This
is the only implicit priority rule the patterns rely on.
int function example(int u) {
int i;
if (u > 0) {
if (u > 1) {
y = 1;
} else for (i=u; i>0; i--) {
i = i + u;
if (i > 100) break;
}
} else if (u == 0) {
y = 0;
} else {
y = -1;
}
return y;
}
Figure 11. Example (C-Code)
4. Conclusion
As demonstrated in the final example, the FlowchartPatterns presented in this paper can greatly improve the
readability of Flowchart-diagrams. The easy recognition
of basic control structures gives a quick impression of an
algorithm which gets even better when the Flowchart is animated during execution. This is true even at high zoom
levels. In addition, this facilitates the identification of badmodelling style and forbidden constructs, such as goto’s
out of loops, etc. This has also been shown in the example. Since the patterns are designed to be combined and
thus scale well, they can be used for diagrams of real-world
complexity. Extending and redesigning a Flowchart is easily possible by stretching the diagram vertically and/or horizontally and putting in additional patterns or moving a
block of patterns up or down. The patterns have been extensively and successfully used in several pre-series and series development projects at DaimlerChrysler over the last
few years. As a result, the readability and maintainability
of Flowchart diagrams in these projects has been greatly
improved.
Furthermore, exclusive use of the patterns shown,
would allow easy analysis of Flowcharts. For example, the
simple version of the popular cyclomatic complexity number from McCabe [7] can easily be computed by adding the
basic complexity values for each pattern shown below and
adding 1 to the result.
• Sequence: 0
Figure 12. Example (onion-style)
• Decision (if): 1
• Decision (case): number of cases
• Iteration: 1
Figure 13. Example (using patterns)
Thus, the cyclomatic complexity of the final example computes to 6. The implementation of tools for other
kinds of control-flow analysis, including path analysis and
the generation of test vectors would be simplified, too.
Also the tools themselves could benefit from wide acceptance of these patterns: At this time, the patterns have
to be manually constructed from the basic elements. To increase usability, built-in templates for each of the patterns
to drag in from the toolbar could be provided. This would
also simplify static analysis of charts, because patterns
would no longer have to be geometrically parsed. Based on
these templates, the code-generator (STATEFLOW Coder)
could be enhanced to recognize the patterns and generate
better code from them (e.g. really generate an if-statement
where the developer has modelled an if-statement). Such
code could be more easily traced back to the model.
Finally, as a first step towards broader acceptance,
both the patterns and the guideline template have been
adopted for the Mathworks Automotive Advisory Board’s
(MAAB) guidelines for the automotive industry [8].
Appendix - Guideline Template
id
title
priority
scope
automation
prerequisites
description
benefit
penalty
author
last change
see also
unique id of each guideline (used for cross-references)
short, unique, descriptive title
mandatory, strongly recommended, recommended
project, department, division, company, industry or world
state of automation, one of none, possible, check, correction
guidelines that must be adhered to for this guideline to make sense
description of the guideline content with text, graphics, ...
description of the benefit when adhering to the guideline
description of the penalty/risk of breaking the guideline
(original) author of the guideline
last change (+author) of the guideline
cross-references to similar guidelines (proposed)
Table 1. The guideline template
References
[1] Les Hatton, Safer C: Developing Software for High-Integrity and Safety-Critical Systems (McGraw-Hill International
Series in Software Engineering, 1998)
[2] Motor Industry Research Association (MISRA), Guidelines For the Use Of The C Language In Vehicle Based Software
(MISRA, April 1998)
[3] Gamma, Erich et.al., Design Patterns: Elements of Reusable Object-Oriented Software (New York, NY: Addison-Wesley
Pub Co., 1995)
[4] Deutsches Institut für Normung, DIN Katalog für technische Regeln, DIN 66001 (Berlin: Beuth Verlag, 1985)
[5] International Organisation for Standardization, ISO 5807: Information Processing - Document Symbols and Conventions
for Data, Program and System Flowcharts, Program Network Charts and System Resource Charts (Genf: International
Organisation for Standardization, 1985)
[6] Nassi and B Shneiderman, Flowchart techniques for structured programming (SIGPLAN Notices, 8(8):12–26, 1973)
[7] T.J. McCabe, A Complexity Measure (IEEE Transactions on Software Engineering SE-2,4:308-320, 1976)
[8] Mathworks Automotive Advisory Board (MAAB), Controller Style Guidelines for Production Intent (The MathWorks,
March 2001)