Main Content

Model Service-Oriented Communication Between Sensors

This example shows how to model service-oriented communication starting from a System Composer™ software architecture and implementing component behavior with Simulink®. Modeling service-oriented communication from the architectural level allows you to design your service interface and components independent of the implementation of their functionality.

In this example, the model slexServiceInterfaceExample consists of a controller component, Controller, and two sensor components, Sensor1 and Sensor2. You model the two sensor components as two different instances of the same referenced model, scSensorModelRef. The referenced model defines two services: reset, which resets the sensor from drifting over time, and fetchData, which reads the latest sensor values. You specify a single service interface between the controller and the two sensor instances, which allows the controller to call reset or fetchData for a specific instance of the referenced sensor component.

Open the model.

model = systemcomposer.openModel('scServiceInterfaceExample.slx');

scServiceInterfaceExample.png

Both instances of the referenced sensor model output a sine wave with different amplitudes. You can view and specify the amplitudes in the Model Data Editor of the top model. To access the Model Data Editor, go to the Modeling tab, and in the Design section, select Model Data Editor.

ModelDataEditor.png

Component-to-Component Interaction Through Client and Server Ports

The controller component interacts with the sensor components using server ports and client ports. The ball and socket icons represent server and client ports respectively.

PropertyInspector.png

Define Service Interface

You define the service interface sensorCmd through the Interface Editor. To access the Interface Editor, go to the Modeling tab, and in the Design section, select Interface Editor. The service interface sensorCmd is used across referenced models and stored in the data dictionary slexServiceInterfaceExample.sldd.

The function prototype defines the function name and parameters. Below the function prototype are the parameters of the function represented as function arguments. For each function argument, you can specify a value in the Type, Dimensions, Units, and Complexity columns. Note that sensorCmd contains two functions, reset and fetchData. The reset function has one function argument specified as resetSignal. The fetchData function has one function argument specified as data.

InterfaceEditor.png

Implement Behavior for Functions

The behaviors of the functions specified in the service interface are defined in referenced models. In service-oriented architectures, you implement these function behavior models in export-function models. For more information, see Export-Function Models Overview.

Server Component Model

The scSensorMdlRef model is an export-function model representing the behavior of the sensors. In scSensorMdlRef, you define the two functions reset and fetchData in their respective Simulink Function blocks. The reset function has a Boolean input argument, resetData. By default, resetData is false, and thus the reset function does not reset the sensors until the controller sets resetData to true.

ServiceInterfaceForMultiplyInstancedComponentExample_05.png

Client Component Model

The scControllerMdlRef model is an export-based model representing the behavior of the controller. In scControllerMdlRef, each sensor has a requestReset and requestFetchData Function-Call Subsystem.

ServiceInterfaceForMultiplyInstancedComponentExample_06.png

For more information on the structure and functionality of the server and client models, see Model Client-Server Communication Using Function Ports.

Schedule Functions and Simulate

To run the model, use the sim function.

sim('scServiceInterfaceExample');

To view the sequence of function calls throughout the simulation of the model, open the Sequence Viewer.

Go to the Simulation tab, in the Review Results section, select Sequence Viewer.

SequenceViewer.png

Test Service Interface Using Test Harness

You can test your service interface by creating a test harness for the components with client and server ports.

Create Test Harness

  1. Right-click the Sensor1 component. From the context menu, select Test Harness > Create for 'Sensor1'.

  2. In the Create Test Harness dialog box, you can specify the inputs, outputs, and other options. By default, the harness saves with the model file, scServiceInterfaceSensorExample_Harness1.

  3. Click OK to create the test harness.

At the center of the harness is a Model block referencing a mock architecture model. The vertical subsystem contains signal specification and routing.

System Composer and Simulink® Test™ autogenerate a software architecture test model, scServiceInterfaceSensorExample_MockArchitecture1, a Simulink behavior model scServiceInterfaceSensorExample_MockClients1, and the test harness model, scServiceInterfaceSensorExample_Harness1.

sensor1-test-harness.png

To open the mock architecture model, double-click the scServiceInterfaceExample_MockArchitecture1 block in the test harness model.

sensor1-mock-architecture.png

The mock architecture contains a Reference Component referencing the component under test, Sensor1. The component under test is connected to the MockClients component which references a new, autogenerated Simulink behavior model, scServiceInterfaceExample_MockClients1.

Implement Behavior of Mock Components

Your component under test is the Sensor1 component which is the server providing services to the Controller. The test harness isolates the Sensor1 component from the entire model by keeping the component as-is in a reference component. Implementation of the mock client is necessary to ensure the server component is behaving as expected.

Open the mock client model by double-clicking the MockClients1 component in the scServiceInterfaceExample_MockArchitecture1 architecture model.

The controller calls the reset function and the fetchData function. To keep the test output of the mock client component as expected, you must supply the test input and output to the mock client.

reset Function Caller

To implement the mock behavior of calling the reset function, you can add a Data Type Conversion block connected to a Pulse Generator block to ensure the client is recieving a boolean value for resetStatus.

mock-clients-callreset.png

fetchData Function Caller

To implement the mock behavior of calling the fetchData function, you can add an Outport block to log the output of the function call.

mock-clients-callfetchData.png

Log Signals

To log the signals of the mock client and Sensor1 components, you can add Outport blocks.

Adding Outport blocks to the behavior models will propogate output signals to the harness model. In the harness model, add three Outport blocks to log the signals of the mock client and Sensor1.

sensor1-test-harness-with-logging.png

Run Test Harness

To run the test, you must add a step transition. Open the Test Sequence (Simulink Test) block in the harness model, in the Transition column of the Run step, add true as the condition for transitioning to the next step.

  1. Click Run in the Simulation tab to simulate the harness.

  2. Open the Simulation Data Inspector to observe logged output of the mock client and Sensor1 component.

simulation-data-inspector.png

In this example, the component under test is Sensor1, so in the Simulation Data Inspector, you can observe the signals from the sensor and mock client components to ensure they are as expected.

  1. In the Inspect tab, select and deselect Data and data from callfetchData:1 signals to observe if the signals match.

  2. Similarly, select and deselect resetData @ Sensor1 and resetData from callreset:1 signals to observe if the signals match.

signal-selection.png

If the signals match between the sensor and client component, your test is complete. For more information on testing service interfaces, see Test Your Service Interface Using Simulink Test.

Generate Code

To generate code for the model, which includes the service interface sensorCmd, use this command.

rtwbuild('scServiceInterfaceExample');

Simulink generates the service interface SensorCmd as an abstract class, which enables implementation to be separate from the interface.

The generated code contains an entry-point for each function of the component. For more information, see Generate Code for Export-Function Model.

AbstractClass.png

The generated code implements this abstract class for the referenced sensor model.

Functions.png

You also use the generated abstract class to construct the class of the controller.

Controller.png

The controller subsequently calls the service from the SensorCmd abstract class.

CallSite.png

See Also

| | | | | | |

Related Topics