Configure Default C Code Generation for Categories of Data Elements and Functions - MATLAB & Simulink (original) (raw)

Reduce the effort of preparing a model for C code generation by specifying default configurations for categories of data elements and functions across a model. Applying default configurations can save time and reduce the risk of introducing errors in code, especially for larger models and models from which you generate multi-instance code.

You must have set up the example environment, as described in Set Up Example Environment.

Set Up Example Environment

  1. Open these external source and header files. These files define and declare the external data type and data that the generated code uses.
    openExample('ecoder/ConfiigDefaultDataAndFuncCodeGenProgExample')
    File Description
    exDblFloat.h Defines the project data type alias for double, DBL_FLOAT. Simulink® uses the PreLoadFcn callback specified for the model to parse this header file and create a correspondingSimulink.AliasType object.
    exInDataMem.c Includes exInDataMem.h and defines variableex_input1.
    exInDataMem.h Includes exDbFloat.h and declares variableex_input1.
    exInDataLut.c exInDataLut.c includesexInDataLut.h and defines variables ex_input2, ex_input3, andex_input4.
    exInDataLut.h Includes exDbFloat.h and declares variablesex_input2, ex_input3, andex_input4.
    exCodeDefs.sldd Data dictionary
    ConfigurationInterface.slx Example model.
  2. Open the example model ConfigurationInterface.Example model ConfigurationInterface.
  3. In the apps gallery, open the Embedded Coder app.

Configure Default Code Generation for Data

This example shows how to use the Code Mappings editor to specify code generation requirements for model data. The model uses multiple execution rates and is configured for single-instance usage.

This example assumes these code generation requirements for data:

Although the model uses single instances of some data, the example configures default settings to demonstrate different types of mappings. As you add blocks to the model, new data elements acquire the default code generation mappings.

Configure Default Settings for Root Inports

Specify an external header file that declares input data. Three of the four root inports read input from variables declared in header file exInDataLut.h. Set that header file as the default.

  1. Open model ConfigurationInterface.
  2. Open the Embedded Coder app.
  3. In the C Code tab, select > . This opens the Code Mappings editor Data Defaults tab.
  4. In the Data Defaults tab, expand Inports and Outports. Then, select Inports.
  5. Set the storage class to ImportFromFile.
  6. Click the Icon to configure additional code mapping properties icon and set Header File toexInDataLut.h.

Configure Default Settings for Model Parameters

Configure default settings for model workspace parameters that you want to be tunable.

  1. In the Code Mappings editor, click the Data Defaults tab.
  2. In the Data Defaults tab, expandParameters.
  3. In the row for Model parameters, click the text 'Auto' will be inlined. The Model Configuration Parameters dialog box opens to the > pane. Set Default parameter behavior toTunable. Apply the change and close the dialog box. In the Code Mappings editor, the text to the right of Model parameters now reads 'Auto' will be tunable.
  4. To include global variable definitions and declarations in the generated code for model parameters, set the storage class for the Model parameters category to ExportedGlobal.

Define Memory Section for Internal Data

Define a memory section for storing unit delay X, data that is internal to the model.

  1. Open the Embedded Coder Dictionary by selecting > .
  2. In the Embedded Coder Dictionary, on the left pane, click Memory Section.
  3. Click Create.
  4. In the new row of the table, name the new memory sectioninternalDataMem. Also set:
    • Pre Statement to #pragma start INTERNALDATA
    • Post Statement to #pragma end INTERNALDATA
    • Statements Surround to Group of variables
  5. Close the dictionary.

For more information, see Control Data and Function Placement in Memory by Inserting Pragmas.

Configure Default Settings for Internal Data

Set up the default code generation configuration for internal data to include memory section internalDataMem.

  1. In the Code Mappings editor, click the Data Defaults tab.
  2. In the Data Defaults tab, expandSignals.
  3. Select category Signals, states, and internal data.
  4. Click the Icon to configure additional code mapping properties icon and set Memory Section tointernalDataMem.

