A Software Design Method for Ada 95 Based Concurrent and Real-Time Systems
Robert G. Pettit IV
Platform Design & Integration
Sallie Mae
Herndon, Virginia 22070
Hassan Gomaa
Department of Information and Software Systems Engineering
George Mason University
Fairfax, Virginia 22030-4444
ABSTRACT
The Ada-based Design Approach for Real-Time Systems (ADARTSSM) is a design approach for concurrent and real-time systems using the Ada programming language. The current version of Ada, Ada 83, has many shortcomings for concurrent and real-time systems, several of which are addressed by the Ada 95 revision to the Ada language. This paper describes how the features of Ada 95 that help in concurrent software design have been incorporated into the ADARTS 95 and CODARTS / Ada 95 design methods. It uses an automobile cruise control system case study to examine an Ada 95 implementation of a concurrent and real-time system in comparison to the Ada 83 solution.
Keywords: real-time systems, Ada-based real-time system design, software design methods, ADARTS, CODARTS, Ada 95
ADARTSSM is the registered service mark of the Software Productivity Consortium Limited Partnership.
1.Introduction
ADARTS, the Ada based Design Approach for Real Time Systems, provides the principles and steps for mapping a real time system specification into an Ada based design consisting of tasks and information hiding packages. ADARTS builds on the strengths of the Naval Research Lab Software Cost Reduction method [Parnas72, Parnas79, Parnas84], Booch's version of Object Oriented Design [Booch94] and the DARTS (Design Approach for Real Time Systems) methods [Gomaa84, Gomaa86, Gomaa93]. Although one of the goals of the method is to be Ada oriented, the principles on which the method is based are general and the method can be applied to the design of any real-time system, with the
Ada-specific aspects of the method omitted. The ADARTS method is described in “Software Design Methods for Concurrent and Real-Time Systems” [Gomaa93], published by Addison Wesley as part of the SEI Software Engineering series. An ADARTS validation exercise is described in [Cochran & Gomaa91].
Using ADARTS, an engineer develops a language independent concurrent software architecture, which is then mapped to Ada in one step of the method - the Ada based Architectural Design step. ADARTS was designed in this way to facilitate mapping to other languages, a capability provided by the CODARTS (Concurrent Design Approach for Real-Time Systems) method [also described in Gomaa93], which is a sister method to ADARTS. ADARTS and CODARTS have several steps in common. Restricting the mapping to an Ada specific architecture to one step of the method means that the changes to ADARTS to support Ada 95 are localized to that step.
After providing an overview of the ADARTS and CODARTS methods, the paper describes the features of Ada 95 that help in concurrent software design and how they have been incorporated into ADARTS and CODARTS. The version of ADARTS that supports the mapping to Ada 95 is referred to in this paper as ADARTS 95, in contrast to the version that supports Ada 83, which is referred to from now on as ADARTS 83. The version of CODARTS that supports Ada 95 is referred to as CODARTS/Ada 95. The paper compares ADARTS 95 and CODARTS/Ada 95 with ADARTS 83, and illustrates this with an example of the design of an automobile cruise control system.
2.THE ADARTS AND CODARTS DESIGN METHODS
2.1Introduction
ADARTS and CODARTS build on the strengths of the NRL, OOD, JSD, and DARTS methods by emphasizing both information hiding module (package) and task structuring. Key features of both ADARTS and CODARTS are the principles for decomposing a real time system into concurrent tasks and information hiding modules. To design maintainable and reusable software components, the two methods incorporate a combination of the NRL module structuring criteria and the OOD object structuring criteria. To structure a system into concurrent tasks, the methods use a set of task structuring criteria that are a refinement of those originally developed for the DARTS design method.
ADARTS starts with a real-time specification (referred to as a behavioral model) developed using Real-Time Structured Analysis (RTSA). CODARTS provides an alternative approach to Real-Time Structured Analysis for analyzing and modeling the system, namely the Concurrent Object-Based Real-Time Analysis (COBRA) approach [Gomaa93].
Both the task structuring criteria and the module structuring criteria are applied to the objects and/or functions of the behavioral model. When performing task and module structuring, the behavioral model is viewed from two perspectives, the dynamic and static structuring views. The dynamic view is provided by the concurrent tasks, which are determined using the task structuring criteria. The static view is provided by the information hiding modules, which are determined using the module structuring criteria. Guidelines are then provided for integrating the task and module views to produce a language independent software architecture, which can then be mapped to Ada.
The task structuring criteria are applied first followed by the module structuring criteria, although it is intended that applying the two sets of criteria should be an iterative exercise. The reason for applying the task structuring criteria first is to allow an early performance analysis of the concurrent tasking design to be made, an important consideration in real-time systems.
2.2STEPS IN USING ADARTS AND CODARTS
The ADARTS and CODARTS methods are described in detail in [Gomaa93]. The main steps of the methods are as follows:
(1) Develop environmental and behavioral model of system
ADARTS uses RTSA for analyzing and modeling the problem domain [Ward86], while CODARTS uses the COBRA method [Gomaa93]. COBRA provides an alternative decomposition strategy to RTSA for concurrent and real-time systems. It provides guidelines for developing the environmental model based on the system context diagram. It provides structuring criteria for decomposing a system into subsystems (aggregate objects), which may potentially be distributed. It also provides criteria for structuring a subsystem into objects. Finally, it provides a behavioral approach for determining how the objects within subsystems interact with each other using event sequencing scenarios.
(2) Structure the system into distributed subsystems.
This is an optional step taken for distributed concurrent and distributed real-time applications. The CODARTS/DA method (CODARTS for distributed applications) provides criteria for structuring a system into subsystems that can execute on geographically distributed nodes and communicate over a network by means of messages. CODARTS/DA builds on and substantially refines and extends the ideas from DARTS/DA [Gomaa89a].
(3) Structure the system (or subsystem) into concurrent tasks.
The concurrent tasks in the system (or subsystem of a distributed application) are determined by applying the task structuring criteria. The inter-task communication and synchronization interfaces are defined. Task structuring is applied to the whole system in the case of a non-distributed design. In the case of a distributed design, where the subsystems have already been defined, task structuring is applied to each subsystem. The performance of the concurrent tasking design is analyzed using a combination of the SEI’s rate monotonic analysis approach, based on real-time scheduling theory, and event sequence analysis.
(4) Structure the system into information hiding modules.
The information hiding modules in the system are determined by applying the module structuring criteria. A module aggregation hierarchy is created in which the information hiding modules are categorized.
(5) Develop software architecture.
Tasks, determined using the task structuring criteria of Step 3, and information hiding modules, determined using the module structuring criteria of Step 4, are now integrated to produce a language independent software architecture.
(6) Develop an Ada-based architectural design.
This step is used to address the Ada specific aspects of the design. Application tasks are mapped directly to Ada tasks while information hiding modules are mapped directly to Ada packages. In this step, Ada support tasks are also added and Ada task interfaces are defined. Additional tasks are usually required in an Ada 83 application to address loosely coupled inter-task communication and synchronization of access to shared data [Buhr 84].
(7) Define component interface specifications for tasks and modules. These represent the externally visible view of each component.
(8) Develop the software incrementally.
It should be noted that steps 1-5 are language independent. However, Step 6 maps the software architecture to the Ada language, and is therefore the only step impacted by Ada 95.
3.Ada 95 Features Relevant to ADARTS and CODARTS Designs
Ada 83 is deficient in several areas for concurrent and real-time systems. Implementations for exclusive access to shared data as well as loosely-coupled message communication between tasks require guardian tasks and message-buffering tasks, respectively, that add overhead to the original solution. Interrupt handling is provided through the Ada 83 tasking model which may increase the interrupt latency time. Finally, object-oriented features such as inheritance are absent from the Ada 83 language, however, support for information hiding is provided through the use of Ada 83 packages.
The Ada 95 revision to the Ada language provides several features to address the Ada 83 deficiencies. This paper examines the effects of Ada 95 on ADARTS design solutions. Protected data types, protected interrupt handlers, inheritance of data types and functions, and subprogram access types are shown to simplify ADARTS designs in comparison to the Ada 83 version. An automobile cruise control case study [Gomaa, 1993] will be used to illustrate the Ada 95 advantages.
The following discussion of Ada 95 features is based on version 5.0 of the Ada 95 Reference Manual [RM95].
3.1Protected Types for Shared Data and Loosely-Coupled Communication
ADARTS designs rely heavily on shared data objects for both loosely-coupled message communication and data abstraction modules (DAMs) shared between tasks. In order to implement exclusive access to shared data between tasks in Ada 83, one must use guardian tasks to synchronize access to DAMs and message-buffering tasks to provide message buffering and synchronization for loosely-coupled communication.
Guardian tasks and message-buffering tasks introduce additional threads of control and therefore increase the task overhead of ADARTS designs. The Ada 95 protected data types provide exclusive access to shared data without introducing additional threads of control. Protected types reduce execution overhead and allow for more natural ADARTS designs.
Access to protected data types is controlled by the functions, procedures, or entries that are associated with the protected type. A protected data type provides synchronized access to the data it encapsulates. Protected functions provide read-only access to the encapsulated data. Function calls may be invoked concurrently with other function calls in order to provide multiple-reader access, but may not be invoked concurrently with procedure or entry calls. Protected procedure and entry calls provide mutually-exclusive read / write access to the protected data type. Protected entry calls block until a guard condition is satisfied (e.g. until a queue is not empty). Procedure or entry calls are queued in the order received until they can be serviced. By using the Ada 95 protected type, ADARTS message queues and DAMs can be implemented as packages containing protected data types and thus no longer require a task to control access to the data.
3.2Interrupt Handling
Real-time systems frequently must interface with specialized I/O devices. ADARTS accounts for this by making asynchronous (interrupt-driven) I/O devices an integral part of the design. With the Ada 83 approach, interrupt handlers must be attached directly to the hardware address for the desired interrupt vector and must be encapsulated within an Ada task [Booch, 1987]. In Ada 95, interrupt handlers are attached to procedures of protected units and the interrupts are referenced by the discrete type, Ada.Interrupts.Interrupt_Id. The Ada 95 pragma, Attach_Handler is then used to attach a handler to an interrupt id. Each time an interrupt is triggered, the attached subprogram is executed.
3.3Subprogram Access Types
ADARTS places great emphasis on the control aspects of real-time systems and introduces state transition modules (STMs) to encapsulate state transition tables which are then executed by control tasks. The implementation of STMs can be greatly simplified using the Ada 95 feature of subprogram access types. By defining a subroutine for each action in the state transition table and then declaring an access type to each of the subroutines, a matrix of actions and states can be easily implemented as an array of transitions with each transition containing an action and a next-state. This array would be accessed by input stimulus and current state and would be used to execute the desired action and return the next state.
3.4Inheritance
ADARTS uses inheritance in the design process when dealing with similar objects. However, when mapping the design to the Ada 83 language, ADARTS (83) is forced to design each individual object as its own separate entity without the aid of inheritance. In the Ada 95 revision, inheritance has been added to the Ada language. ADARTS (95) designs can now derive similar classes of objects from a common parent class while still placing each object in its own information hiding module.
4.Cruise Control Case Study
4.1Introduction
The Automobile Cruise Control System will be used as an example for implementing ADARTS designs using Ada 95 versus Ada 83. This paper uses a simplified example of the cruise control system as presented in [Gomaa, 1994]. A larger version of this example is presented in [Gomaa, 1993].
The cruise control system has a driver operated lever with four switch positions: ACCEL, RESUME, and OFF (2 positions). It also has a neutral position. The operation of the lever can be described by a state transition diagram having the following states:
1.Idle. The engine is switched off.
2.Initial. When the driver turns the engine on, the car enters Initial state.
3.Accelerating. When the driver engages the cruise control lever in the ACCEL position, the car enters Accelerating state and accelerates automatically.
4.Cruising. When the driver releases the lever, the current speed is saved as the cruising speed and the car enters Cruising state. In this state, the speed of the car is automatically maintained at the cruising speed.
5.Cruising Off. When the driver presses the brake or alternatively engages the cruise control lever in the OFF position, the car enters Cruising Off state and returns to manual operation, with automatic control suspended.
6.Resuming. When the driver engages the cruise control lever in the RESUME position, the car automatically accelerates or decelerates to the last cruising speed. When it reaches the desired speed, the car returns to Cruising state.
4.2Task Structuring
By applying the ADARTS task structuring criteria, a task architecture diagram is developed as presented in Figure 1.
The concurrent tasks of the Cruise Control System are as follows:
7.Monitor Cruise Control Input. This is an asynchronous I/O task that reads cruise control lever inputs and send them as cruise control requests to the Cruise Control task.
8.Monitor Auto Sensors. This is a passive I/O task that periodically samples the brake and engine sensors at the same frequency. If Monitor Auto Sensors detects a change in the brake or engine status, it sends a message to the Cruise Control task.
9.Monitor Shaft Rotation. This is a high-priority asynchronous input task that is activated for each shaft rotation. This task uses the shaft rotation count to update the current speed.
10.Throttle. This is an asynchronous device output task controlling the throttle position.
11.Display Speed. This is a periodic device output that updates the speed display.
12.Cruise Control. This is control task of the Cruise Control System. This task accepts cruise control messages and takes appropriate action based on the Cruise Control STM.
13.Auto Speed Control. This is a concurrent task providing speed operations that may execute concurrently with the Cruise Control task.
4.3Information Hiding Modules
Once the tasks have been identified, the ADARTS information hiding module structuring criteria are used to identify the packages that will be used in the Cruise Control System. The information hiding modules of the Cruise Control System are categorized by a module aggregation hierarchy as shown in Table 1.
Figure 1 Cruise Control System - Task Architecture Diagram
Modules / OperationsDevice Interface Modules
Engine / Read, Initialize
Brake / Read, Initialize
Cruise Control Lever / Read, Initialize
Throttle / Output, Initialize
Display / Output, Initialize
Shaft / Read, Initialize
Behavior Hiding Modules
Data Abstraction Modules
Current Speed / Read, Update
Desired Speed / Read, Select, Clear
State Transition Modules
Cruise Control STM / Process Event, Current State
Function Driver Modules
Speed Control / Increase Speed, Maintain Speed, Resume Cruising, Deactivate
Table 1 Information Hiding Module Aggregation Hierarchy
4.4Software Architecture
Finally, the task and module views of the Cruise Control System are integrated to form a software architecture. The software architecture for the Cruise Control System is shown in Figure 2.