Configure Default C Code Generation for Categories of Data Elements and Functions
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
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 thePreLoadFcn
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 variablesex_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. Open the example model
ConfigurationInterface
.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:
Use project type definition
DBL_FLOAT
defined in header fileexDblFloat.h
.Get data element
ex_input1
from header fileexInDataMem.h
. The data is used for computing a value stored in memory, and then used in an if-else condition of a Switch block.Get data elements
ex_input2
,ex_input3
, andex_input4
from header fileexInDataLut.h
. The data is used in lookup tablesTable1
andTable2
.Data imported into the model from header files
exInDataMem.h
andexInDataLut.h
is of typeDBL_FLOAT
, a project standard.Parameter
K1
must be tunable to enable calibration.Data store
mode
defines data that is shared within the model. The Logical Operator block writes to the data store and a Rate Transition block reads from the data store.Data element
X
represents the delay for the Unit Delay block.Store data that is internal to the model, such as delay
X
, in a section of memory labeledinternalDataMem
.Export output data declarations to header file
exSysOut.h
and definitions toexSysOut.c
.Name variables representing inports and outports in the generated code as specified in this table so they match variable names in the external header and definition files.
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.
Open model
ConfigurationInterface
.Open the Embedded Coder app.
In the C Code tab, select Code Interface > Default Code Mappings. This opens the Code Mappings editor Data Defaults tab.
In the Data Defaults tab, expand Inports and Outports. Then, select Inports.
Set the storage class to
ImportFromFile
.Click the icon and set Header File to
exInDataLut.h
.
Configure Default Settings for Model Parameters
Configure default settings for model workspace parameters that you want to be tunable.
In the Code Mappings editor, click the Data Defaults tab.
In the Data Defaults tab, expand Parameters.
In the row for Model parameters, click the text
'Auto' will be inlined
. The Model Configuration Parameters dialog box opens to the Code Generation > Optimization 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
.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.
Open the Embedded Coder Dictionary by selecting Code Interface > Embedded Coder Dictionary.
In the Embedded Coder Dictionary, on the left pane, click Memory Section.
Click Create.
In the new row of the table, name the new memory section
internalDataMem
. Also set:Pre Statement to
#pragma start INTERNALDATA
Post Statement to
#pragma end INTERNALDATA
Statements Surround to
Group of variables
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
.
In the Code Mappings editor, click the Data Defaults tab.
In the Data Defaults tab, expand Signals.
Select category Signals, states, and internal data.
Click the icon and set Memory Section to
internalDataMem
.
Configure Default Settings for Root Outport
Specify the default external header and definition files for variables to which the generated code writes output.
In the Code Mappings editor, click the Data Defaults tab.
In the Data Defaults tab, expand Inports and Outports.
Select category Outports.
Set the storage class to
ExportToFile
.Click the icon and set Header File to
exSysOut.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 is
Auto
. When the storage class for a data element is
Auto
, 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.
To avoid optimizations and force the code generator to use the default configuration, set the storage class for the individual element to
Model default
.To override the default configuration, specify the storage class that meets the code generation requirements for that data element.
For this example, configure the code generator to apply the default storage class setting to these data elements:
Inports
In2
,In3
, andIn4
Outport
Out1
Model parameter
K1
State
X
In the Code Mappings editor, click the Inports tab.
Select the rows for inports
In2
,In3
, andIn4
. Then, for one of the selected inports, set the storage class toModel default: ImportFromFile
. The storage class for the three selected inports changes toModel default: ImportFromFile
.Click the Outports tab. For outport
Out1
, set the storage class toModel default: ExportToFile
.Click the Parameters tab. Expand Model Parameters. Then, for parameter
K1
, set the storage class toModel default: ExportedGlobal
.Click the Signals/States tab. Expand States. For state
X
, set the storage class toModel default: Default
.Save the model.
Generate and Verify Code
Generate code and verify the generated code.
In the file
ConfigurationInterface.h
, search for#include
statements that include the header files that declare external input data.#include "exInDataMem.h" #include "exInDataLut.h"
Open file
ConfigurationInterface.c
. The code initializes the gain variableK1
and uses the variable in the model step functionexFast_step1
.DBL_FLOAT K1 = 2.0; . . . void exFast_step1(void) { DBL_FLOAT rtb_Gain; rtb_Gain = K1 * look1_binlc(ex_input2, (&(rtTable1_bp01Data[0])), (&(rtTable1_tableData[0])), 10U); rtDWork.RateTransition_Buffer0 = rtb_Gain; } . . . }
In file
ConfigurationInterface.c
, find#pragma
control lines that define memory sections forINTERNALDATA
(the local data store, unit delay, and constants).#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
Open file
exSysOut.c
. The file includes an exported data definition forex_output
.#include "ConfigurationInterface.h" DBL_FLOAT ex_output;
Open shared file
exSysOut.h
. The file declaresex_output
. To gain access toex_output
, external code can include this header file.extern 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:
Store generated initialize and terminate functions in memory section
functionSlowMem
and execution functions in memory sectionfunctionFastMem
.Use the naming rule
exSlow_$N
to nameinitialize
andterminate
functions. Use the naming ruleexFast_$N
to name execution functions.
Define Memory Sections
Define the two memory sections: functionSlowMem
for initialize and
terminate functions and functionFastMem
for execution functions.
Open the Embedded Coder app.
Open the Embedded Coder Dictionary by selecting Code Interface > Embedded Coder Dictionary.
In the Embedded Coder Dictionary, on the left pane, click Memory Section.
Click Create.
In the new row of the table, name the new memory section
functionFastMem
. Then, set:Pre Statement to
#pragma start FASTMEM
Post Statement to
#pragma end FASTMEM
Click Add again. Name the memory section
functionSlowMem
. 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.
In the Embedded Coder Dictionary, click Function Customization Template.
Click Create.
In the new row of the table, name the new template
exFastFunction
. Then, set:Function Name to
exFast_$N
. This naming rule applies the prefixexFast_
to the name that identifies the default code generator name of the function (for example,initialize
orstep
).Memory Section to
functionFastMem
. This mapping associates the memory section that you defined in Define Memory Sections with the new template.
Click Create again. Name the template
exSlowFunction
. Then, set:Function Name to
exSlow_$N
.Memory Section to
functionSlowMem
.
Close the dictionary.
Configure Default Settings for Functions
In the C Code tab, click Code Interface > Default Code Mappings.
In the Code Mappings editor, click the Function Defaults tab.
Configure the initialize and terminate entry-point functions. For category Initialize/Terminate, select template
exSlowFunction
.Configure the execution entry-point functions. For category Execution, select template
exFastFunction
.Save the model.
Generate and Verify Code
Generate code.
In the Code view:
Open file
ConfigurationInterface.c
. Click in the Search 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 in
ConfigurationInterface.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
. Use Search to find#pragma
control lines that define memory sections forFASTMEM
andSLOWMEM
. Verify thepragma
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 model
ConfigurationInterface
.
Memory section
internalDataMem
with Pre Statement set to#pragma start INTERNALDATA
and Post Statement set to#pragma end INTERNALDATA
.Memory section
functionFastMem
with Pre Statement set to#pragma start FASTMEM
and Post Statement set to#pragma end FASTMEM
.Memory section
functionSlowMem
with Pre Statement set to#pragma start SLOWMEM
and Post Statement set to#pragma end SLOWMEM
.Function customization template
exFastFunction
with function naming ruleexFast_$N
and memory sectionfunctionFastMem
Function customization template
exSlowFunction
with function naming ruleexSlow_$N
and memory sectionfunctionSlowMem
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
In the Simulink Editor, select Modeling > Link to Data Dictionary.
In the Model Properties dialog box, in the External Data tab, browse to the location of your copy of data dictionary file
exCodeDefs
and select that file.Click Migrate data.
In the Link Model to Data Dictionary dialog box, click Apply.
In the Migrate Data dialog box, click Migrate. When the data migration is complete, click OK.
Review Contents of Attached Data Dictionary
In the lower-left corner of the model canvas, click the Model data icon.
From the list of model data sources, click External Data.
In the Model Explorer, in the Model Hierarchy pane, expand the exCodeDefs node.
Right-click Embedded Coder Dictionary.
Click the Open Embedded Coder Dictionary button that appears.
In the Embedded Coder Dictionary, review the definitions in the Function Customization Template and Memory Section tabs.
Close the Embedded Coder Dictionary.
Remove Model Sourced Code Definitions from Model Embedded Coder Dictionary
Open the Embedded Coder app.
In the C Code tab, select Code Interface > Embedded Coder Dictionary.
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 toConfigurationInterface
. Click the Delete icon.In the Memory Sections table, select the rows for
functionFastMem
,functionSlowMem
, andinternalDataMem
that have Source set toConfigurationInterface
. Click the Delete icon.
Close the dictionary.
Save the model.
Configure Default Categories for Code Generation
In the C Code tab, select Code Interface > Default Code Mappings.
In the Code Mappings editor, click the Data Defaults tab.
Expand Signals. Select category Signals, states, and internal data.
Click the icon. Set Memory Section to
internalDataMem
.Click the Function Defaults tab.
For the Initialize/Terminate category, select function customization template
exSlowFunction
.For the Execution category, select template
exFastFunction
.
Save the model.
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:
Import project type definition for data of type
double
, DBL_FLOAT, from header fileexDblFloat.h
.Import signal
ex_input1
for computing a value stored in memory and used in an if-else condition in the Switch block. Import the signal data from header fileexInDataMem.h
.Import signals
ex_input2
,ex_input3
, andex_input4
for lookup tablesTable1
andTable2
. Import the signal data from header fileexInDataLut.h
.Data imported into the model from header files
exInDataMem.h
andexInDataLut.h
is of typeDBL_FLOAT
, a project standard.Parameters
UPPER
,LOWER
,K1
, andK2
are parameter objects stored in the model workspace. Represent the parameters as global variables in the generated code.Data element
X
represents the delay for the Unit Delay block.Store data that is internal to the model in memory section
internalDataMem
.Store generated initialize and terminate functions in memory section
functionSlowMem
and execution functions in memory sectionfunctionFastMem
.Use the identifier naming rule
exSlow_$N
to nameinitialize
andterminate
entry-point functions. Use the naming ruleexFast_$N
to name execution functions for .5 second and 1.5 second periodic functions. Set the name of the 1 second periodic function toexFast_1sec
.Export output data declarations to header file
exSysOut.h
and definitions toexSysOut.c
.
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
:
Memory sections
internalDataMem
,functionFastMem
, andfunctionSlowMem
.Function customization templates
exFastFunction
andexSlowFunction
.
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:
Storage class for Inport blocks, Outport blocks, and model parameters
Memory section for internal data (for example, signald and block states)
Header and definition files for Inport and Outport blocks
Function customization template for initialize, terminate, and execution functions
% 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:
Storage class for Inport blocks, Outport blocks, and model parameters
Memory section for internal data (for example, signal data and block states)
Header and definition files for Inport and Outport blocks
Function customization template for initialize, terminate, and execution functions
% 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')
defmemInternal = 'None'
% 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.
To avoid optimizations and force the code generator to use the default configuration, set the storage class to
Model default
.To override the default configuration, specify the storage class that meets the code generation requirements for that inport.
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:
In the call to the
find
function, you specify a value indicating code mapping information that you want the function to return.The calls to
setInport
,setOutport
,setModelParameter
, andsetState
identify data elements that you want to configure and a name-value pair argument that specifies the configuration information that you want to set, such as the storage class or a storage class property.The calls to
getInport
,getOutport
,getModelParameter
, andgetState
identify a data element for which you want to return configuration information and the type of information that you want the function to return.
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')
scIn1 = 'Model default'
scIn2 = getInport(cm,'In2','StorageClass')
scIn2 = 'Model default'
scIn3 = getInport(cm,'In3','StorageClass')
scIn3 = 'Model default'
scIn4 = getInport(cm,'In4','StorageClass')
scIn4 = 'Model default'
scK1 = getModelParameter(cm,'K1','StorageClass')
scK1 = 'Model default'
scTable2 = getModelParameter(cm,'Table2','StorageClass')
scTable2 = 'Model default'
scX = getState(cm,'ConfigurationInterface/Delay','StorageClass')
scX = 'Model default'
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'
Related Topics
- C Data Code Interface Configuration for Model Interface Elements
- Choose Data Configuration Approach
- Choose Storage Class for Controlling Data Representation in Generated Code
- Organize Parameter Data into a Structure by Using Struct Storage Class
- Define Service Interfaces, Storage Classes, Memory Sections, and Function Templates for Software Architecture
- Configure Generated C Function Interface for Model Entry-Point Functions
- Generate Code to Conform to Software Architecture by Sharing and Copying Default Settings Between Models