Protect Global Data with const
and volatile
Type
Qualifiers
In C, you use the type qualifier const
to prevent code in an
application from assigning a new value to a variable. In an application where an external
actor (for example, a hardware device) can manipulate the value of a variable, you use the
keyword volatile
to prevent a compiler from optimizing the assembly code in
a way that compromises the integrity of the variable value. You can also use
volatile
to prevent a compiler from eliminating storage for
const
data, such as a parameter that has a value that you want to tune
during execution.
To apply the qualifiers to an individual data item in a model, including a custom structure that you create by using a nonvirtual bus or a parameter structure, apply the appropriate predefined storage class directly to the data item. The storage class prevents optimizations such as Default parameter behavior from eliminating storage for the data item. For an example, see Type Qualifiers. For information about optimizations that a directly applied storage class prevents, see How Generated Code Stores Internal Signal, State, and Parameter Data.
If the predefined storage classes do not meet your requirements, you can create your own custom storage class. To make your custom storage class apply the qualifiers, in the Custom Storage Class Designer, set Memory section to the appropriate built-in memory section or to a memory section that you create. For more information, see Create Storage Classes by Using the Custom Storage Class Designer.
You can apply the qualifiers to a category of model data by default, such as parameters or states. As you add blocks to a model, new data items in these categories carry the qualifiers that you specify. For more information, see Configure Default Code Generation for Data.
If the predefined storage classes do not meet your requirements, you can create your own by using an Embedded Coder Dictionary. In the Dictionary, for your new storage class, select the appropriate check boxes under Qualifiers. For more information, see Create Code Definitions for Use in the Code Mappings Editor.
Maintain const
Correctness for Arguments of Entry-Point Functions
When your external code calls a generated entry-point function and passes
const
data through an argument (formal parameter) of the function, to
make the corresponding argument in the function definition const
,
customize the execution (step) entry-point function interface.
To configure the step entry-point function interface for a model, see Configure Name and Arguments for Individual Step Functions.
To configure the step entry-point function interface for a Simulink Function block, see Configure Entry-Point Function Interfaces for Simulink Function and Function Caller Blocks.
Incorrect Results or Undefined Behavior When Passing Volatile Data to a Generated Function
The generated code can define and call functions other than model entry-point functions. For example, you can configure an atomic subsystem to appear in the code as a separate function. Also, lookup table blocks, such as n-D Lookup Table, typically yield separate utility functions.
When the generated code defines a function with an argument (formal parameter), the
function does not protect against volatile data passed through the argument. Thus the
function definition does not apply volatile
to the argument, and when
other generated code or your external code calls the function and passes in volatile data,
the called function implicitly casts away the volatility.
When you execute code that calls a function accepting volatile data and the value of the data changes, you can get incorrect results or undefined behavior. To avoid this scenario, assign the value of a volatile variable to a non-volatile variable and pass the non-volatile variable as an argument to the function.