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');
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.
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.
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
.
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
.
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.
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.
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
Right-click the
Sensor1
component. From the context menu, select Test Harness > Create for 'Sensor1'.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
.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
.
To open the mock architecture model, double-click the scServiceInterfaceExample_MockArchitecture1
block in the test harness model.
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
.
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.
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
.
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.
Click Run in the Simulation tab to simulate the harness.
Open the Simulation Data Inspector to observe logged output of the mock client and
Sensor1
component.
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.
In the Inspect tab, select and deselect
Data
anddata from callfetchData:1
signals to observe if the signals match.Similarly, select and deselect
resetData @ Sensor1
andresetData from callreset:1
signals to observe if the signals match.
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.
The generated code implements this abstract class for the referenced sensor model.
You also use the generated abstract class to construct the class of the controller.
The controller subsequently calls the service from the SensorCmd
abstract class.
See Also
Function Element | Function Element Call | Simulink Function | Function
Caller | Function-Call Subsystem | addServiceInterface
| setFunctionPrototype
| getFunctionArgument