Main Content

Cross-Release Code Integration

If you have an Embedded Coder® license, you can integrate generated C code from previous releases (R2010a and later) with generated code from the current release when the source models are single-rate and the generated C code is from:

  • Top-model or subsystem build processes that use the nonreusable function code interface.

  • Single or multiple instance model reference build processes that suppress error status monitoring (SuppressErrorStatus is on).

If you can reuse existing code without modification, you can reduce the cost of reverification.

Workflow

Consider this control system model.

The Controller Model block references a model that consists of three components:

  • P1 is a Model block, which references a model developed with a previous release, for example, R2015b. The generated model code, with the standalone code interface, is in the folder P1_ert_rtw.

  • C1 is a Model block, which references a model that you are developing in the current release.

  • P2 is a subsystem block developed with a previous release, for example, R2016a. The generated subsystem code is in the folder P2_ert_rtw.

  • P3 is a Model block, which references a model developed with a previous release, for example, R2016b. The generated model code, with the model reference code interface, is in the folder slprj/ert/P3.

To integrate code from previous releases with generated code from the current release, use this workflow:

  1.  Specify an existing shared code folder

  2.  Import components into current release

  3.  Incorporate components into current release model

Limitations

The cross-release code integration workflow does not support:

  • Export-function models for ERT code.

  • Simulink Function and Function Caller blocks across the boundaries of ERT code generated by different releases.

  • The integration of generated code from releases before R2010a.

  • The import of generated code from the current release into a previous release (forward compatibility).

  • The export of files located in the MATLAB® root folder of the previous release, for example, blockset library files.

  • The export and import of generated code from models with noninlined S-functions.

  • C-API.

At the end of the model build process, the code generation report displays shared files that are directly used by the integration model, for example, Controller. The report does not display shared files used by the components of the model, for example, P1 and P2.

If your model has:

  • A cross-release SIL or PIL block, you cannot run rapid accelerator mode simulations.

  • A Model block that references a model containing a cross-release SIL or PIL block, you cannot run accelerator mode or rapid accelerator mode simulations.

You can run:

  • Top-model SIL simulations of models that contain cross-release SIL or PIL blocks. The models must not contain cross-release AUTOSAR Model blocks.

  • Model block SIL simulations of referenced models that contain cross-release SIL or PIL blocks. The referenced models must not contain cross-release AUTOSAR Model blocks.

For information about other cross-release AUTOSAR code integration limitations, see Import AUTOSAR Code from Previous Releases.

Simulink.Bus Support

To use a bus object as a data type in cross-release ERT code integration, use one of these approaches.

ApproachCode ExportCode Import
Automatic

In the previous release, before generating code, set the DataScope property of the Simulink.Bus object to Auto. Do not assign a value to the HeaderFile property.

The code generator creates the Simulink.Bus data type definition in the default header file, which is located in the code generation folder for the model.

In the current release, before running crossReleaseImport, set the DataScope property of the Simulink.Bus object to Auto.

When you build the integration model, the build process uses the Simulink.Bus data type from the header file in the imported code.

Exported bus

In the previous release, before generating code, specify these properties of the Simulink.Bus object:

  • DataScope — Set to Exported.

  • HeaderFile — Specify a file name, for example, prevRelBusType.

The code generator creates prevRelBusType.h in the shared utility code folder. This header file contains the definition for the Simulink.Bus data type. Use sharedCodeUpdate to add prevRelBusType.h to the shared code folder that ExistingSharedCode specifies.

For R2010a and R2010b, the DataScope property is not available. Do not assign a value to the HeaderFile property. The code generator creates the Simulink.Bus data type definition in modelName_types.h, which is located in the code generation folder for the model.

In the current release, before running crossReleaseImport, set the DataScope property of the Simulink.Bus object to Imported.

When you build the integration model that incorporates the imported SIL or PIL block, the build process uses the Simulink.Bus data type definition in prevRelBusType.h.

If the imported code is from R2010a or R2010b, specify these properties of the Simulink.Bus object:

  • DataScope — Set to Imported.

  • HeaderFile — Set to file path for modelName_types.h, which is in the imported code folder.

When you build the integration model, the build process uses the Simulink.Bus data type definition in modelName_types.h.

Imported bus

In the previous release, before generating code, specify these properties of the Simulink.Bus object:

  • DataScope — Set to Imported.

  • HeaderFile — Specify a path to a file that contains the Simulink.Bus data type definition, for example, aBusType.h.

For R2010a and R2010b, the DataScope property is not available. For the HeaderFile property, specify a path to a file that contains the Simulink.Bus data type definition, for example, aBusType.h.

In the current release, after importing generated code, you do not have to change the Simulink.Bus.

When you build the integration model that incorporates the imported SIL or PIL block, the build process uses the Simulink.Bus data type definition from aBusType.h.

If the imported code is from R2010a or R2010b, specify these properties of the Simulink.Bus object:

  • DataScope — Set to Imported.

  • HeaderFile — Set to aBusType.h.

