Main Content

生成されたコードでの信号、状態、パラメーター データの初期化

モデル内の信号線、ブロック パラメーター、ブロックの状態は、生成されたコード内でグローバル変数などのデータとして表示されます。既定の設定では、コードはプライマリ アルゴリズムの実行前にこのデータを初期化します。Simulink®でのシミュレーションの数値と一致させるために、コード ジェネレーターはモデルで作成した仕様に基づいて初期値を選択します。

生成されたコードがデータを初期化する方法を理解すると、次を行うことができます。

  • 実行中に状態を再初期化するシステムをモデル化する。つまり、アプリケーションでシステム全体を再起動できる。

  • 初期値を変数としてメモリに保存する。これは、実行間で維持できる。これらの値はシステムを起動または再起動する前に上書きできる。

  • 不変な初期値のストレージを削除し、不必要または重複してデータを初期化するコードの生成を回避することで、効率的にコードを生成できる。

モデル内の信号および状態の初期化に関する基本的な情報については、信号と離散状態の初期化および状態情報の読み込みを参照してください。

静的初期化と動的初期化

グローバル変数などのデータ項目を初期化するために、アプリケーションは静的または動的な初期化を使用できます。

  • 静的初期化は変数を定義する (メモリを割り当てる) 同じステートメントで発生します。初期化は関数定義内では発生しません。

    生成されたモデル関数では初期化ステートメントが実行されないため、コードの効率を上げることができます。

  • 動的初期化は関数内で発生します。各モデルまたは非バーチャル サブシステムの場合、コード ジェネレーターは通常、初期化専用の 1 つ以上の関数を作成します。

    生成されたコードまたはコードは実行中に初期化関数を呼び出し、システムを再起動できます。

非ゼロのビット パターンが必要な実際のグラウンドの初期化

各データ項目には実際の"グラウンド値"があります。この値は項目のデータ型によって異なる場合があります。たとえば、データ型がdoubleまたはint8の信号の場合、実際のグラウンド値はゼロになります。列挙型の場合、グラウンド値は既定の列挙型メンバーになります。

データの種類によっては、実際のグラウンド値を表すためにコンピューターはゼロをメモリに保存します (すべてのビットがゼロ)。ただし、その他のデータによっては、コンピューターは非ゼロ値をメモリに保存します。このデータには、たとえば次が含まれます。

  • バイアスを併用する固定小数点データ。コードは、指定したスケーリングとバイアスを使用して実際のゼロを表す保存された整数値にこのようなデータ項目を初期化します。

  • 既定のメンバーをゼロ以外の整数値にマッピングする列挙型。たとえば、既定のメンバーが基となる整数値 3 を使用するHighの場合、コードはこのようなデータ項目をHighに初期化します。

信号と状態データの初期化

モデル内では、ブロック パラメーターを使用して信号と状態データの値を制御できます。たとえば、Unit Delayブロックの初期値を設定するには、[初期条件]パラメーターを使用します。場合によっては、Simulink.SignalオブジェクトのInitialValueプロパティを使用することもできます。これらのブロック パラメーターのほとんどにおいて、既定値は0です。

また、Initialize Functionサブシステム内のState Writerブロックと[初期状態]モデル コンフィギュレーション パラメーターを使用して状態を初期化することもできます。

既定の設定では、生成されたコードは信号と状態データ (およびモデルのエラー ステータスなどのその他のデータ) を生成された初期化関数内で動的に初期化します。既定でmodel_initializeという名前のこの関数は、信号と状態の初期化操作を次の順序で実行します。

  1. DWork 構造体などの生成された既定の構造体内にある信号と状態データを、保存されたゼロの値に初期化します。

  2. 生成された既定の構造体内にない追加の信号と状態データを関連する実際のグラウンド値に初期化します。

    この初期化は次の両方の条件を満たすデータに対してのみ適用されます。

    • 生成されたコードはデータを定義する (メモリを割り当てる)。

    • データはAuto(既定のストレージ クラス) またはModel default以外のストレージ クラスを使用します (コード マッピング エディターで[既定]ストレージ クラスを指定する場合は、既定の設定)。

    たとえば、コードはこの操作をストレージ クラスExportedGlobalを使用するデータ項目に適用します。

  3. たとえばUnit Delayブロックの[初期条件]パラメーターを使用して、モデルが指定する実際値に各信号と状態を初期化します。

  4. State Writerブロックを使用して代入する実際値に各状態を初期化します。この関数は、Initialize Functionサブシステムをモデル内で使用する場合にのみこの初期化を実行します。

  5. コンフィギュレーション パラメーターの[初期状態]で指定する実際値に各状態を初期化します。

