3.5. Developing a Conceptual Model
It is possible to defer identifying the runtime nature of components until late in the development process. As noted earlier, you can do this by using system components and later manually changing the category in the relevant type, implementation, and subcomponent declarations for these components. In the next few sections, we present an alternative approach where you declare components as abstract and build an architectural component hierarchy. Then you use component extensions to create multi-view architectural representations. For example, in using the Siemens architecture approach [Hofmeister 00], you can include abstract components in a conceptual (runtime neutral) view and later extend these into runtime specific components, creating an execution view of the architecture.
3.5.1. Employing Abstract Components in a PBA Model
In declaring components for the PBA system, rather than using the device category for the pilot interface and the system category for the control components as we did in Table 3-1, we declare them as abstract. For this example, we assume there is a potential for decomposing the pilot interface into a complex interface unit. We could have made the sensor and actuator components abstract as well. However, to simplify the example and to demonstrate that you can mix abstract with runtime-specific categories, we maintain these components as devices. The declarations for this approach are shown in Table 3-2, where we have used the same partitioning and naming convention that is used in Table 3-1. Abstract components are represented graphically by dashed rectangles.
Table 3-2. Abstract Component Declarations for the PBA
A complete system implementation using abstract components is shown in Listing 3-16. We have used an enclosing system, since we plan on instantiating it. However, we could have modeled the enclosing system as abstract as well, converting it to a system model later for instantiation. We have not included the hardware components or their relevant connections in this specification. We add these later in this discussion.
Listing 3-16. Complete PBA System Using Abstract Components
system Complete end Complete; system implementation Complete.PBA_speed_control_ab subcomponents speed_sensor: device sensor.speed; throttle: device actuator.speed; speed_control: abstract control.speed; interface_unit: abstract interface.pilot; connections DC1: port speed_sensor.sensor_data -> speed_control.sensor_data; DC2: port speed_control.command_data -> throttle.cmd; DC3: port interface_unit.set_speed -> speed_control.set_speed; EC4: port interface_unit.disengage -> speed_control.disengage; end Complete.PBA_speed_control_ab;
3.5.2. Detailing Abstract Implementations
In this section, we define the implementation control.speed for the speed_control subcomponent. This is shown in Listing 3-17. We detail this component by partitioning it into two subcomponents, as we did earlier in Listing 3-3. We declare the components read_data and control as abstract and include them as abstract subcomponents in the abstract implementation control.speed. In these declarations we have not included any property associations, specifically no runtime related properties. We will defer these until we generate the execution (runtime) representation. The interfaces and connections for data and control flow are included, since this information is nominally included in a conceptual (runtime neutral) representation. As before, no data types are defined for these interfaces8.
Listing 3-17. Abstract Subcomponents for the control.speed Implementation
abstract read_data features sensor_data: in data port; proc_data: out data port; end read_data; abstract implementation read_data.speed end read_data.speed; abstract control_laws features proc_data: in data port; cmd: out data port; disengage: in event port; set_speed: in data port; end control_laws; abstract implementation control_laws.speed end control_laws.speed; abstract control features command_data: out data port; sensor_data: in data port; set_speed: in data port; disengage: in event port; end control; abstract implementation control.speed subcomponents scale_speed_data: abstract read_data.speed; speed_control_laws: abstract control_laws.speed; connections DC1: port sensor_data -> scale_speed_data.sensor_data; DC2: port scale_speed_data.proc_data -> speed_control_laws.proc_data; DC3: port speed_control_laws.cmd -> command_data; EC1: port disengage -> speed_control_laws.disengage; DC4: port set_speed -> speed_control_laws.set_speed; end control.speed;
3.5.3. Transforming into a Runtime Representation
We transform abstract representations into runtime representations by extending implementations. In so doing, we change the category of an implementation and its corresponding type and transform the categories of the subcomponents that reference those classifiers. We start at the lowest level of the component hierarchy, extending implementations that have subcomponents. We progress upward until we reach the complete system. For this example, we use the same runtime categories as those in the previous section (i.e., those shown in Table 3-1).
First, we extend the implementation control.speed, since it is the lowest level abstract implementation with subcomponents.9 This is shown in Listing 3-18, where a process type control_rt and a process implementation control_rt.speed are declared. The declaration of the type control_rt simply extends the type control, changing the category from abstract to process. There are no other refinements to the type. For the implementation control_rt.speed, the declaration changes the category of the implementation to process and refines (refined to) the category of both subcomponent to threads. Note that all of the characteristics (e.g., features, properties) of their ancestors are inherited by the components defined in an extension declaration (extends). Therefore, only modified elements of an implementation are included in an extension declaration of that implementation. It is not necessary to extend the type or implementation declarations for the abstract implementations read_data.speed and control_laws.speed, since there are no subcomponents in either of these implementations.10
In changing a category, it is important that the features, subcomponents, modes, properties, etc. declared for an abstract component are consistent with the semantics of the new category. For example, an abstract component with a processor subcomponent cannot be extended into a thread component.
Next, we extend the enclosing system type Complete to create Complete_rt and its implementation Complete.PBA_speed_control_ab to create Complete_rt.PBA_speed_control_ab, as shown in Listing 3-18. In the declaration of Complete_rt.PBA_speed_control_ab, we also refine the subcomponents speed_control and interface_unit, changing their category from abstract to a runtime specific category. These choices parallel the categories of the simplified model developed earlier.
Listing 3-18. Transforming the Generic PBA System into a Runtime Representation
process control_rt extends control end control_rt; process implementation control_rt.speed extends control.speed subcomponents scale_speed_data: refined to thread read_data.speed; speed_control_laws: refined to thread control_laws.speed; end control_rt.speed; device interface_rt extends interface end interface_rt; device implementation interface_rt.pilot extends interface.pilot end interface_rt.pilot; system Complete_rt extends Complete end Complete_rt; system implementation Complete_rt.PBA_speed_control_ab extends Complete.PBA_speed_control_ab subcomponents speed_control: refined to process control_rt.speed; interface_unit: refined to device interface_rt.pilot; end Complete_rt.PBA_speed_control_ab;
3.5.4. Adding Runtime Properties
At this point, we have refined the PBA model to include runtime components and subcomponents. However, we have not included runtime properties. For example, values for the timing properties required for a scheduling analysis are not assigned (e.g., the execution time for threads). We can do this in a number of ways. We could add local property associations to the individual abstract declarations, as shown in Listing 3-19 for the abstract types that are refined into threads. For properties that are declared as inheritable, we could modify components that are higher in the component hierarchy, relying on the inheritance of values to subcomponents (e.g., putting the values in the declarations for the abstract component type control).
Listing 3-19. Modifying Declarations with Local Property Associations
abstract read_data features sensor_data: in data port; proc_data: out data port; properties Dispatch_Protocol => Periodic; Compute_Execution_Time => 1 ms .. 2 ms; Period => 50 ms; end read_data; abstract control_laws features proc_data: in data port; cmd: out data port; disengage: in event port; set_speed: in data port; properties Dispatch_Protocol => Periodic; Compute_Execution_Time => 3 ms .. 5 ms; Period => 50 ms; end Control_laws;
We could adopt a policy where we assign relevant properties by extending an abstract component (extends) and adding the property associations into the extension. This allows us to create multiple variants of the component parameterized with different property values. We can also parameterize individual subcomponents with different property values as part of a subcomponent refinement (refined to). An example of adorning the subcomponent refinements is shown in Listing 3-20.
Listing 3-20. Property Associations Adorning Subcomponent Refinements
process implementation control_rt.speed extends control.speed subcomponents scale_speed_data: refined to thread read_data.speed {Dispatch_Protocol => Periodic; Compute_Execution_Time => 1 ms .. 2 ms; Period => 50ms;}; speed_control_laws: refined to thread control_laws.speed {Dispatch_Protocol => Periodic; Compute_Execution_Time => 3 ms .. 5 ms; Period => 50ms;}; end control_rt.speed;
Another approach to centralizing property associations is to include all property declarations for the extended system in the highest system implementation declaration or for a very large system in a limited number of system implementations. To do this we use contained property associations. This is useful when different instances of the same component need to have different property values. We effectively configure an instance of the model through properties and place this configuration information (property associations) in one place instead of modifying different parts of the model. An example is shown in Listing 3-21. We assign values to the Period and Compute_Execution_Time properties for the thread subcomponents using individual property associations. We use a single property association to apply the value Periodic to the Dispatch_Protocol property for both threads.
Listing 3-21. Contained Property Associations within a System Implementation
system implementation Complete_rt.PBA_speed_control_ab extends Complete.PBA_speed_control_ab subcomponents speed_control: refined to process control_rt.speed; interface_unit: refined to device interface_rt.pilot; properties Period => 50ms applies to speed_control.scale_speed_data; Compute_Execution_Time => 1 ms .. 2 ms applies to speed_control.scale_speed_data; Period => 50ms applies to speed_control.speed_control_laws; Compute_Execution_Time => 3 ms .. 5 ms applies to speed_control.speed_control_laws; Dispatch_Protocol => Periodic applies to speed_control.scale_speed_data, speed_control.speed_control_laws; end Complete_rt.PBA_speed_control_ab;
3.5.5. Completing the Specification
In order to complete the specification for the PBA system to the level of the model we developed in the previous section, we need to include hardware components, their relevant interfaces, and their interconnections. For this purpose, we simply use the updated hardware component declarations as shown in Listing 3-4.
In addition, we need to add a bus access feature to the abstract component interface.pilot. A completed PBA speed control system implementation is shown in Listing 3-22. In the table, we have highlighted the portions of Complete.PBA_speed_control_ab that were modified in the extension to Complete_rt.PBA_speed_control_ab.
By adding the hardware subcomponents into the system implementation Complete.PBA_speed_control_ab, we have a system implementation Complete_rt.PBA_speed_control_ab that is comparable to the one we generated in the previous section. That is, with this representation, we can add binding properties and conduct a scheduling analysis as we did in Section 0.
Listing 3-22. A Complete PBA System Implementation
abstract interface features set_speed: out data port; disengage: out event port; BA1: requires bus access Marine.Standard; end interface; device sensor features sensor_data: out data port; BA1: requires bus access Marine.Standard; end sensor; device actuator features cmd: in data port; BA1: requires bus access Marine.Standard; end actuator; system implementation Complete.PBA_speed_control_ab subcomponents speed_sensor: device sensor.speed; throttle: device actuator.speed; speed_control: abstract control.speed; interface_unit: abstract interface.pilot; RT_1GHz: processor Real_Time.one_GHz; Standard_Marine_Bus: bus Marine.Standard; Stand_Memory: memory RAM.Standard; connections DC1: port speed_sensor.sensor_data -> speed_control.sensor_data; DC2: port speed_control.command_data -> throttle.cmd; DC3: port interface_unit.set_speed -> speed_control.set_speed; EC4: port interface_unit.disengage -> speed_control.disengage; BAC1: bus access Standard_Marine_Bus <-> speed_sensor.BA1; BAC2: bus access Standard_Marine_Bus <-> RT_1GHz.BA1; BAC3: bus access Standard_Marine_Bus <-> throttle.BA1; BAC4: bus access Standard_Marine_Bus <-> interface_unit.BA1; BAC5: bus access Standard_Marine_Bus <-> Stand_Memory.BA1; end Complete.PBA_speed_control_ab; system implementation Complete_rt.PBA_speed_control_ab extends Complete.PBA_speed_control_ab subcomponents speed_control: refined to process control_rt.speed; interface_unit: refined to device interface_rt.pilot; properties Period => 50ms applies to speed_control.scale_speed_data; Compute_Execution_Time => 1 ms .. 2 ms applies to speed_control.scale_speed_data; Period => 50ms applies to speed_control.speed_control_laws; Compute_Execution_Time => 3 ms .. 5 ms applies to speed_control.speed_control_laws; Dispatch_Protocol => Periodic applies to speed_control.scale_speed_data, speed_control.speed_control_laws; end Complete_rt.PBA_speed_control_ab;