Configure Default Settings for Root Outport

Specify the default external header and definition files for variables to which the generated code writes output.

  1. In the Code Mappings editor, click the Data Defaults tab.
  2. In the Data Defaults tab, expand Inports and Outports.
  3. Select category Outports.
  4. Set the storage class to ExportToFile.
  5. Click the Icon to configure additional code mapping properties icon and set Header File toexSysOut.h and Definition File toexSysOut.c.

Apply Default Configurations to Individual Data Elements

Unless you explicitly map individual data elements to alternative storage class settings, the Code Mappings editor assumes the storage class for elements isAuto. When the storage class for a data element isAuto, the code generator might eliminate or change the representation of relevant code for optimization purposes. If optimizations are not possible, the code generator applies the model default configuration.

For this example, configure the code generator to apply the default storage class setting to these data elements:

  1. In the Code Mappings editor, click the Inports tab.
  2. Select the rows for inports In2, In3, andIn4. Then, for one of the selected inports, set the storage class to Model default: ImportFromFile. The storage class for the three selected inports changes to Model default: ImportFromFile.
  3. Click the Outports tab. For outport Out1, set the storage class to Model default: ExportToFile.
  4. Click the Parameters tab. Expand Model Parameters. Then, for parameter K1, set the storage class to Model default: ExportedGlobal.
  5. Click the Signals/States tab. ExpandStates. For state X, set the storage class toModel default: Default.
  6. Save the model.

Generate and Verify Code

Generate code and verify the generated code.

#include "exInDataMem.h"
#include "exInDataLut.h"

}
.
.
.
}

#pragma start INTERNALDATA
D_Work rtDWork;
#pragma end INTERNALDATA
.
.
.
#pragma start INTERNALDATA
static RT_MODEL rtM_;
#pragma end INTERNALDATA
.
.
.
pragma start INTERNALDATA
extern D_Work rtDWork;
#pragma end INTERNALDATA

#include "ConfigurationInterface.h"
DBL_FLOAT ex_output;

Configure Default Code Generation for Functions

This example shows how to use the Code Mappings editor to specify code generation requirements for model functions. The model uses multiple execution rates and is configured for single-instance usage. The code generator produces initialize, execution, and terminate entry-point functions. Because the model uses multiple rates, the code generator produces an execution function for each rate.

This example assumes these code generation requirements:

Define Memory Sections

Define the two memory sections: functionSlowMem for initialize and terminate functions and functionFastMem for execution functions.

  1. Open the Embedded Coder app.
  2. Open the Embedded Coder Dictionary by selecting > .
  3. In the Embedded Coder Dictionary, on the left pane, click Memory Section.
  4. Click Create.
  5. In the new row of the table, name the new memory sectionfunctionFastMem. Then, set:
    • Pre Statement to #pragma start FASTMEM
    • Post Statement to #pragma end FASTMEM
  6. Click Add again. Name the memory sectionfunctionSlowMem. Then, set:
    • Pre Statement to #pragma start SLOWMEM
    • Post Statement to #pragma end SLOWMEM

Define Function Customization Templates

To configure categories of functions, define function customization templates. Unless you define templates in the Embedded Coder Dictionary that are associated with a model, the only available template is Default. Based on the requirements, in the dictionary, define two function customization templates: one to specify the naming rule and memory section for initialize and terminate functions and one to specify the naming rule and memory section for execution functions.

  1. In the Embedded Coder Dictionary, click Function Customization Template.
  2. Click Create.
  3. In the new row of the table, name the new templateexFastFunction. Then, set:
    • Function Name to exFast_$N. This naming rule applies the prefix exFast_ to the name that identifies the default code generator name of the function (for example,initialize or step).
    • Memory Section to functionFastMem. This mapping associates the memory section that you defined in Define Memory Sections with the new template.
  4. Click Create again. Name the templateexSlowFunction. Then, set:
    • Function Name to exSlow_$N.
    • Memory Section tofunctionSlowMem.
  5. Close the dictionary.

