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.
Copy these external source and header files from
matlabroot/toolbox/rtw/rtwdemos
to a writable working folder. These
files define and declare the external data type and data that the generated code
uses.
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 corresponding
Simulink.AliasType object. |
exInDataMem.c | Includes exInDataMem.h and defines variable
ex_input1 . |
exInDataMem.h | Includes exDbFloat.h and declares variable
ex_input1 . |
exInDataLut.c | exInDataLut.c includes exInDataLut.h
and defines variables ex_input2 , ex_input3 ,
and ex_input4 . |
exInDataLut.h | Includes exDbFloat.h and declares variables
ex_input2 , ex_input3 , and
ex_input4 . |
exCodeDefs.sldd | Data dictionary |
rtwdemo_configdefaults.slx | Example model. |
Open your copy of example model rtwdemo_configdefaults
.
In the apps gallery, open the Embedded Coder app.
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 file
exDblFloat.h
.
Get data element ex_input1
from header file
exInDataMem.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
, and
ex_input4
from header file exInDataLut.h
. The data
is used in lookup tables Table1
and Table2
.
Data imported into the model from header files exInDataMem.h
and
exInDataLut.h
is of type DBL_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 labeled internalDataMem
.
Export output data declarations to header file exSysOut.h
and
definitions to exSysOut.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.
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 rtwdemo_configdefaults. Save a copy to a writable location.
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 and the Property Inspector.
In theData Defaults tab, expand Inports and Outports. Then, select Inports.
Set the storage class to ImportFromFile
.
In the Property Inspector, set Header File to
exInDataLut.h
.
Configure default settings for model workspace parameters that you want to be tunable.
In the Code Mappings editor, click the Data Defaults tab.
In theData 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 to
Tunable
. 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 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, click the Memory Sections tab.
Click Add.
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.
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 theData Defaults tab, expand Signals.
Select category Signals, states, and internal data.
In the Property Inspector, set Memory Section to
internalDataMem
.
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 theData Defaults tab, expand Inports and Outports.
Select category Outports.
Set the storage class to ExportToFile
.
In the Property Inspector, set Header File to
exSysOut.h
and Definition File to
exSysOut.c
.
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
, and
In4
Outport Out1
Model parameter K1
State X
In the Code Mappings editor, click the Inports tab.
Select the rows for inports In2
, In3
, and
In4
. 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
.
Click the Outports tab. For outport Out1
,
set the storage class to Model default: ExportToFile
.
Click the Parameters tab. Expand Model
Parameters. Then, for parameter K1
, set the storage
class to Model default: ExportedGlobal
.
Click the Signals/States tab. Expand
States. For state X
, set the storage class to
Model default: Default
.
Save the model.
Generate code and verify the generated code.
In the file rtwdemo_configdefaults.h
, search for
#include
statements that include the header files that declare
external input
data.
#include "exInDataMem.h" #include "exInDataLut.h"
Open file rtwdemo_configdefaults.c
. The code initializes the gain
variable K1
and uses the variable in the model step function
exFast_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 rtwdemo_configdefaults.c
, find #pragma
control lines that define memory sections for INTERNALDATA
(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 for ex_output
.
#include "rtwdemo_configdefaults.h" DBL_FLOAT ex_output;
Open shared file exSysOut.h
. The file declares
ex_output
. To gain access to ex_output
, external
code can include this header file.
extern DBL_FLOAT ex_output;
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 section
functionFastMem
.
Use the naming rule exSlow_$N
to name
initialize
and terminate
functions. Use the
naming rule exFast_$N
to name execution functions.
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, click the Memory Sections tab.
Click Add.
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
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 the Function Customization Templates tab.
Click Add.
In the new row of the table, name the new template
exFastFunction
. 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.
Click Add again. Name the template
exSlowFunction
. Then, set:
Function Name to exSlow_$N
.
Memory Section to
functionSlowMem
.
Close the dictionary.
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 code.
In the Code view:
Open file rtwdemo_configdefaults.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
rtwdemo_configdefaults.c
, click the function name. Verify the
pragma
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 rtwdemo_configdefaults.h
. Use
Search to find #pragma
control lines
that define memory sections for FASTMEM
and
SLOWMEM
. 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 . . .
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
rtwdemo_configdefaults
.
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
rule exFast_$N
and memory section
functionFastMem
Function customization template exSlowFunction
with function naming
rule exSlow_$N
and memory section
functionSlowMem
Update model rtwdemo_configdefaults
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.
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.
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 Templates and Memory Sections tabs.
Close the 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 tab, select the
rows for exSlowFunction
and
exFastFunction
that have Source
set to rtwdemo_configdefaults
. Click
Remove.
In the Memory Sections tab, select the rows for
functionFastMem
,
functionSlowMem
, and
internalDataMem
that have Source
set to rtwdemo_configdefaults
. Click
Remove.
Close the dictionary.
Save the model.
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.
In the Property Inspector, 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 Storage Classes, Memory Sections, and Function Templates for Software Architecture.
This example shows how to configure default data and function code generation for example model rtwdemo_configdefaults
.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 rtwdemo_configdefaults
uses multiple execution rates and is configured for single-instance usage.
open_system('rtwdemo_configdefaults')
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 file
exDblFloat.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 file exInDataMem.h
.
Import signals ex_input2
, ex_input3
, and ex_input4
for lookup tables Table1
and Table2
. Import the signal data from header file exInDataLut.h
.
Data imported into the model from header files exInDataMem.h
and exInDataLut.h
is of type DBL_FLOAT
, a project standard.
Parameters UPPER
, LOWER
, K1
, and K2
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 section functionFastMem
.
Use the identifier naming rule exSlow_$N
to name initialize
and terminate
entry-point functions. Use the naming rule exFast_$N
to name execution functions for .5 second and 1.5 second periodic functions. Set the name of the 1 second periodic function to exFast_1sec
.
Export output data declarations to header file exSysOut.h
and definitions to exSysOut.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
, and functionSlowMem
.
Function customization templates exFastFunction
and exSlowFunction
.
Get Data and Function Code Mappings for Model
Get the code mappings for example model rtwdemo_configdefaults
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('rtwdemo_configdefaults');
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','internalDataMem'); % Configure function defaults setFunctionDefault(cm,'InitializeTerminate','FunctionCustomizationTemplate','exSlowFunction'); setFunctionDefault(cm,'Execution','FunctionCustomizationTemplate','exFastFunction');
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 = 'internalDataMem'
% Verify default function configurations deftempInitTerm = getFunctionDefault(cm,'InitializeTerminate','FunctionCustomizationTemplate')
deftempInitTerm = 'exSlowFunction'
deftempExecution = getFunctionDefault(cm,'Execution','FunctionCustomizationTemplate')
deftempExecution = 'exFastFunction'
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
, and setState
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
, and getState
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'
scK2 = getModelParameter(cm,'K2','StorageClass')
scK2 = 'Model default'
scX = getState(cm,'rtwdemo_configdefaults/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 exeuction 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:D2
, which has a sample time of 1 seccond, 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:D2, and the name-value pair argument specifying that the function set the function name to exFast_1sec
.
setFunction(cm,'Periodic:D2','FunctionName','exFast_1sec')
Verify Function Name Setting
Verify the updated function name setting for execution function Periodic:D2
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:D2','FunctionName')
functionName = 'exFast_1sec'
Related Links