Access Data Through Functions by Using Storage Classes in Embedded Coder Dictionary
To replace the direct access to data in the generated code with your own or legacy functions that read and write data in a customized way, you can enable function access on your storage classes. You create these storage classes in the Embedded Coder® Dictionary. Root-level inports, root-level outports, and model parameters that use your storage class appear in the generated code as calls to specified functions. You provide the function declarations and definitions in separate header and source files pointed to by the storage class.
Open Embedded Coder Dictionary
You can define and apply a storage class to root-level inports, root-level outports, and model parameters so they can be accessed by customizable get and set functions. Such customization can be useful, for example, to abstract layers of software, gain access to data from an external file or to control access to critical sections of code.
This example shows how to set up a storage class in the Embedded Coder Dictionary and map the storage class to root-level inports/outports and model parameters in the Code Mappings editor.
Open example model RollAxisAutopilot
.
open_system('RollAxisAutopilot')
The example gives you access to the supporting files that define the get
and set
functions required for the example: RollAxisAutopilot_Value.h
, RollAxisAutopilot_Value.c
, RollAxisAutopilot_Pointer.h
, and RollAxisAutopilot_Pointer.c
.
In the Apps gallery, under Code Generation, click Embedded Coder.
To open the Embedded Coder Dictionary, on the C Code tab, click Code Interface > Embedded Coder Dictionary.
Access Legacy Data by Value
To access data by using a value, follow these steps:
In the Embedded Coder Dictionary, on the left pane, click Storage Class.
The
RollAxisAutopilot
model has two storage classes:SignalStruct
andParamStruct
. They are already created by using the Create button. This example uses these storage classes. You can perform the following steps for a storage class that you create as well.For the
SignalStruct
storage class, in the Property Inspector pane, update these property values:Data Access to
Function
Header File to
$R_Value.h
Make sure that Access Mode is set to
Value
. Data Scope is set toImported
by default and cannot be changed.For the
ParamStruct
storage class, in the Property Inspector pane, update these property values:Data Access to
Function
Header File to
$R_Value.h
These properties are already set:
Access Mode to
Value
Data Initialization to
Static
Storage classes used for parameters can have Data Initialization set to
Auto
,Static
, orNone
.Open the Configuration Parameters dialog box. In the toolstrip, on the C Code tab, click Settings. Select Code Generation > Custom Code > Code information > Source files and specify:
RollAxisAutopilot_Value.c
In the Embedded Coder app, open the Code Mappings editor. On the Data Defaults tab, map these model element categories:
Inports to
SignalStruct
Outports to
SignalStruct
Model parameters to
ParamStruct
Build the model and generate code.
In the generated code, view the file RollAxisAutopilot.c
. The model
step
function uses the specified get
and
set
functions to execute the algorithm. The generated code accesses the
legacy data by calling the custom, handwritten get
and
set
functions. For example, here is the code snippet for the HDG_Ref
inport:
if (get_HDG_Mode()) { /* Outputs for Atomic SubSystem: '<Root>/HeadingMode' */ rtb_Sum1 = (get_HDG_Ref() - get_Psi()) * 0.015F * get_TAS(); /* End of Outputs for SubSystem: '<Root>/HeadingMode' */ } else { /* Outputs for Atomic SubSystem: '<Root>/RollAngleReference' */ if ((real32_T)fabs(get_Turn_Knob()) >= 3.0F) { rtb_Sum1 = get_Turn_Knob(); }
get
and set
functions if the functions that you write accept and return the expected values.Access Legacy Data by Pointer
To access data by using a pointer, follow all the preceding steps but make these changes:
In the Embedded Coder Dictionary, for storage classes
SignalStruct
andParamStruct
, specify:Access Mode to
Pointer
Header File to
$R_Pointer.h
Select Configuration Parameters > Code Generation > Custom Code > Code information > Source files and replace
RollAxisAutopilot_Value.c
with:RollAxisAutopilot_Pointer.c
With the pointer access, a get
function now returns a pointer whose
value must be dereferenced with the *
before use. For example, the
generated code for the HDG_Ref inport now looks like this
code:
if (*get_HDG_Mode()) { /* Outputs for Atomic SubSystem: '<Root>/HeadingMode' */ rtb_Sum1 = (*get_HDG_Ref() - *get_Psi()) * 0.015F * *get_TAS(); /* End of Outputs for SubSystem: '<Root>/HeadingMode' */ } else { /* Outputs for Atomic SubSystem: '<Root>/RollAngleReference' */ if ((real32_T)fabs(tmp_1) >= 3.0F) { rtb_Sum1 = tmp_1; }
Creating your own storage class in Embedded Coder Dictionary gives you the flexibility of customizing function names and return
types. You can also use the storage class GetSet
to access data through
get
and set
functions. For more information, see
Access Data Through Functions with Storage Class GetSet.