If you have Simulink®
Coder™, whether you use a virtual or nonvirtual bus can make a significant
difference in the efficiency, size, and readability of generated code. For example, a
nonvirtual bus appears as a structure in generated code, and only one copy exists of any
algorithm that uses the bus. The use of a structure in the generated code can be helpful
when tracing the correspondence between the model and the code. For example, here is the
generated code for the Bus Creator block in the ex_bus_logging
model.
A virtual bus does not appear as a structure or any other coherent unit in generated code. A separate copy of any algorithm that manipulates the bus exists for each element. In general, virtual buses do not affect the generated code.
To group signals into structures in the generated code, use nonvirtual buses. See Organize Data into Structures in Generated Code (Simulink Coder).
When you create a MATLAB® structure to initialize a bus that contains non-double signal elements, you need to set the values of structure fields. The technique that you choose to set the values can influence the efficiency and readability of the generated code. See Control Data Types of Initial Condition Structure Fields.
When you generate code for a bus that is input to or output from a referenced model, there are some code generation limitations. See Limitations for Virtual Buses Crossing Model Reference Boundaries.
Code generation for arrays of buses produces structures with a specific format. See Code Generation for Arrays of Buses.
You can use a MATLAB structure to initialize the signal elements in a bus. See Specify Initial Conditions for Bus Signals.
If the signal elements of the target bus use numeric data types other than
double
, in general:
To avoid manually matching the field data types with the data types of the signal elements, use untyped expressions to set the field values. As you develop and rapidly prototype a model, use this technique for convenience.
To generate more efficient production code and to avoid floating-point storage in the code, match the data types of the structure fields with the data types of the corresponding signal elements.
The technique that you choose can influence the efficiency and readability of the generated code.
For examples and more information about tunable initial conditions in the generated code, see Control Signal and State Initialization in the Generated Code (Simulink Coder).
If you set the Default parameter behavior
configuration parameter to Inlined
, by default, the
field values of the initial condition structure appear in the generated code as
inlined numbers (non-tunable). For these structures, use untyped expressions to
set the field values in Simulink. The field values do not require data types because the structure
is not tunable in the generated code.
However, if you later set Default parameter behavior to
Tunable
or apply a storage class to the structure
by using a Simulink.Parameter
object, the code can contain
floating-point storage and inefficient explicit typecasts and bit shifts. To
avoid these issues, consider matching the data types of the structure fields
with the data types of the corresponding signal elements.
Suppose that you specify an initial condition structure directly in a block
dialog box, or in a Simulink.Signal
object, with an expression
such as struct('signal1',5,'signal2',7.2)
(instead of storing
the structure in a variable or Simulink.Parameter
object). In
this case, to generate a tunable structure in the code, you set
Default parameter behavior to
Tunable
.
Use the table to decide how to control the data types of the fields in these initial condition structures.
Goal | Technique | |
---|---|---|
Use a nonvirtual bus. | Use untyped expressions to set the field values. | |
Use a virtual bus. | Avoid manually matching the field data types with those of the signal elements. | Use untyped expressions to set the field values. |
Generate more efficient code and avoid floating-point storage. | Match the structure field data types with the
signal element types. Store the data type information in
the |
Suppose that you store an initial condition structure in a variable or
Simulink.Parameter
object that you create in the base
workspace or a data dictionary. For example, you use this technique to share the
structure between multiple blocks, or to generate a tunable structure when you
set Default parameter behavior to
Inlined
. In this case, use the table to decide
how to control the data types of the fields in the initial condition
structure.
Goal | Technique | |
---|---|---|
Avoid manually matching the field data types with those of the signal elements. | Use untyped expressions to set the field values. In
the generated code, the structure fields use the data
type | |
Generate more efficient code and avoid floating-point storage. | Match the structure field data types with the
signal element types. Store the data type information in
the structure fields or use a
To use the Model Advisor to check your model for potentially expensive data type mismatches, see Check structure parameter usage with bus signals. | |
Initialize an array of buses in a referenced model by using an array of structures. Pass the array of structures to the referenced model as the value of a model argument in the Model block. | Match the structure field data types with the
signal element types. Store the data type information in
the structure fields or use a
If you do not pass the structure to the referenced model as a model argument, follow the other guidelines for nonvirtual buses to decide how to control the data types. |
You can use untyped expressions to set the structure field values. The fields
implicitly use the data type double
. Set the field values to
represent the ideal, real-world initialization values.
You avoid manually matching the field data types with the data types of the corresponding signal elements. However, depending on the virtuality of the bus, the method that you use to apply the initial condition, and other factors, you can introduce floating-point storage and potentially inefficient typecasts in the generated code.
Suppose that you create a bus myBusSig
with these signal
elements. Each element uses a specific data type.
myBusSig signalElement1 (int32) signalElement2 (boolean) signalElement3 (single)
Create an initial condition structure initStruct
. Use
untyped expressions to specify the field values. Optionally, to enhance
readability of the Boolean field signalElement2
, use the
value false
instead of 0
.
initStruct.signalElement1 = 3; initStruct.signalElement2 = false; initStruct.signalElement3 = 17.35;
If you use the function Simulink.Bus.createMATLABStruct
to create the structure, the function stores data type information in the
structure fields. After you create the structure, you can optionally use untyped
expressions to change the field values. See Use Simulink.Bus.createMATLABStruct to Create Structure.
To store data type information in the structure fields, use typed expressions
to set the field values, or use the function
Simulink.Bus.createMATLABStruct
to create the
structure. Use these techniques to generate efficient code by eliminating
floating-point storage and potentially inefficient explicit typecasts.
To avoid manually applying new data types to the structure fields when you
change the data types of the corresponding signal elements, consider using a
Simulink.Bus
object to control the data types in the
structure and the bus simultaneously.
Use Typed Expressions to Set Field Values. Suppose that you create a bus myBusSig
with this
hierarchy of signal elements. Each element uses a specific data type.
myBusSig signalElement1 (int32) signalElement2 (boolean) signalElement3 (single)
Create an initial condition structure initStruct
by
using typed expressions to set the field values. Match the data types of the
fields with the data types of the corresponding signal elements.
initStruct.signalElement1 = int32(3); initStruct.signalElement2 = false; initStruct.signalElement3 = single(17.35);
The structure fields store data type information. If you later change the data type of a signal element, manually apply the new data type to the corresponding structure field.
To match a fixed-point data type, set the field value by using a fi
(Fixed-Point Designer) object.
Change Field Value by Preserving Data Type Information. Suppose that you change the value of a field in an existing initial
condition structure. To preserve the data type information in the field you
can use subscripted assignment, with the syntax
(:)
.
initStruct.signalElement3(:) = 16.93;
If you do not use subscripted assignment, you must remember to preserve the data type by using a typed expression.
initStruct.signalElement3 = single(16.93);
If you do not use either of these techniques, the field loses the data type information.
initStruct.signalElement3 = 16.93; % Field data type is now 'double'.
Use Simulink.Bus.createMATLABStruct
to Create
Structure. You can use the function
Simulink.Bus.createMATLABStruct
to create a
structure whose fields all have ground values, typically
0
. If you configure the data types of the signal
elements before using the function, for example by setting the output data
types of the blocks that generate the signal elements, each field in the
output structure uses the same data type as the corresponding signal
element. The fields store the data type information as if you use typed
expressions to set the values.
You can initialize some of the signal elements with a value other than
ground by passing a partial structure to the function. When you create this
partial structure, match the data type of each field with the data type of
the corresponding signal element by using typed expressions. For more
information and examples, see Simulink.Bus.createMATLABStruct
.
When you later change the value of a field in the structure, choose one of these techniques to set the new value:
Untyped expression. The field value no longer stores the data type information.
Typed expression or subscripted assignment. The field value continues to store the data type information.
Whether you store data type information in the structure fields or use untyped
expressions to set the field values, you can use a Simulink.Bus
object as the data type of the entire initial condition structure. You can then
manage the field values and data types independently.
If you use this technique, consider using untyped expressions to set the field
values. Then, you do not need to match the field data types manually when you
change the data types of the signal elements. To control the data types of the
fields and the signal elements, use the DataType
property
of the elements in the Bus
object.
Suppose that you use a Bus Creator block to create a bus
myBusSig
with these signal elements.
myBusSig signalElement1 (int32) signalElement2 (boolean) signalElement3 (single)
Open the Bus Editor.
buseditor
Create a Bus
object, myBus
,
that corresponds to the bus.
Create an initial condition structure
initStruct
. Used untyped expressions to set
the field values. To enhance readability of the field
signalElement2
, use the Boolean value
false
instead of 0
.
initStruct.signalElement1 = 3; initStruct.signalElement2 = false; initStruct.signalElement3 = 17.35;
To represent the structure, create a Simulink.Parameter
object.
initStruct = Simulink.Parameter(initStruct);
Use the parameter object to specify an initial condition for the
bus. For example, in a Unit Delay block dialog box,
set Initial condition to
initStruct
.
Use the Bus
object to specify the data type of
the parameter object.
initStruct.DataType = 'Bus: myBus';
Use the Bus
object to specify the data type of
the bus. For example, in the Bus Creator block dialog
box, set Output data type to Bus:
myBus
.
During simulation and in the generated code, the structure fields and the
signal elements use the data types that you specify in the Bus
object. Before simulation and code generation, the parameter object casts the
structure fields to the data types that you specify in the Bus
object.
For basic information about Bus
objects, see Specify Bus Properties with Simulink.Bus Objects.
To remove data type information from all the fields of a structure, you can
write a custom function that replaces the field values with
double
numbers. Use the example function castStructToDbl
as a template.
To convert a structure that uses doubles to one that stores data type
information, you can create a reference structure using the function Simulink.Bus.createMATLABStruct
. You can then write a custom
function to cast the field values to the data types in the reference structure.
Use the example function castStructFromDbl
as a template.
To detect when the data types of structure fields are not consistent with associated bus elements, use the Model Advisor.
On the Modeling tab, click Model Advisor.
Click OK.
Select By Task > Modeling Signals and Parameters using Buses > Check structure parameter usage with bus signals.
Click the Run This Check button.
If you use a bus as an input to or an output from a referenced model (Model block):
You cannot configure the I/O arguments step
method
style of C++ class interface for the referenced
model.
As a workaround, use a nonvirtual bus instead. Alternatively, use the
Default
style of C++ class
interface.
You cannot configure function prototype control for the referenced model.
As a workaround, use a nonvirtual bus instead.
For more information about using buses as inputs to or outputs from a referenced model, see Nonvirtual Buses at Model Interfaces. For more information about bus virtuality, see Types of Composite Signals.
When you generate code for a model that includes an array of buses, a
typedef
that represents the underlying bus type appears in
the *_types.h
file.
Code generation produces an array of C structures that you can integrate with legacy C code that uses arrays of structures. As necessary, code for bus variables (arrays) is generated in the following structures:
Block IO
States
External inputs
External outputs
Here is a simplified example of some generated code for an array of buses.
For basic information about code generation for nonvirtual buses, which appear in the code as structures, see Organize Data into Structures in Generated Code (Simulink Coder).