このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
生成されたコード内のデータ ストア
データ ストアについて
データ ストアには、そのデータ ストアが定義されているレベル以下のモデルの階層でアクセスできるデータが含まれています。データ ストアによって、サブシステムや参照モデルは I/O 端子を使用してレベル間でデータの受け渡しを行わなくてもデータを共有することができます。Simulink® のデータ ストアの詳細については、Data Store Memory ブロックを使用したデータ ストアを参照してください。この節では、データ ストアのコード生成についてさらに詳しく説明します。
Data Store Memory ブロックに対するコード生成
Data Store Memory ブロック用に生成されたコードを制御するには、データ ストアにストレージ クラスを適用します。Data Store Memory ブロックをワークスペースまたはデータ ディクショナリに保存する信号オブジェクトに関連付けて、オブジェクトにストレージ クラスを適用することで、ブロックのコード生成を制御できます。
[モデル化] タブで [モデル データ エディター] をクリックします。
モデル データ エディターで、[データ ストア] タブを選択します。
[Name] 列の対応する行をクリックして、ターゲット Data Store Memory ブロックの名前の編集を開始します。
名前の横のボタン
をクリックして [作成と関連付け] を選択します。
[新規データの作成] ダイアログ ボックスで、[値] を
Simulink.Signal
に設定します。オプションで、[場所] ドロップダウン リストを使用して、結果のSimulink.Signal
オブジェクトを保存するワークスペースを選択します。[作成] をクリックします。データ ストアと同じ名前の
Simulink.Signal
オブジェクトは、ターゲット ワークスペースに表示されます。Simulink によりブロック パラメーター [データ ストア名を Simulink の信号オブジェクトに関連付ける] が選択されます。オブジェクトに対するプロパティ ダイアログ ボックスが開いたら、[OK] をクリックします。
Simulink Coder アプリまたは Embedded Coder アプリでコード マッピング エディターを開きます。[C コード] タブで、[コード インターフェイス] 、 [個々の要素コードのマッピング] を選択します。
[データ ストア] タブでターゲット ストレージ クラスを適用します。
メモ:
Data Store Memory ブロックを信号オブジェクトに関連付ける場合、データ ストアの名前と信号オブジェクトの名前のマッピングは 1 対 1 でなければなりません。同じ名前が付けられた 2 つ以上のエントリを 1 つの信号オブジェクトにマッピングすると、その名前の競合はコードの生成時にエラーとしてフラグが設定されます。詳細については、コード生成のための信号オブジェクトの設定の競合の解決を参照してください。
Data Store Memory ブロックのストレージ クラス
ストレージ クラスと型修飾子を割り当てることによって、モデル内の Data Store Memory ブロックが生成コード内でどのように格納され、どのように表現されるのかを制御することができます。これは、ブロック状態にストレージ クラスと型修飾子を割り当てるのとほとんど同じ方法で行います。
ブロック状態と同様に、Data Store Memory ブロックには既定の設定で [Auto]
ストレージ クラスが与えられており、メモリは DWork
ベクトル内に格納されています。ストレージ場所のシンボリック名は、データ ストア名が基になっています。
同じデータ ストア名をもつ複数の Data Store Memory ブロックからコードを生成することは可能ですが、同じ名前のブロックのうち [Auto]
以外のストレージ クラスをもつことができるのは "多くても 1 つのブロック" であるという制約があります。この条件が満たされないとエラーが報告されます。
[Auto]
ストレージ クラスのブロックの場合、コード ジェネレーターは各ブロックに固有のシンボリック名を生成して名前が衝突しないようにします。[Auto]
以外のストレージ クラスをもつ Data Store Memory ブロックの場合、生成コードはシンボルとしてデータ ストア名を使用します。
次のモデルでは、Data Store Write ブロックによって Data Store Memory ブロックの myData
で宣言されたメモリに書き込みが行われます。
Data Store Memory ブロックのストレージ宣言を制御するには、Coder アプリでコード マッピング エディターを使用します。[データ ストア] タブで、ブロックの [ストレージ クラス] を選択します。
.c
ファイルと .cpp
ファイルでの Data Store Memory ブロックの初期化と、ヘッダー ファイルでの Data Store Memory ブロックの宣言に対してコードが作成されるため、このブロックは非バーチャルです。次の表には、上記のモデル内の Data Store Memory ブロックについて生成されるコードがさまざまなストレージ クラスに応じてどのように異なるのかが示されています。以下の表に、myData
ブロックについて生成される変数宣言と MdlOutputs
コードを示します。
ストレージ クラス | 宣言 | コード |
---|---|---|
|
typedef struct D_Work_tag { real_T myData; } D_Work;
/* Block states (auto storage) */ D_Work model_DWork; | model_DWork.myData = rtb_SineWave; |
|
/* Exported block states */ real_T myData;
extern real_T myData; | myData = rtb_SineWave; |
|
extern real_T myData; | myData = rtb_SineWave; |
|
extern real_T *myData; | (*myData) = rtb_SineWave; |
ストレージ クラスの適用の詳細については、モデル インターフェイス要素の C コード生成の構成を参照してください。
ERT モデルの場合は、データストアで多次元配列の次元を保持できます。詳細については、Preserve Dimensions of Multidimensional Arrays in Generated Code (Embedded Coder)を参照してください。
生成コードでのデータ ストア バッファリング
Data Store Read ブロックは、実行時にデータ ストアの値を出力バッファーにコピーする非バーチャル ブロックです。値がバッファーされると、Data Store Write ブロックで 2 つの下流ブロックが実行される間にデータ ストアが更新されたとしても、Data Store Read ブロックの出力に接続されている下流ブロックで同じ値が利用されます。
次の図は、任意の実行順序を実現するために優先度が変更されているブロックを使用するモデルを示しています。
次の実行順序が適用されます。
Data Store Read ブロックは、出力時にデータ ストア
A
の現在の値をバッファーします。Abs1 ブロックは Data Store Read のバッファー済みの出力を使用します。
Data Store Write ブロックはデータ ストアを更新します。
Abs ブロックは Data Store Read のバッファー済みの出力を使用します。
Data Store Read の出力はバッファーであるため、Abs と Abs1 は両方とも同じ値、つまり Data Store Read の実行時のデータ ストアの値を使用します。
次の図は別の例を示しています。
この例では、次の実行順序が適用されます。
Data Store Read ブロックは、出力時にデータ ストア
A
の現在の値をバッファーします。Atomic Subsystem が実行されます。
Sum ブロックは Atomic Subsystem の出力を Data Store Read の出力に追加します。
Simulink は Atomic Subsystem がデータ ストアを更新することを前提としているため、Simulink はデータ ストアをバッファーします。Atomic Subsystem は Data Store Read で出力がバッファーされてから実行されます。また、このバッファーによって、Sum ブロックは Data Store Read の実行時と同じデータ ストアの値を使用するようになります。
場合によっては、Data Store Read ブロックの出力バッファーを最適化できるかどうかがコード ジェネレーターによって判定され、生成されたコードでは Data Store Read ブロックのバッファーされた値ではなくデータ ストアが直接参照されます。次の図で例を示します。
生成コードで、関数 fabs()
の引数はバッファーされた値ではなくデータ ストア A
です。
再利用可能なモデルのインスタンスにより共有されるデータ ストア
データストアを使用して、再利用可能な参照モデル (参照モデル インスタンス間でのデータの共有を参照) または (コンフィギュレーション パラメーター [コード インターフェイスのパッケージ化] の [再利用可能な関数]
への設定により) 再呼び出し可能なコードを生成するために設定するモデルのインスタンス間でデータを共有できます。データ ストアを Data Store Memory ブロックとして実装して、[モデル インスタンス間で共有する] パラメーターを選択する場合、次のようになります。
既定では、データ ストアは別個のグローバル シンボルとして生成されたコードに表示されます。
Embedded Coder® がある場合、モデルから生成されたコードのみがデータストアを使用できる、などのアクセス制限を行うには、ストレージ クラス
FileScope
を適用することでデータストアがstatic
として表示されるように設定します。FileScope
およびその他のストレージ クラスの詳細については、生成されたコードでのデータ表示を制御するストレージ クラスの選択 (Embedded Coder)を参照してください。
データ ストアを使用する生成コード内の構造体
1 つを超えるデータ ストアを使用して生成コード内の複数の信号にグローバルなアクセスを実現する場合は、1 つのデータ ストアを使用して複数の信号を単一の構造体変数にまとめることができます。このように信号データをまとめることで、モデルから生成されたコードを、データを構造体の形式にする必要がある他の既存のコードと統合しやすくなります。
この例では、1 つのデータ ストアを使用して複数のモデル信号を生成コード内の構造体に格納する方法を示します。複数のデータを 1 つのデータ ストアに格納するには、データ ストアが非バーチャル バス信号または非バーチャル バス信号の配列などの合成信号を受け入れるように設定します。
モデル例の確認
モデル例 BusStructInCode
を開きます。
open_system('BusStructInCode')
モデルに含まれている 3 つのサブシステムは、モデルの最上位レベルからの入力に対する計算を実行します。各サブシステムの Data Store Memory ブロックに中間計算信号が格納されます。
モデルを使用してコードを生成します。コード生成レポートで、ファイル BusStructInCode.c
を表示します。コードは各データ ストアのグローバル変数を定義します。
real_T BioBTURate; real_T CoalBTURate; real_T GasBTURate;
モデル例から生成されたコードを他の既存のコードと統合するとします。また、既存のコードは 1 つの構造体変数内の 3 つのデータ ストアのデータにアクセスする必要があるとします。データ ストアを使用して、生成コード内の構造体にあるターゲット データを組み合わせることができます。
データ ストアの設定
バス型を作成してデータ ストアのデータ型として使用することで、複数の信号を含むデータ ストアを設定します。生成コードに表示する構造体と同じ要素の階層を使用してバス型を定義します。
型エディター ツールを開きます。
typeeditor
それぞれの 3 つのターゲット信号の 1 つの要素を使用して新しいバス型
Raw_BTU_Rate
を定義します。要素BioBTU
、GasBTU
およびCoalBTU
に名前を付けます。モデル例の最上位レベルに Data Store Memory ブロックを追加します。
[モデル化] タブで [モデル データ エディター] をクリックします。
モデル データ エディターで、[データ ストア] タブを検査します。
新しい Data Store Memory ブロックの場合、[Value] 列を使用して、データ ストア名を
Raw_BTU_Data
に設定します。[Data Type] 列を使用して、データ ストアのデータ型を
Bus: Raw_BTU_Rate
に設定します。コード マッピング エディターの [データ ストア] タブで、ストレージ クラス
[ExportedGlobal]
をRaw_BTU_Data
に適用します。
データ ストア要素への書き込み
データ ストアの特定の要素に書き込むには、Data Store Write ブロックを使用します。ダイアログ ボックスの [要素の代入] タブで、1 つの要素、要素の集合またはデータ ストアのコンテンツ全体に書き込むように指定できます。
Biomass Calc Subsystem を開きます。
Data Store Memory ブロックで
BioBTURate
を削除します。Data Store Write ブロックのブロック ダイアログ ボックスで、[データ ストア名] を
Raw_BTU_Data
に設定します。[要素の代入] タブの [バス内信号] で、データ ストア
Raw_BTU_Data
のコンテンツを展開します。要素BioBTU
をクリックして、[選択] をクリックします。[OK] をクリックします。Gas Calc Subsystem および Coal Calc Subsystem も同様に変更します。
各サブシステムの Data Store Memory ブロックを削除します。
各 Data Store Write ブロックのダイアログ ボックスで、[データ ストア名] を
Raw_BTU_Data
に設定します。Gas Calc Subsystem で、Data Store Write ブロックを使用してデータストア要素
GasBTU
に書き込みます。Coal Calc Subsystem で、要素CoalBTU
に書き込みます。
データ ストア構造体を使用するコードの生成
モデル例のコードを生成します。
コード生成レポートで、ファイル
BusStructInCode.h
を表示します。このコードはバス型Raw_BTU_Rate
に対応する構造体を定義します。typedef struct { real_T BioBTU; real_T GasBTU; real_T CoalBTU; } Raw_BTU_Rate;
ファイル
BusStructInCode.c
を表示します。このコードは、構造体の型Raw_BTU_Rate
のグローバル変数Raw_BTU_Data
を使用するデータ ストアを表します。モデル ステップ関数で、コードは計算済みの信号のデータをグローバル変数Raw_BTU_Data
のフィールドに割り当てます。