この初期化関数を実行すると、関数が代入した最後の実際値が各データ項目に追加されます。たとえば、State Writerブロックを使用してブロックの状態を5に初期化し、同時に[初期状態]コンフィギュレーション パラメーターを使用して同じ状態を10に初期化すると、状態は最終的に10を初期値として使用します。

一括初期化用のmemset

連続するストレージをもつ信号または状態のデータ項目を保存されたゼロの値に初期化するために、生成されたコードで初期化変数にmemsetを呼び出すことができます。連続するストレージをもつデータ項目には DWork 構造体、配列またはマルチワード データ型を使用するデータ項目が含まれます。

アプリケーションで必要な場合は、生成されたデータがmemsetを使用して浮動小数点データ型を保存されたゼロに初期化するのを回避できます。float と double を 0.0 に初期化するために memset を使用を参照してください。

調整可能な初期値

Gainブロックの[ゲイン]パラメーターなど、調整可能なブロック パラメーターが生成されたコードに表示される方法を設定できます。初期値を設定するほとんどのブロック パラメーター ([初期条件]など) は調整可能です。たとえば、コンフィギュレーション パラメーターの[既定のパラメーター動作]では、生成されたコード内で初期値をインライン化された定数または調整可能なグローバル データのどちらとして表示するかを決定できます。また、パラメーター オブジェクトとストレージ クラスを使用してこれらの初期値の表現を制御できます。

調整可能な初期値の場合、モデル初期化関数では代入ステートメントの右側がグローバル変数、構造体フィールドまたはメモリ内で変更可能な値をもつその他のデータになります。

生成されたコード内で初期値を調整可能にする方法の詳細については、生成されたコードにおける信号および状態の初期化の制御を参照してください。

パラメーター データの初期化

生成されたコードは、パラメーター データを Simulink で指定した値に静的に初期化します。

調整可能なパラメーター (グローバル変数) の初期値をシステム定数または他のマクロを伴う数式として表す場合は (Embedded Coder®を必要とします)、数式による初期化 (Embedded Coder)を参照してください。

パラメーター データの種類

次のモデル要素は生成されたコード内でパラメーター データとして表示されます。

  • [既定のパラメーター動作][調整可能]に設定した場合のGainブロックの[ゲイン]パラメーターなどの調整可能なブロック パラメーター。各パラメーターは専用のグローバル構造体のフィールドとして表示されます。

  • [既定のパラメーター動作][インライン]に設定した場合の調整可能な一部のブロック パラメーター。コード ジェネレーターがパラメーターの値を数値リテラルとしてインライン化できない場合、パラメーターは専用のグローバルなconst構造体のフィールドとして表示されます。

  • エクスポートされたデータ スコープをもつストレージ クラスを適用するSimulink.Parameterオブジェクト。たとえば、組み込みストレージ クラスExportedGlobalにはエクスポートされたデータ スコープがありますが、ストレージ クラスImportedExternにはありません。

数式による初期化 (Embedded Coder)

パラメーター オブジェクト (Simulink.Parameterなど) の値を、数値、MATLAB®変数、他のパラメーター オブジェクトを伴う数式に設定できます。数式を使用した変数値の設定を参照してください。

この手法を Embedded Coder で使用する場合、指定した式を使用して、対応するパラメーター データ (グローバル変数) を初期化するコードを生成できます。例については、システム定数または他のマクロからのパラメーター値の初期化 (Embedded Coder)(Embedded Coder)を参照してください。制限など、一般情報については、式の値を使用したパラメーター オブジェクトのコード生成を参照してください。

生成されたコードでのデータの初期化

この例では、生成されたコードが信号、状態、パラメーター データを初期化する方法を示します。

モデル例の確認

モデル例rtwdemo_rtwintroを開きます。

open_system('rtwdemo_rtwintro')

アプリ ギャラリーで[Simulink Coder]をクリックします。

モデル データ エディターを開きます。[モデル化]タブで[モデル データ エディター]をクリックします。

[状態]タブを検査します。Unit Delay ブロックの状態について、[初期値]は既定で0に設定されます。つまり、状態の初期値はゼロです。状態の名前はXです。

[初期値]5などの非ゼロの数値に設定します。

set_param('rtwdemo_rtwintro/X','InitialCondition','5')

コード マッピング エディターを開きます。[C コード]タブで、[コード インターフェイス]、[個々の要素コードのマッピング]を選択します。

[信号/状態]タブの[状態]で、X[ストレージ クラス]ExportedGlobalに設定します。この設定により、ブロックの状態が独立したグローバル変数として生成されたコードに現れます。

coder.mapping.utils.create('rtwdemo_rtwintro'); cm = coder.mapping.api.get('rtwdemo_rtwintro'); setState(cm,'rtwdemo_rtwintro/X','StorageClass','ExportedGlobal');