When you build the integration model, the build process uses the Simulink.Bus data type definition in aBusType.h.

Root-Level I/O Through Global Variables in Generated Code

When imported ERT code from a previous release implements an input or output port through a global variable, the code that is generated from the integration model depends on the properties of the signal connected to the port in the integration model.

If the integration model signal does not map to a generated code variable that has the same name as the signal in the imported code, the generated code:

  • Defines the variable if it is declared but undefined in the imported code.

  • Creates additional code to copy data between the variable generated from the integration model and the variable in the imported code.

If the integration model signal maps to a variable with the same name as the signal in the imported code, the variable used by the imported code is also used by the code generated from the integration model. You must use a compatible storage class for the signal.

Storage Class PropertyProperty Value Support
TypeUnstructured only
Data access

Cannot connect a port implemented as a Pointer variable in the imported code to a signal of the same name that is implemented through a Direct storage class in the integration model

Cannot connect a port implemented as a Direct variable in the imported code to a signal of the same name that is implemented as a Pointer in the integration model

Data scope

If the imported code declares but does not define the variable (i.e. code is generated from a signal that uses the Imported value), then one of the following is required:

  • The integration model uses the Exported value.

  • External code defines the variable.

If the imported code defines the variable (i.e. code is generated from a signal that uses the Exported value):

  • For signals in the integration model that are connected to root-level I/O ports:

    • Set the EnableDataOwnership configuration parameter to on.

    • Use a custom storage class with these properties:

      • TypeUnstructured

      • Data accessDirect

      • Data scopeExported

      • Owner – Non-empty value that is not the name of the integration model. For example, the value can be the name of the imported component.

  • For signals in the integration model that are not connected to root-level I/O ports, use a custom storage class with these property values:

    • Data scope - Imported

    • Data access - Direct

Communicate Between Current and Previous Release Components Through Global Data Stores

Current and previous release components can communicate through global data stores associated with Simulink.Signal objects in the MATLAB base workspace or a Simulink data dictionary. The workflow described here applies to cross-release ERT code integration.

Code Generation Configuration

Before generating model component code in the old release, configure data store memory to use a storage class that imports external code.

If a top-model or subsystem build process generates the code, set the Storage class property of the Simulink.Signal objects to one of these classes:

  • ImportedExtern

  • ImportedExternPointer

  • ImportFromFile custom storage class

If a model reference build process generates the code, you can also use these classes:

  • ExportedGlobal

  • ExportToFile custom storage class

Import Configuration

In the current release, before you run crossReleaseImport, define a Simulink.Signal object in the MATLAB base workspace or a Simulink data dictionary for each global data store of the component that you want to import:

  1. For the object name and the Data type, Complexity, and Dimensions object properties, specify values that match values of the corresponding object in the component that you want to import.

  2. For the Storage class property, specify a value that is compatible. If the previous release value is ImportedExtern, specify one of these values for the current release:

    • ImportedExtern

    • ExportedGlobal

    • ImportFromFile or ExportToFile custom storage class.

    If the previous release value is ImportedExternPointer, then specify ImportedExternPointer for the current release.

  3. For the Identifier property, specify a matching value only if the property is specified for the object in the component that you want to import.

  4. Save the Simulink.Signal objects. The objects are required each time you simulate or build the imported SIL or PIL block.

For more information, see Data Stores in Generated Code.

Parameter Tuning

The cross-release ERT code integration workflow supports parameter tuning in an integration model that contains component code with tunable parameters from previous releases.

In the current release, before you run crossReleaseImport, for each tunable parameter of the component that you want to import:

  1. Define a Simulink.Parameter object in the MATLAB base workspace or a Simulink data dictionary.

  2. For the object name and the Data type, Complexity, and Dimensions object properties, specify values that match the previous release object values. If the variable in the imported source code does not have the same name as the object, for the Identifier property, specify a value that matches the variable name.

  3. If the previous release object uses the GetSet custom storage class, specify:

    Support of the GetSet custom storage class from a previous release applies only for R2011a and later releases.

For code generated by a top-model or subsystem build process in a previous release, these limitations apply:

  • If a tunable parameter specified by a Simulink.Parameter object in the previous release has storage class set to ExportedGlobal and the storage class of the Simulink.Parameter object in the current release is also ExportedGlobal, an error occurs when you build the integration model.

  • On a Mac operating system, if a tunable parameter specified by a Simulink.Parameter object in the previous release has storage class set to ExportedGlobal, you cannot build the integration model if the storage class of the Simulink.Parameter object in the current release (with the same name or alias) is ImportedExtern. To work around this limitation, modify the default settings:

    1. Get the build tool from the default toolchain.

      tc = coder.make.getDefaultToolchain;
      cComp = tc.getBuildTool('C Compiler');

    2. Extract the C compiler standard options.

      stdMaps = cComp.SupportedStandard.getLangStandardMaps;
      optionValues = stdMaps.getCompilerOptions('*');  

    3. Remove -fno-common from the standard options for the C and C++ compilers.

      optionToRemove = '-fno-common';
      optionsToKeep = strrep(optionValues, optionToRemove, '');
      c_standard_opts_id = '$(C_STANDARD_OPTS)';
      
      custToolChainOpts = get_param(model,'CustomToolchainOptions');
      custToolChainOpts{2} = ...
         strrep(custToolChainOpts{2}, c_standard_opts_id, optionsToKeep);
      
      set_param(model, 'CustomToolchainOptions',custToolChainOpts);

