Documentation

Buses in the Generated Code

If you have Simulink® Coder™, the various techniques for defining buses are essentially equivalent for simulation, but the techniques 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 Group Signals into Structures in the Generated Code Using Buses.

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 signal 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 array of buses signals produces structures with a specific format. See Code Generation for Arrays of Buses.

Control Data Types of Initial Condition Structure Fields

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.

Inline Numeric Values of Structure Fields in the Generated Code

If you set Configuration Parameters > Optimization > Signals and Parameters > Default parameter behavior 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.

Generate Tunable Structure Specified Directly in a Block Dialog Box

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.

GoalTechnique

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 struct by using typed expressions to set the field values.

Generate Tunable Structure Stored in a Variable or Parameter Object

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.

GoalTechnique

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 double. The generated algorithm uses explicit typecasts to reconcile the data type mismatches.

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 Simulink.Bus object to control the data types of the fields and the signal elements simultaneously.

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 Simulink.Bus object to control the data types of the structure fields and the signal elements simultaneously.

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.

Use Untyped Expressions to Set Field Values

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 signal, 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 signal 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.

Store Data Type Information in Structure Fields

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 signal 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 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.

Use Bus Object as Data Type of Initial Condition Structure

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 signal myBusSig with these signal elements.

myBusSig
   signalElement1 (int32)
   signalElement2 (boolean)
   signalElement3 (single)

  1. Open the Bus Editor.

    buseditor

  2. Create a bus object, myBus, that corresponds to the bus signal.

  3. 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;
    

  4. To represent the structure, create a Simulink.Parameter object.

    initStruct = Simulink.Parameter(initStruct);
    

  5. Use the parameter object to specify an initial condition for the bus signal. For example, in a Unit Delay block dialog box, set Initial condition to initStruct.

  6. Use the bus object to specify the data type of the parameter object.

    initStruct.DataType = 'Bus: myBus';

  7. Use the bus object to specify the data type of the bus signal. 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 When to Use Bus Objects.

Configure Data Types for Existing Structure

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.

Check for Mismatched Data Types with Model Advisor

To detect when the data types of structure fields are not consistent with the associated bus signal elements, in the Simulink Editor, use the Analysis > Model Advisor > By Product > Simulink Check structure parameter usage with bus signals check.

Limitations for Virtual Buses Crossing Model Reference Boundaries

If you use a bus signal 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 Bus Data Crossing Model Reference Boundaries. For more information about bus virtuality, see Virtual and Nonvirtual Buses.

Code Generation for Arrays of Buses

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 Group Signals into Structures in the Generated Code Using Buses.

Related Examples

Was this topic helpful?