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 that has an argument (formal parameter), the
function definition does not apply volatile
to the argument. Therefore,
when other generated code or your external code calls the function and passes a volatile
variable as the value of the argument, the called function implicitly casts away the
volatility.
If your application executes the called function while the value of the volatile data
changes, the function can yield incorrect results or undefined behavior. In particular, for
lookup table data that you prepare for calibration, by applying const
and
volatile
, make sure that you do not calibrate the data while your
application executes the lookup utilities.