モデルで、Triggered Subsystem であるAmplifierサブシステムを開きます。

モデル データ エディターで、[パラメーター]タブを検査します。信号および状態の初期値の設定および確認のために、[状態]タブではなく[パラメーター]タブを使用できます。

Outport ブロックの[初期出力](InitialOutput) パラメーターが既定値の0に設定されていることがモデル データ エディターに表示されます。このサブシステムは条件付きで実行されるため、このサブシステムの出力には初期値が必要です。初期値は既定のままにします。

モデルで、[コンフィギュレーション パラメーター]、[信号ストレージの再利用]をオフにします。この設定をオフにすると、信号データを保存する目的で生成された構造体のフィールドとして、信号線が生成されたコードに表示されます。この信号の表現により、コード ジェネレーターでデータが初期化される方法を確認しやすくなります。

set_param('rtwdemo_rtwintro','OptimizeBlockIOStorage','off')

モデルで、コンフィギュレーション パラメーター ([コンフィギュレーション パラメーター]、[最適化]、[既定のパラメーター動作]) を検証します。コンフィギュレーション パラメーターはInlinedに設定されています。つまり、初期値を含むブロック パラメーターは、インライン化されたリテラルまたはconstデータとして生成されたコードに現れます。

モデルのルート レベルに移動します。

モデル データ エディターで[追加情報の表示/更新]ボタンをクリックします。

[コンテンツのフィルター]ボックスの近くの[選択を使用してフィルター処理します]ボタンをクリックします。

モデルでINCというラベルの Constant ブロックをクリックします。このブロックの[定数値](Value) パラメーターはINCに設定されていることがモデル データ エディターで表示されます。INCはベース ワークスペース内の MATLAB 変数です。

INCについて、[値]列の値をSimulink.Parameter(uint8(1))に設定します。MATLAB によってINCSimulink.Parameterオブジェクトに変換されます。

コード マッピング エディターの[パラメーター]タブで、ストレージ クラスExportedGlobalINCに適用します。この設定により、生成されたコードではINCがグローバル変数として定義されます。初期化の場合、INCはパラメーター データの項目です。

INC = Simulink.Parameter(INC); INC.StorageClass ='ExportedGlobal';

コードの生成と検査

モデルをビルドしてコードを生成するには、Ctrl+Bを押します。

slbuild('rtwdemo_rtwintro');
### Starting build procedure for: rtwdemo_rtwintro ### Successful completion of build procedure for: rtwdemo_rtwintro Build Summary Top model targets built: Model Action Rebuild Reason ================================================================================================= rtwdemo_rtwintro Code generated and compiled Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 16.023s

生成されたファイルrtwdemo_rtwintro.cのコードでは、関数定義の外でパラメーター データINCが静的に初期化されています。INCの値は1です。

file = fullfile('rtwdemo_rtwintro_grt_rtw','rtwdemo_rtwintro.c'); rtwdemodbtype(file,'/* Exported block parameters */','uint8_T INC = 1U;',1,1)
/* Exported block parameters */ uint8_T INC = 1U; /* Variable: INC

同じファイル内で関数rtwdemo_rtwintro_initializeの定義を検証します。最初に、この関数はmemsetを使用して、モデル内の内部信号を保存された0の値に初期化します。

rtwdemodbtype(file,'/* block I/O */','sizeof(B_rtwdemo_rtwintro_T));',1,1)
/* block I/O */ (void) memset(((void *) &rtwdemo_rtwintro_B), 0, sizeof(B_rtwdemo_rtwintro_T));

次に、関数は Unit Delay の状態Xをグラウンド値に初期化します。この場合、グラウンド値はゼロです。

rtwdemodbtype(file,'/* exported global states */','X = 0U;',1,1)
/* exported global states */ X = 0U;

また、この関数はルートレベルの入出力 (Inport ブロックと Outport ブロック) を含めたその他のデータもグラウンド値に初期化します。

rtwdemodbtype(file,'/* external inputs */','Amplifier_Trig_ZCE = POS_ZCSIG;',1,1)
/* external inputs */ rtwdemo_rtwintro_U.Input = 0; /* external outputs */ rtwdemo_rtwintro_Y.Output = 0; rtwdemo_rtwintro_PrevZCX.Amplifier_Trig_ZCE = POS_ZCSIG;

次に、関数はX[初期条件]ブロック パラメーターで指定した値に初期化します。

rtwdemodbtype(file,'/* InitializeConditions for UnitDelay: ''/X'' */',...'X = 5U;',1,1)
/* InitializeConditions for UnitDelay: '/X' */ X = 5U;

最後に、関数はAmplifierサブシステムの出力を初期化します。

