主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

删除零初始化代码

删除根级别 I/O 零初始化删除内部数据零初始化 参数控制生成的代码是否包含内部数据(模块状态和模块输出)和外部数据(根输入端口和输出端口)的初始化代码(其值为零)。消除零初始化代码可加速模型初始化,减少 ROM 消耗,并提高生成代码的执行速度。

在启动期间,符合标准的 C 和 C++ 编译器将全局数据初始化为零,从而无需在生成的代码中包含此数据的零初始化代码。符合标准的编译器不一定将动态分配的数据和局部变量初始化为零。在选择删除根级 I/O 零初始化删除内部数据零初始化参数之前:

  • 如果您的编译器不符合标准,请确认它将全局数据初始化为零。

  • 如果将 Code interface packaging (component) 参数设置为可重用函数C++ 类,请确认数据是静态分配的,或者代码将动态分配的数据初始化为零。

如果将代码接口打包参数设置为 Reusable function 并选择使用动态内存分配进行模型初始化参数:

  • 删除根级 I/O 零初始化删除内部数据零初始化复选框已被清除。

  • 在命令行中,ZeroExternalMemoryAtStartupZeroInternalMemoryAtStartup 参数被设置为 'on'

如果将代码接口打包参数设置为 C++ 类并选择Use dynamic memory allocation for model block instantiation参数:

  • 删除内部数据零初始化复选框已被清除。

  • ZeroInternalMemoryAtStartup 参数设置为 'on' 并且是只读的。

删除内部数据的零初始化代码

此示例显示如何消除将内部数据初始化为零的代码。

示例模型

打开 InternalZeroInitialization 模型。该模型包含一个启用子系统,其初始输出为零。该子系统包含一个 Unit Delay 模块,其初始条件为 0

model = 'InternalZeroInitialization';
open_system(model);

生成不带优化的代码

使用 Embedded Coder® 构建模型。

evalc('slbuild(model)');

此代码位于 InternalZeroInitialization.c 文件中。

cfile = fullfile('InternalZeroInitialization_ert_rtw','InternalZeroInitialization.c');
coder.example.extractLines(cfile,'/* Model initialize', '* File trailer', 1, 0);
/* Model initialize function */
void InternalZeroInitialization_initialize(void)
{
  /* Registration code */

  /* initialize error status */
  rtmSetErrorStatus(rtM, (NULL));

  /* states (dwork) */
  (void) memset((void *)&rtDWork, 0,
                sizeof(D_Work));

  /* SystemInitialize for Enabled SubSystem: '<Root>/Enabled Subsystem' */
  /* InitializeConditions for UnitDelay: '<S1>/Unit Delay' */
  rtDWork.UnitDelay_DSTATE = 0.0;

  /* End of SystemInitialize for SubSystem: '<Root>/Enabled Subsystem' */
}

/*

启用优化

打开配置参数对话框。在优化窗格中,选择删除内部数据零初始化

或者,您可以使用命令提示符来启用优化。将模型参数 ZeroInternalMemoryAtStartup 设置为 'off'

set_param(model, 'ZeroInternalMemoryAtStartup', 'off');
set_param(model, 'ZeroInternalMemoryAtStartup', 'off');

生成优化代码

使用 Embedded Coder 构建模型。

evalc('slbuild(model)');

此代码位于 InternalZeroInitialization.c 文件中。生成的代码不会通过赋值零来初始化内部数据。

coder.example.extractLines(cfile,'/* Model initialize', '* File trailer', 1, 0);
/* Model initialize function */
void InternalZeroInitialization_initialize(void)
{
  /* (no initialization code required) */
}

/*
bdclose(model)

删除根级输入和输出端口的初始化代码并将其设置为零

此示例显示如何从设置为零的根级输入端口和输出端口中删除初始化代码。

示例模型

RootZeroInitialization 模型中,所有输入和输出信号的值都是零。因为信号 sig1sig2 分别具有数据类型 int16Boolean,并且所有输出信号都具有数据类型 double,所以这些信号的初始值也为按位零。信号具有 0 的整数位模式,这意味着所有位都关闭。信号 sig1_bsig2_b 具有带偏差的定点数据类型,因此它们的初始值不是按位零。

model = 'RootZeroInitialization';
open_system(model);

生成代码

% Build the model by using Embedded Coder.
set_param(model, 'ZeroExternalMemoryAtStartup','on');
evalc('slbuild(model)');

这些 RootZeroInitialization.c 代码行显示了未进行优化的根级输入端口和输出端口的初始化。四个输入信号分别初始化为全局变量。这四个输出信号是全局结构的成员,memset 函数将其按位初始化为零。

cfile = fullfile('RootZeroInitialization_ert_rtw',...
    'RootZeroInitialization.c');
coder.example.extractLines(cfile, '/* Model initialize function */',...
    'trailer for generated code', 1, 0);
/* Model initialize function */
void initialize(void)
{
  /* Registration code */

  /* external inputs */
  sig1 = 0;
  sig2 = false;
  sig1_b = -3;
  sig2_b = -3;

  /* external outputs */
  (void)memset(&rtY, 0, sizeof(ExternalOutputs));
}

/*

启用优化

  1. 打开配置参数对话框。

  2. 优化窗格中,选择删除根级别 I/O 零初始化

或者,使用命令行 API 来启用优化:

 set_param(model, 'ZeroExternalMemoryAtStartup','off');

生成优化代码

优化代码不包含输入信号 sig1sig2 和四个输出信号的初始化代码,因为它们的初始值按位均为零。

编译模型。

evalc('slbuild(model)');

这是初始化函数中的 RootZeroInitialization.c 优化代码。

cfile = fullfile('RootZeroInitialization_ert_rtw',...
    'RootZeroInitialization.c');
coder.example.extractLines(cfile, '/* Model initialize function */',...
    'trailer for generated code', 1, 0);
/* Model initialize function */
void initialize(void)
{
  /* Registration code */

  /* external inputs */
  sig1_b = -3;
  sig2_b = -3;
}

/*

关闭模型和代码生成报告。

bdclose(model)

附加信息

  • 默认情况下,代码生成器不会为设置为零的局部变量生成初始化代码。您可以通过清除删除初始化为零值的局部变量参数来禁用此优化。清除此参数可生成符合MISRA C++:2008 Rule 0-1-4 (Polyspace Bug Finder)等编码标准的代码。有关详细信息,请参阅控制将局部变量设置为零的初始化代码的生成

  • 您可以使用使用 memset 初始化浮点数和双精度数参数来控制初始化期间零的表示。请参阅Use memset to initialize floats and doubles to 0.0

  • 无论删除内部数据零初始化删除根级 I/O 零初始化参数的设置如何,代码都不会初始化存储类具有导入范围的零值。

  • 如果在 Initialize Function 模块中指定值(零或非零),则代码会初始化这些值,而不管删除内部数据零初始化删除根级 I/O 零初始化参数的设置如何。

  • 如果将输入端口连接到 Initialize Function 模块,则无论删除根级 I/O 零初始化参数的设置如何,代码都不会初始化该输入端口的值。

另请参阅

主题