Many Java books state that it is too slow for real-time systems. But Java compilers and virtual machines have come a long way in solving the run-time issues of Java systems' performance. However, the question remains whether we can ensure that the systems we design and build are compliant with both our functional and performance requirements before we even get down to writing our Java code.
There are two converging standards that can help. The Uniform Modeling Language (UML) is widely accepted and is used to analyze and design a wide variety of systems. The Specification and Description Language (SDL) is a design-oriented language that is precise enough not only to generate 100 percent of our Java code, but also to simulate our system at a very early stage.
For real-time systems, we propose a workflow that combines the flexibility of UML with the precision of SDL to save time-to-market. Since we can also include validation and verification in this workflow, we can indeed reduce those targeting and execution errors that bedevil the end of the development process. Moreover, we can generate 100 percent of the application code from the design. Since we will have simulated and tested that design at an early stage, we can have a high level of confidence in both functional and environmental compliance.
UML provides a good starting place for analyzing such a system. Use-case diagrams describe our system from the user's perspective, detailing something that an "actor" requires of the system-actors are people or systems that interact with our system. Take a mobile telephone. Conceptually, this is a simple system that allows a caller to make and receive calls. But to make things more interesting maybe we can add an address book.
Use-case diagrams themselves are intentionally simple. However, each item on a diagram will have a properties sheet describing in detail the expected functionality; for example, any pre- and post-conditions. Importantly, UML allows for the inclusion also of user-defined properties.
Each use-case consists of a set of scenarios. A scenario is simply a sequence of steps describing an interaction between an actor and the system. It is typical for each use-case to have one usual or basic course of action, and there may also be other unusual or alternative courses. These may indicate error situations, or may just be different ways of achieving the usual course of action. If the system is complex, we may choose to first break each use-case into smaller ones. Otherwise, we will use sequence diagrams to describe scenarios.
Often, the last step in our analysis phase is the creation of a model of the information in our system. We can mechanically create this from our collection of sequence diagrams. UML uses the class diagram to depict the information model. We can then add other classes by further analyzing our system.
This process has been easy up to now because we have just been analyzing our requirements and forgetting about implementation details. However, consider how we interface with the real world. We need to account for things like keypads and screens and, in our mobile phone system, we need to connect to a communications network. This will involve messages and protocols, and we must do things in real time. We can elaborate our analysis model a little further in UML to describe some entities to help us interface with the real world; indeed, UML calls these "interface classes."
However, this is still not sufficient to describe the real-time behavior of the system. For that we must look elsewhere.
No precise description
UML does not contain any precise way to describe behavior: what happens inside a method or procedure. Of course we can use structured text, but this is only useful as further description. State charts can (and should) be used to show what happens when events occur in our system so that we can analyze sequencing still further.
This helps a little, but again it is just not precise enough to help describe the complete behavior of our system. We cannot, for example, easily (or safely) simulate this. So where can we get help to specify the real-time behavior and can we use this specification to simulate, test and generate 100 percent of our application code?
Any reasonable workflow demands that we move between phases effortlessly while retaining information consistency. The standardized one-to-one mapping between UML and SDL ensures this, allowing automatic translation of UML class diagrams and state diagrams into SDL. All applicable data in these diagrams-for example, class attributes and methods-are mapped into relevant SDL constructs. This is the first real manifestation of what UML describes as a real-time profile for UML.
The transition of UML to SDL is based on UML stereotypes, tagged values and constraints, so the translation is done according to how the designer wants UML entities mapped onto SDL design constructs. This means the design is created exactly how the designer wants.
Consistency checking and analysis to design synchronization-ensuring that both analysis and design are equivalent-is possible as the mapping between UML and SDL is one-to-one. What's more, we can convert UML sequence charts into message sequence charts, which we can feed into or compare with the output from our simulation and testing activities.
Once the initial SDL architecture and detailed design have been created from the UML models additional detailed design is added. This may include further definition or decomposition of objects, or creation of new communications paths or signals.
The biggest gap that must be filled is the detailed real-time behavior-the information that cannot be precisely defined within the UML model. SDL provides visual symbols to handle real-time constructs such as receiving and sending events, timers, data manipulation and dynamic creation of entities. The emphasis on design in SDL is defining what the system should do, not necessarily how it should do it.
Analysis tools check the syntax and semantics of the detailed design, just like a normal compiler. Once completed, we can then check the correctness of the design-long before the traditional implementation phase.
Simulation of the system allows the designer to execute the design on the host platform to check the behavior; this can be the whole design or any set of subsystems within it. The aim is to debug and prove the design rather than debug the code.
Creating a simulation executable is achieved via 100 percent automatic code generation from SDL: the simulation is actual code executing on the host. Once in the simulation environment we can do almost anything possible in a standard source level debugger, except we always work on debugging the visual design. If we set a breakpoint or trace through the simulation, we do this on the design, not on the code. Outputs from simulation, for example, message sequence charts, can be stored and used later for automatic regression testing on the host.
Detecting and fixing most design errors in simulation means that our design does what we intended. But we can prove our design even further. Using validation techniques, we can perform automatic state exploration, effectively using computing power to try and break the system. Intelligent algorithms execute the design and check a number of rules every time the system does something. For example, checks will be made for deadlock or race conditions, or that data stays within the ranges defined. Designers and testers can also define their own system properties to be checked.
The aim is to prove the design and to bring testing further forward in the life cycle. Prove the design and almost eliminate testing of code: we can jump straight to integration and acceptance testing.
The traditional implementation phase-writing code-is removed from the workflow. What is called 100 percent code generation means that all the code is generated from the design, the design we have just tested.
Code generation provides the following benefits over and above not having to write any code:
- Efficient code. Optimize once in the code generation software and that optimization is included everywhere.
- Zero coding errors. The code is an implementation of the design. There is no deviation from the design, no memory leaks, no errors.
- Design and code consistency. The design and code never deviate.
Essentially, 100 percent code generation has been used successfully across the globe in hundreds of projects. Today 100 percent code generation is a reality, not a dream.
Getting the code onto the target platform means integrating the 100 percent generated code with the relevant hardware devices and legacy code. But before we do that we have to decide how to deploy our system.
SDL works on logical entities, just like UML. So when we develop our design architecture, we say nothing about how it will be deployed physically. We can do this by using UML deployment diagrams to define how the entities should be deployed. This is used by the code generation process to write and target the code as required-and can automatically build in the relevant glue to connect the different subsystems.
We started out talking about Java. However, the choice of language is in some respects academic. The real-time workflow ends with the generation of 100 percent of the application code. This code is compilable and the source code may be considered disposable. The unique differences between, say, Java and C++ are managed carefully at the deployment stage.
It is clear that SDL developers benefit from using UML to analyze requirements: to take a more abstract view of the system under construction; to agree this with customers and users before diving into the design details.
The International Telecommunications Union has ratified what is known as SDL-2000. Among other things, this adds UML concepts to SDL and importantly provides the mapping between UML and SDL (what is known as Z.109, the "real-time profile for UML"). The Object Management Group is in the process of describing its side of the real-time profile, including a so-called action language. There is a lot of momentum from the real-time market, and especially the telecommunications segment, to base this on SDL. In the meantime, Z.109 is becoming the de facto dominant real-time profile for UML.