rtwdemodbtype(file,'SystemInitialize for Triggered SubSystem',...'End of SystemInitialize for SubSystem',1,1)
/* SystemInitialize for Triggered SubSystem: '/Amplifier' */ /* SystemInitialize for Outport: '/Output' incorporates: * Outport: '/Out' */ rtwdemo_rtwintro_Y.Output = 0;

保存された値と実際値との違いの検証

一部のデータでは、実際の初期値がゼロであってもコンピューターのメモリに非ゼロの値が保存されます。この違いを確認するには、勾配とバイアスでスケーリングされた固定小数点データ型をブロックの状態Xに適用します。この例を実行するには、Fixed-Point Designer™ が必要です。

モデル データ エディターで、[信号]タブを検査します。

モデルで、Switch ブロックswitch_outの出力信号をクリックします。

モデル データ エディターの[データ型]列を使用して、信号のデータ型をfixdt(1,16,1,3)に設定します。この式は1の勾配と3のバイアスをもつ固定小数点データ型を表します。

set_param('rtwdemo_rtwintro/Switch','OutDataTypeStr',...'fixdt(1,16,1,3)')

モデルで、Sum ブロックを選択します。プロパティ インスペクターで、[信号属性]の下の[すべての入力が同じデータ型をもつ]をオフにします。

set_param('rtwdemo_rtwintro/Sum','InputSameDT','off')

異なるプラットフォームでコンパイルエラーを回避するには,モデル コンフィギュレーション パラメーターの[コード生成のみ]を選択します。この設定により、モデルで生成されるのはコードのみになります。

set_param('rtwdemo_rtwintro','GenCodeOnly','on')

モデルをビルドしてコードを生成するには、Ctrl+Bを押します。

slbuild('rtwdemo_rtwintro')
### Starting build procedure for: rtwdemo_rtwintro ### Successful completion of code generation for: rtwdemo_rtwintro Build Summary Top model targets built: Model Action Rebuild Reason =================================================================== rtwdemo_rtwintro Code generated Generated code was out of date. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 6.8432s

モデル初期化関数は、最初にXを実際のグラウンド値0に初期化します。バイアス3をもつ勾配とバイアスでスケーリングされたデータ型により、この実際値は保存された-3の値に対応します。

rtwdemodbtype(file,'/* exported global states */','X = -3;',1,1)
/* exported global states */ X = -3;

次に、関数はX[初期条件]ブロック パラメーターで指定した実際の初期値である5に初期化します。この実際値は保存された2の値に対応します。

rtwdemodbtype(file,'/* InitializeConditions for UnitDelay: ''/X'' */',...'X = 2;',1,1)
/* InitializeConditions for UnitDelay: '/X' */ X = 2;

モデル化の目的

目的 詳細
ブロックを使用した初期化動作の明示的なモデル化

Initialize FunctionサブシステムとReset Functionサブシステムを使用して初期化とリセット動作を明示的にモデル化できます。サブシステムでState Writerブロックを使用し、初期値を計算して状態に動的に代入します。対応するコードがモデル初期化関数に表示されます。

詳細については、Startup, Reset, and Shutdown Function Interfaces(Embedded Coder)を参照してください。

明示的にデータをゼロに初期化するコード生成の防止

アプリケーション環境で既にグローバル変数をゼロに初期化している場合は、コードをより効率的にするため、グローバル変数を明示的にゼロに初期化するステートメントの生成を防ぐことができます。この最適化はメモリにゼロとして保存されている初期値をもつ信号と状態に対してのみ適用されます。たとえば、コード ジェネレーターは以下に対して最適化を適用しません。

  • ブロック パラメーターを使用して非ゼロの初期値を指定するデータ。

  • 実際値はゼロでも、対応する保存された値がゼロではないデータ。

  • 既定のメンバーが非ゼロの整数にマッピングされる列挙型データ。

最適化には Embedded Coder が必要です。詳細については、Remove Zero Initialization Code(Embedded Coder)を参照してください。

外部コードからデータをインポートするコードの生成

外部コードが定義するデータを再利用 (インポート) するコードを生成できます。たとえば、ストレージ クラスImportedExternを信号線、ブロックの状態、パラメーター オブジェクトに適用できます。インポートしたデータには以下が適用されます。

  • 生成されたコードはパラメーター データを初期化しない。インポートしたパラメーター データはコードで初期化しなければなりません。

  • 生成した初期化関数は一部の信号と状態データを動的に初期化する。生成されたコードによって割り当てられるデータとは異なり、コードは、インポートした信号または状態データを保存されたゼロの値に初期化しません。その代わり、コードはデータを Simulink で指定した実際値にすぐに初期化します。

生成されたコードによるインポート データの初期化を回避する方法など、詳細については、外部の呼び出しコードと生成コード間のデータ交換を参照してください。

参考

関連するトピック