Configure Default Settings for Functions

  1. In the C Code tab, click > .
  2. In the Code Mappings editor, click the Function Defaults tab.
  3. Configure the initialize and terminate entry-point functions. For categoryInitialize/Terminate, select templateexSlowFunction.
  4. Configure the execution entry-point functions. For categoryExecution, select template exFastFunction.
  5. Save the model.

Generate and Verify Code

  1. Generate code.
  2. In the Code view:
    • Open file ConfigurationInterface.c. Click in theSearch field. A menu lists the generated entry-point functions:
      * exFast_step0 (called periodically, every 0.5 seconds)
      * exFast_step1 (called periodically, every 1 second)
      * exFast_step2 (called periodically, every 1.5 seconds)
      * exSlow_initialize
    • To gain access to the entry-point function code inConfigurationInterface.c, click the function name. Verify thepragma control statements that surround the function code. For example:
      .
      .
      .

    #pragma start FASTMEM
    void exFast_step2(void) /* Sample time: [1.5s, 0.0s] /
    {
    boolean_T rtb_DataStoreRead;
    rtb_DataStoreRead = ((ex_input1 > 10.0) || (ex_input1 < -10.0));
    rtDWork.RateTransition1_Buffer0 = rtb_DataStoreRead;
    }
    #pragma end FASTMEM
    #pragma start SLOWMEM
    void exSlow_initialize(void)
    {
    /
    (no initialization code required) */
    }
    #pragma end SLOWMEM
    .
    .
    .

    • Open file ConfigurationInterface.h. UseSearch to find #pragma control lines that define memory sections for FASTMEM andSLOWMEM. Verify the pragma control statements surround the declarations. For example:
      .
      .
      .

    #pragma start SLOWMEM
    extern void exSlow_initialize(void);
    #pragma end SLOWMEM
    #pragma start FASTMEM
    extern void exFast_step0(void);
    #pragma end FASTMEM
    .
    .
    .

Configure Model Elements for Code Generation with Definitions Stored in Shared Data Dictionary

You have the option of configuring default data and function code generation with definitions that are set up in a Simulink data dictionary. A data dictionary enables sharing of code definitions between models. This example shows how to change a model from using code definitions in a model-specific Embedded Coder Dictionary to using definitions in an Embedded Coder Dictionary that is in a shared data dictionary. If you have completed the examples in Configure Default Code Generation for Data and Configure Default Code Generation for Functions you have added these code definitions to the Embedded Coder Dictionary associated with modelConfigurationInterface.

Update model ConfigurationInterface to use the same code definitions in data dictionary exCodeDefs.sldd instead of definitions in the local model Embedded Coder Dictionary.

You must have set up the example environment, as described in Set Up Example Environment.

Attach Shared Data Dictionary to Model

  1. In the Simulink Editor, select > .
  2. In the Model Properties dialog box, in the External Data tab, browse to the location of your copy of data dictionary fileexCodeDefs and select that file.
  3. Click Migrate data.
  4. In the Link Model to Data Dictionary dialog box, clickApply.
  5. In the Migrate Data dialog box, click Migrate. When the data migration is complete, click OK.

Review Contents of Attached Data Dictionary

  1. In the lower-left corner of the model canvas, click the Model data icon.
  2. From the list of model data sources, click External Data.
  3. In the Model Explorer, in the Model Hierarchy pane, expand theexCodeDefs node.
  4. Right-click Embedded Coder Dictionary.
  5. Click the Open Embedded Coder Dictionary button that appears.
  6. In the Embedded Coder Dictionary, review the definitions in the Function Customization Template and Memory Section tabs.
  7. Close the Embedded Coder Dictionary.

Remove Model Sourced Code Definitions from Model Embedded Coder Dictionary

  1. Open the Embedded Coder app.
  2. In the C Code tab, select > .
  3. Remove the code definitions created locally in the model.
    • In the Function Customization Templates table, select the rows for exSlowFunction andexFastFunction that have Source set to ConfigurationInterface. Click theDelete icon.
    • In the Memory Sections table, select the rows forfunctionFastMem,functionSlowMem, andinternalDataMem that have Source set to ConfigurationInterface. Click theDelete icon.
  4. Close the dictionary.
  5. Save the model.