Use Multiple Instances of Code Generated from Reusable Referenced Model

Using a reusable referenced model, you can specify unique model argument values for each instance of the referenced model in a parent model. Import previously generated code for the reusable referenced model into the current release as a parameterized cross-release SIL or PIL block, and then insert multiple instances of the block into an integration model. For each block instance, you can specify unique model argument values.

  1. Update existing shared code folder.

    sharedCodeUpdate(sourceFolder,destinationFolder)

  2. Import generated code for the reusable referenced model into the current release as a parameterized cross-release block, for example, a SIL block.

    handleSILBlock = crossReleaseImport(reusableReferencedModelcodeLocation, ...
     configSetIntegrationModel, 'SimulationMode', 'SIL');

  3. In the integration model, replace, for example, two instances of the referenced model with instances of the cross-release SIL block.

    open_system(integrationModel);
    
    blockInstanceName1 = 'refModelInstanceName1';
    blockinstanceName2 = 'refModelInstanceName2';
    
    SILBlockFullName = getfullname(handleSILBlock);
    replace_block(integrationModel, 'Name', blockInstanceName1, ...
                  SILBlockFullName, 'noprompt');
    replace_block(integrationModel, 'Name', blockInstanceName2, ...
                  SILBlockFullName, 'noprompt');

  4. Suppose the reusable referenced model has model arguments paramA and paramB, and the values for the referenced model instances, refModelInstanceName1 and refModelInstanceName2, are workspace variables. In this case, you can specify argument values for the cross-release block instances that are workspace variables.

    pathToBlockInstanceName1 = [integrationModel, '/', blockInstanceName1];
    pathToBlockInstanceName2 = [integrationModel, '/', blockInstanceName2];
    
    set_param(pathToBlockInstanceName1, 'paramA', 'paramA_instName1');
    set_param(pathToBlockInstanceName1, 'paramB', 'paramB_instName1');
    
    set_param(pathToBlockInstanceName2, 'paramA', 'paramA_instName2');
    set_param(pathToBlockInstanceName2, 'paramB', 'paramB_instName2');
    

  5. To specify unique model argument values for the block instances in the integration model, assign values to the workspace variables, paramA_instName1, paramB_instName1, paramA_instName2, and paramB_instName2.

Compare Simulation Behavior of Model Component in Current Release and Generated Code from Previous Release

In a previous release, suppose that you developed a model component, generated code for the component, and tested and deployed the generated code. Now, in the current release, you want to add features to the model component and use the model component in system development and code generation. Before you proceed, you can compare the functional behavior of the model component and the generated code from the previous release.

To test the numerical equivalence between the model component and the generated code from the previous release, use Simulink Test™. With the Test Manager (Simulink Test), you can perform back-to-back tests and output comparisons:

  1. Bring the model component into the current release as a Model block with the Simulation mode block parameter set to Normal.

  2. With the Model block, create a top model that specifies test input data.

  3. Import the code generated in the previous release into the current release as a SIL block.

  4. With the SIL block, create another top model that specifies the same the test input data.

  5. In the Test Manager, create an equivalence test case that runs simulations of the top models and compares outputs.

  6. Run the test case and review results.

For more information, see Test Two Simulations for Equivalence (Simulink Test).

Note

If you want to compare the behavior of generated code from the current and previous release, in step 1, specify these Model block parameters:

  • Set Simulation mode to Software-in-the-loop (SIL) or Processor-in-the-loop (PIL).

  • Set Code interface to Top model.

Import AUTOSAR Code from Previous Releases

If you install the Embedded Coder Support Package for AUTOSAR Standard, you can import into the current release AUTOSAR component code that you generated in a previous release.

When you run crossReleaseImport, the function imports the AUTOSAR code as a cross-release Model block instead of a SIL or PIL block. The Simulation mode parameter of the Model block is set to Software-in-the-loop (SIL) or Processor-in-the-loop (PIL). Incorporate the Model block into the current release model.

These limitations apply:

  • The cross-release workflow does not support per-instance memory that accesses NVRAM.

  • Tunable parameters must be mapped to AUTOSAR calibration parameters or AUTOSAR internal calibration parameters.

  • If the original model uses variants or symbolic dimensions (dimension variants), the imported model can use only the same variant and symbolic dimension configuration that was used when generating the code in the previous release.

See Also

| |

Related Topics