Localizable
Storage ClassFor signals, if possible, generate variables that are local to functions rather than in global storage. Generating local variables prevents the code generator from implementing optimizations that remove these variables from the generated code. Local variables improve observability, readability, and are helpful in debugging the generated code.
Minimizing the use of global variables by using local variables interacts with stack usage control. For example, stack size can determine the number of local and global variables that the code generator can allocate in the generated code. For more information, see Customize Stack Space Allocation (Simulink Coder).
The model rtwdemo_localizable_csc
contains two signals that have a
Localizable
storage class. In the Latching
subsystem, the signal with the label Latch
has a
Localizable
storage class. In the Debug
subsystem,
the signal with the label Debug
has a Localizable
storage class.
Localizable
Storage ClassOpen the model.
model='rtwdemo_localizable_csc'; open_system(model);
To observe the specification, for each signal, open the Signal Properties dialog
box and select the Code Generation tab. The Signal object
class parameter is set to Simulink.Signal
. The
Storage class parameter is set to Localizable
(Custom)
.
Build the model. The Debug_b
function contains this code:
static void Debug_b(const real_T rtu_In1[6], const real_T rtu_In2[6], real_T rtd_A[6]) { real_T Debug; int32_T i; for (i = 0; i < 6; i++) { Debug = rtu_In1[i] * rtu_In2[i]; rtd_A[i] += Debug; } }
The Latching
function contains this code:
static void Latching(const real_T rtu_In1[36], real_T rty_Out1[6], real_T rty_Out2[6], real_T rtd_A[6]) { real_T Latch[6]; int32_T i; int32_T i_0; for (i = 0; i < 6; i++) { Latch[i] = rtd_A[i]; rty_Out2[i] = -Latch[i]; } for (i = 0; i < 6; i++) { rty_Out1[i] = 0.0; for (i_0 = 0; i_0 < 6; i_0++) { rty_Out1[i] += rtu_In1[6 * i_0 + i] * Latch[i_0]; } } }
Both functions contain variables for holding intermediate values. The
Debug_b
function contains the variable Debug
.
The Latching
function contains the variable
Latch
.
Change the signal storage class from Localizable
to
ExportToFile
. For each signal, open the Signal
Properties dialog box. On the Code Generation tab, for
the Storage class parameter, select
ExportToFile
. The rtwdemo_localizable_csc.c
file
contains these two global variable declarations:
real_T Debug[6]; real_T Latch[6];
The Debug_b
function contains this code:
static void Debug_b(const real_T rtu_In1[6], const real_T rtu_In2[6], real_T rtd_A[6]) { int32_T i; for (i = 0; i < 6; i++) { Debug[i] = rtu_In1[i] * rtu_In2[i]; rtd_A[i] += Debug[i]; } }
The Latching
function contains this code:
static void Latching(const real_T rtu_In1[36], real_T rty_Out1[6], real_T rty_Out2[6], real_T rtd_A[6]) { int32_T i; int32_T i_0; for (i = 0; i < 6; i++) { Latch[i] = rtd_A[i]; rty_Out2[i] = -Latch[i]; } for (i = 0; i < 6; i++) { rty_Out1[i] = 0.0; for (i_0 = 0; i_0 < 6; i_0++) { rty_Out1[i] += rtu_In1[6 * i_0 + i] * Latch[i_0]; } } }
The code readability and observability is the same as with the
Localizable
storage class specification except the labeled signals
are global variables.
Remove the Debug
and Latch
labels. Build the
model. The Debug_b
function contains this code:
static void Debug(const real_T rtu_In1[6], const real_T rtu_In2[6], real_T rtd_A[6]) { int32_T i; for (i = 0; i < 6; i++) { rtd_A[i] += rtu_In1[i] * rtu_In2[i]; } }
The Latching
function contains this code:
static void Latching(const real_T rtu_In1[36], real_T rty_Out1[6], real_T rty_Out2[6], real_T rtd_A[6]) { int32_T i; int32_T i_0; for (i = 0; i < 6; i++) { rty_Out2[i] = -rtd_A[i]; rty_Out1[i] = 0.0; for (i_0 = 0; i_0 < 6; i_0++) { rty_Out1[i] += rtu_In1[6 * i_0 + i] * rtd_A[i_0]; } } }
Without the Localizable
or ExportToFile
storage classes, the code generator removes the Debug
and
Latch
variables. Without these variables, the readability and
observability of the generated code decreases.
For the code generator to localize signals with the Localizable
storage class specification, in the Configuration Parameters dialog box, you must select
the Enable Local Block Outputs parameter.
This parameter is on by default.
You can specify the same Localizable
storage class on two signals
that are in different reusable subsystems. Therefore, you can create a library block
from a reusable subsystem with a Localizable
storage class
specification.
The code generator does not create a local variable for a signal that must stay global. A few cases in which the code generator can not localize a signal are:
Input and output signals of a Nonreusable subsystem even when the
Function interface parameter is set to Allow
arguments (Optimized)
.
Signal is holding a state because its receiver and drive blocks execute at different rates.
Localizable
specification is on a signal that crosses the
boundary of a conditionally executed subsystem.