Configure Default Categories for Code Generation

  1. In the C Code tab, select > .
  2. In the Code Mappings editor, click the Data Defaults tab.
  3. Expand Signals. Select category Signals, states, and internal data.
  4. Click the Icon to configure additional code mapping properties icon. Set Memory Section tointernalDataMem.
  5. Click the Function Defaults tab.
    • For the Initialize/Terminate category, select function customization template exSlowFunction.
    • For the Execution category, select templateexFastFunction.
  6. Save the model.
  7. Generate and review code.

For more information about setting up an Embedded Coder Dictionary, see Define Service Interfaces, Storage Classes, Memory Sections, and Function Templates for Software Architecture.

Configure Default Data and Function Code Generation Programmatically

This example shows how to configure default data and function code generation for example model ConfigurationInterface. The example uses the default mapping programming interface to specify code generation requirements for model data and functions. Use that interface to automate the configuration, or if you prefer to configure models programmatically. For information about configuring the default data and function code generation by using the Code Mappings editor, see Configure Default C Code Generation for Categories of Data Elements and Functions.

Open the Model

The model ConfigurationInterface uses multiple execution rates and is configured for single-instance usage.

open_system('ConfigurationInterface')

Code Generation Requirements

For this example, these are the code generation requirements:

For this example, someone, such as a system architect, has previously created these code definitions in an Embedded Coder Dictionary that is part of Simulink data dictionary exCodeDefs.sldd:

Get Data and Function Code Mappings for Model

Get the code mappings for example model ConfigurationInterface by specifying the name of the model in a call to function coder.mapping.api.get. The function returns an object that represents the code mappings for the model. You specify that object as the first argument in subsequent calls to other functions in the API.

If code mappings do not exist for a model, create a code mappings object by calling coder.mapping.utils.create.

cm = coder.mapping.api.get('ConfigurationInterface');

Set Relevant Category, Property, and Value Combinations

Set relevant category, property, and value combinations with calls to setDataDefaults and setFunctionDefaults. The first two arguments that you specify for these functions are the code mappings object returned by coder.mapping.api.get and the name of a data or function category. In addition, you specify name-value pair arguments that specify the default configuration information that you want to set, such as the storage class and storage class properties.

In this example, you set the default:

% Configure data defaults setDataDefault(cm,'Inports','StorageClass','ImportFromFile','HeaderFile','exInDataLut.h'); setDataDefault(cm,'Outports','StorageClass','ExportToFile','HeaderFile','exSysOut.h',... 'DefinitionFile','exSysOut.c'); setDataDefault(cm,'ModelParameters','StorageClass','ExportedGlobal'); setDataDefault(cm,'InternalData','MemorySection','None');

% Configure function defaults setFunctionDefault(cm,'InitializeTerminate','FunctionCustomizationTemplate','Default'); setFunctionDefault(cm,'Execution','FunctionCustomizationTemplate','Default');

Verify Default Mappings

Verify default mappings with calls to getDataDefaults and getFunctionDefaults. The first two arguments that you specify for these functions are the code mappings object returned by coder.mapping.api.get and the name of a data or function category. In addition, you specify the name of the configuration information that you want the function to return, such as the name of the storage class or a storage class property.

In this example, you verify these default settings:

% Verify default data configurations defscInports = getDataDefault(cm,'Inports','StorageClass')

defscInports = 'ImportFromFile'

defhfileInports = getDataDefault(cm,'Inports','HeaderFile')

defhfileInports = 'exInDataLut.h'

defscOutport = getDataDefault(cm,'Outports','StorageClass')

defscOutport = 'ExportToFile'

defhfileOutport = getDataDefault(cm,'Outports','HeaderFile')

defhfileOutport = 'exSysOut.h'

defdffileOutport = getDataDefault(cm,'Outports','DefinitionFile')

