メインコンテンツ

ゼロ初期化コードの削除

ルート レベル I/O のゼロ初期化を削除パラメーターと内部データのゼロ初期化を削除パラメーターは、値がゼロである内部データ (ブロック状態とブロック出力) と外部データ (ルートの Inport と Outport) の初期化コードを生成コードに含めるかどうかを制御します。ゼロ初期化コードを除去することで、モデルの初期化が高速になり、ROM の消費が低減され、生成コードの実行速度が向上します。

起動時に、規格に準拠した C および C++ コンパイラは、グローバル データをゼロに初期化するため、このデータのゼロ初期化コードを生成コードに含める必要はありません。規格に準拠したコンパイラは、動的に割り当てられたデータおよびローカル変数を必ずしもゼロに初期化するわけではありません。[ルート レベル I/O のゼロ初期化を削除] パラメーターと [内部データのゼロ初期化を削除] パラメーターを削除する前に以下を行います。

  • コンパイラが規格に準拠したものでない場合、グローバル データがゼロに初期化されることを確認します。

  • Code interface packaging (component)パラメーターを [再利用可能な関数] または [C++ クラス] に設定している場合、データが静的に割り当てられているか、動的に割り当てられたデータがコードでゼロに初期化されることを確認します。

[コード インターフェイスのパッケージ化] パラメーターを [Reusable function] に設定し、モデルの初期化に動的メモリ割り当てを使用パラメーターを選択すると、次のようになります。

  • [ルート レベル I/O のゼロ初期化を削除][内部データのゼロ初期化を削除] のチェック ボックスがオフになります。

  • コマンド ラインで ZeroExternalMemoryAtStartup パラメーターと ZeroInternalMemoryAtStartup パラメーターが 'on' に設定されます。

[コード インターフェイスのパッケージ化] パラメーターを [C++ クラス] に設定し、Use dynamic memory allocation for model block instantiationパラメーターを選択すると、次のようになります。

  • [内部データのゼロ初期化を削除] チェック ボックスがオフになります。

  • ZeroInternalMemoryAtStartup パラメーターが 'on' に設定されて読み取り専用になります。

内部データのゼロ初期化コードの削除

この例では、内部データをゼロに初期化するコードを除去する方法を示します。

モデル例

InternalZeroInitialization モデルを開きます。モデルには、初期出力がゼロである Enabled Subsystem が含まれています。そのサブシステムに、初期状態が 0 である Unit Delay ブロックが含まれています。

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)

ゼロに設定されたルート レベルの Inport と Outport からの初期化コードの削除

この例では、ゼロに設定されたルート レベルの Inport と Outport から初期化コードを削除する方法を示します。

モデル例

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 のコード行は、最適化を使用しない場合のルートレベルの Inport と Outport の初期化を示しています。4 つの入力信号のそれぞれがグローバル変数として個別に初期化されます。4 つの出力信号は、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');

最適化を使用したコードの生成

入力信号 sig1 および sig2 と 4 つの出力信号は初期値がビット単位でゼロになるため、それらの信号の初期化コードは最適化されたコードには含まれません。

モデルをビルドします。

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)などのコーディング規約に準拠するコードを生成するには、このパラメーターをオフにします。詳細については、ゼロに設定されたローカル変数の初期化コードの生成を制御を参照してください。

  • [float と double を 0.0 に初期化するために memset を使用] パラメーターを使用して、初期化時のゼロの表現を制御できます。float と double を 0.0 に初期化するために memset を使用を参照してください。

  • [内部データのゼロ初期化を削除] パラメーターと [ルート レベル I/O のゼロ初期化を削除] パラメーターの設定に関係なく、ストレージ クラスのスコープが [Imported] であるゼロ値はコードで初期化されません。

  • Initialize Function ブロックで値 (ゼロまたは非ゼロ) が指定されている場合、[内部データのゼロ初期化を削除] パラメーターと [ルート レベル I/O のゼロ初期化を削除] パラメーターの設定に関係なく、それらの値はコードで初期化されます。

  • Inport が Initialize Function ブロックに接続されている場合、[ルート レベル I/O のゼロ初期化を削除] パラメーターの設定に関係なく、その Inport の値はコードで初期化されません。

参考

トピック