defdffileOutport = 'exSysOut.c'

defscParams = getDataDefault(cm,'ModelParameters','StorageClass')

defscParams = 'ExportedGlobal'

defmemInternal = getDataDefault(cm,'InternalData','MemorySection')

% Verify default function configurations deftempInitTerm = getFunctionDefault(cm,'InitializeTerminate','FunctionCustomizationTemplate')

deftempInitTerm = 'Default'

deftempExecution = getFunctionDefault(cm,'Execution','FunctionCustomizationTemplate')

deftempExecution = 'Default'

Configure Individual Data Elements to Use Default Configuration Settings

The storage class for each model data element is set to Auto, which means that the code generator might eliminate or change the representation of relevant code for optimization purposes. If optimizations are not possible, the code generator applies the model default configuration.

For this example, you configure the code generator to apply the default storage class setting to the Inport blocks, the Output block, model parameters, and state X for the Unit Delay block. Use the find function to get the names of the data elements in the model of the different categories. Then, use the values returned by find in calls to setInport, setOutport, setModelParameter, and setState to set the storage class to Model default. Use calls to getInport, getOutport, getModelParameter, and getState to verify, the storage class settings.

In each of the function calls, you specify the code mappings object returned by coder.mapping.api.get. In addition:

input = find(cm,'Inports'); setInport(cm,input,'StorageClass','Model default');

output = find(cm,'Outports'); setOutport(cm,output,'StorageClass','Model default');

params = find(cm,'ModelParameters'); setModelParameter(cm,params,'StorageClass','Model default');

states = find(cm,'States'); setState(cm,states,'StorageClass','Model default');

scIn1 = getInport(cm,'In1','StorageClass')

scIn2 = getInport(cm,'In2','StorageClass')

scIn3 = getInport(cm,'In3','StorageClass')

scIn4 = getInport(cm,'In4','StorageClass')

scK1 = getModelParameter(cm,'K1','StorageClass')

scTable2 = getModelParameter(cm,'Table2','StorageClass')

scTable2 = 'Model default'

scX = getState(cm,'ConfigurationInterface/Delay','StorageClass')

Override Default Header File Setting for Inport Block In1

Previously, you set the default header file for inports to exInDataLut.h. The requirements specify that you import data for Inport block In1 from header file exInDataMem.h.

For Inport block In1, override the default storage class to ImportFromFile and set the header file to exInDataMem.h with a call to setInport. The function call specifies the code mappings object returned by coder.mapping.api.get, the name of the Inport block to configure, and name-value pair arguments specifying that the function set StorageClass to ImportFromFile and HeaderFile to exInDataMem.h.

setInport(cm,'In1','StorageClass','ImportFromFile','HeaderFile','exInDataMem.h');

Verify Header File Setting

Verify the updated header file setting for Inport block In1 with a call to getInport. The function call specifies the code mappings object returned by coder.mapping.api.get, the name of the Inport block of interest, and the configuration information to return.

hfileIn1 = getInport(cm,'In1','StorageClass')

hfileIn1 = 'ImportFromFile'

Override Default Function Name Setting for Step Function

Previously, you set the default function customization template for execution functions to functionFastMem, which applies the naming rule exFast_$N to the three step functions generated for the model. The requirements specify that the name for function Periodic:D1, which has a sample time of 1 second, be named exFast_1sec.

Set the function name with a call to setFunction.The function call specifies the code mappings object returned by coder.mapping.api.get, the source of the function, Periodic:D1, and the name-value pair argument specifying that the function set the function name to exFast_1sec.

setFunction(cm,'Periodic:D1','FunctionName','exFast_1sec')

Verify Function Name Setting

Verify the updated function name setting for execution function Periodic:D1 with a call to getFunction.The function call specifies the code mappings object returned by coder.mapping.api.get, the function of interest, and property FunctionName.

functionName = getFunction(cm,'Periodic:D1','FunctionName')

functionName = 'exFast_1sec'

See Also

Topics