Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

生成されたコードにおける構造体へのデータの整理

C コードでは、構造体 (struct) を使用してデータをメモリの連続した位置に格納します。信号や状態などのデータを意味のある名前を使用して整理できます。各構造体は名前空間として機能するため、複数のデータ項目を指定するために名前を再利用できます。配列と同様に、構造体を利用すれば、ポインターの使用によって効率的に大量のデータを転送、操作するコードを記述できます。

既定では、コード ジェネレーターはデータを標準の構造体に集約します (生成されたコードによる内部信号、状態、パラメーター データの保存方法を参照)。これらの構造体の特性を制御したり、異なる構造体を作成してこの既定の動作をオーバーライドしたりする場合は、次の表の情報を使用してください。

目的手法

標準のデータ構造体の特性を制御する。たとえば、構造体型の名前、構造体変数、フィールド名を指定します。

Embedded Coder® を使用する場合、Manage Replacement of Simulink Data Types in Generated Code (Embedded Coder)を参照してください。

たとえば、プラグマまたはその他のコード装飾を挿入して、メモリ内の構造体の配置を制御する。

Embedded Coder を使用する場合、Control Data and Function Placement in Memory by Inserting Pragmas (Embedded Coder)を参照してください。

名前および他の基本特性が制御可能な構造体にデータを集約する。ブロックおよび信号をモデルに追加すると、結果の新しいデータがこれらの構造体に既定で表示される。

Embedded Coder を使用する場合、コード マッピング エディターを使用して、構造体化されたストレージ クラスをデータのカテゴリに適用します。

  • モデル コンフィギュレーション パラメーターの [コード インターフェイスのパッケージ化][再利用できない関数] に設定して再利用できない単一インスタンスのコードを生成する場合、組み込みストレージ クラス Struct を適用して、フラットなグローバル構造体変数を作成します。または、クイック スタート ツールで作成したストレージ クラスの例 ParamStructSignalStruct を使用するか、独自の構造体化されたストレージ クラスを適用します。

  • たとえば、[コード インターフェイスのパッケージ化][再利用できない関数] 以外の値に設定して、モデルまたはコンポーネントからマルチインスタンス (再呼び出し可能な) コードを生成する場合、コード マッピング エディターでは、組み込みストレージ クラス Struct またはパッケージで作成する構造体化されたストレージ クラスを使用することはできません。代わりに、Embedded Coder ディクショナリを使用して独自の構造体化されたストレージ クラスを作成します。Embedded Coder クイック スタート ツールを使用してコード生成用のモデルを準備する場合 (クイック スタート ツールを使用したコードの生成 (Embedded Coder)を参照)、ストレージ クラスの例 ParamStructSignalStruct を使用できます。

  • この手法を使用してグローバル データ ストアまたはグローバル パラメーターを集約することはできません (ベース ワークスペースまたはデータ ディクショナリに保存するパラメーター オブジェクトも含む)。これらの種類のデータについては、他の手法を使用して構造体を作成してください。

コード マッピング エディターの詳細については、Configure Default C Code Generation for Categories of Data Elements and Functions (Embedded Coder)を参照してください。独自のストレージ クラスを作成するには、Define Service Interfaces, Storage Classes, Memory Sections, and Function Templates for Software Architecture (Embedded Coder)を参照してください。

細かく制御できる特性をもつカスタム構造体に個々のデータ項目を整理して、生成されたコードの可読性を向上する。

必要な構造体型を表す Simulink.Bus オブジェクトを作成します。バス オブジェクトを使用して、非バーチャル バス信号のデータ型およびパラメーター構造体をモデルで設定します。

  • パラメーター データの整理方法を示す例については、パラメーターの構造体を参照してください。

  • 信号データの整理方法を示す例については、信号の構造体を参照してください。

構造体の配列を作成するには、構造体の配列を参照してください。

生成されたコードと外部コード間で構造化されたデータを交換する (たとえば、外部コードで既にカスタム構造体型と対応するグローバル変数を定義している場合など)。

必要な構造体型を表す Simulink.Bus オブジェクトを作成します。外部コードで既に型を定義している場合、関数 Simulink.importExternalCTypes を使用してバス オブジェクトを生成します。バス オブジェクトを使用して、非バーチャル バス信号のデータ型およびパラメーター構造体をモデルで設定します。例については、Exchange Structured and Enumerated Data Between Generated and External Code (Embedded Coder)を参照してください。

生成された関数の引数 (仮パラメーター) の数を減らす。

  • model_step など、コードを生成するモデルのエントリポイント関数に対する引数の数を減らすには、構造体を使用した引数の数の削減を参照してください。

  • 参照モデルのエントリポイント関数に対する引数の数を減らす場合は、参照モデルで次のようにします。

  • 再呼び出し可能なマスク サブシステムのエントリポイント関数の引数の数を減らすには、マスク パラメーターをカスタム構造体に集約します。

ルックアップ テーブル データを構造体に整理する。

Simulink.LookupTable オブジェクトと Simulink.Breakpoint オブジェクトを使用します。Simulink.LookupTable を参照してください。
ビット フィールドを生成する。ビットフィールド (Embedded Coder)およびboolean データをビットフィールドにパッキングすることによる生成コードの最適化 (Embedded Coder)を参照してください。

構造体を作成する手法

生成されたコードで構造体を作成するには、次の手法を使用します。

  • コード マッピング エディターを使用して、構造体化されたストレージ クラスをデータのカテゴリに適用します。ブロックと信号をモデルに追加すると、既定の設定で新しいデータ要素がこのストレージ クラスを取得します。

  • モデル データ エディターを使用して、組み込みストレージ クラス Struct などの構造体化されたストレージ クラスを個々のデータ項目に直接適用します。

  • カスタム非バーチャル バスおよびパラメーター構造体を作成します。

使用する手法を決定するには、次の表の情報を使用してください。

機能構造体化されたストレージ クラスの既定の適用構造体化されたストレージ クラスの直接適用 非バーチャル バスとパラメーター構造体
既定の設定で新しいデータ項目を構造体に集約

あり

なしなし
最適化でターゲット データの削除を回避 (生成されたコードにデータが表示されるように指定)

なし

ありExportedGlobal などのストレージ クラスをバスまたは構造体に直接適用する場合のみ
ブロック線図の外観を変更せずにデータを構造体に集約

あり

ありなし
信号、状態、パラメーター データを同じ構造体に配置なしありなし
構造体に状態のデータを含めるありありなし
入れ子にされた構造体に構造体を整理なしなしあり
構造体の配列に構造体を整理なしなしあり
構造体型の名前を制御

あり

あり。ただし、型名は指定した変数名から派生するあり
生成された関数で引数の数を減らす構造体を作成

あり。ただし、Embedded Coder ディクショナリを使用して独自のストレージ クラスを作成しなければならない

なしあり
Embedded Coder が必要ありありなし

構造体化されたストレージ クラスの既定の適用

既定のストレージ クラスをモデル データのカテゴリに適用できます。モデルにブロックおよび信号を適用すると、関連付けられたデータは指定する既定のストレージ クラスを取得します。既定の設定で新しいデータを構造体に集約するには、構造体化されたストレージ クラスを適用します。クイック スタート ツールで作成したストレージ クラスの例 ParamStructSignalStruct を使用するか、Embedded Coder ディクショナリを使用して独自のストレージ クラスを作成しなければなりません。

既定の適用を使用してグローバル データ ストアまたはグローバル パラメーター (ベース ワークスペースまたはデータ ディクショナリに保存するパラメーター オブジェクト) を集約することはできません。

既定のストレージ クラスを適用にするには、コード マッピング エディターを使用します。モデル ウィンドウのアプリ ギャラリーで、[Embedded Coder] をクリックします。次に、[コード マッピング][Data Defaults] で、[Storage Class] 列を使用してストレージ クラスを適用します。

コード マッピング エディターの詳細については、Configure Default C Code Generation for Categories of Data Elements and Functions (Embedded Coder)を参照してください。Embedded Coder ディクショナリを使用して独自のストレージ クラスを作成する場合は、Create Code Definitions for Use in the Code Mappings Editor (Embedded Coder)を参照してください。

構造体化されたストレージ クラスの直接適用

構造体化されたストレージ クラスを個々のデータ項目に適用できます。直接適用では、[既定のパラメーター動作][信号ストレージの再利用] などのコード生成最適化によって生成されたコードから各データ項目が削除されなくなります。また、直接適用では、[コード マッピング][Data Defaults] で指定する既定のストレージ クラスをオーバーライドします。

ストレージ クラスを直接適用するには、モデル データ エディター ([モデル化] タブで [モデル データ エディター] をクリック) を使用します。[ビューの変更][コード] に設定し、[Storage Class] 列を使用してストレージ クラスを適用します。

Struct の使用方法を示す例については、C コード生成のパラメーターの構成 (Embedded Coder)を参照してください。ストレージ クラスの適用の詳細については、Struct ストレージ クラスを使用してパラメーター データを構造体に整理する (Embedded Coder)を参照してください。

非バーチャル バスとパラメーター構造体

  • 非バーチャル バスを作成するには、Bus Creator ブロックを使用して複数の信号線を単一のバスに整理するか、Inport ブロックまたは Outport ブロックを非バーチャル バスとして設定します。構造体型を表す Simulink.Bus オブジェクトを作成しなければなりません。例については、信号の構造体を参照してください。非バーチャル バスの詳細については、非バーチャル バスの作成を参照してください。

  • パラメーター構造体を作成するには、MATLAB® コマンドまたは変数エディターを使用して複数のブロック パラメーター値を MATLAB 構造体に整理します。オプションで、Simulink.Bus オブジェクトを作成して構造体型の名前および各フィールドのデータ型と次元などの他の特性を制御できるようにします。例については、パラメーターの構造体を参照してください。パラメーター構造体の一般情報については、関連するブロック パラメーター定義を構造体に整理を参照してください。

パラメーターの構造体

生成されたコードで構造体を作成します。構造体は、パラメーター データを格納します。

C コンストラクター

typedef struct {
  double G1;
  double G2;
} myStructType;

myStructType myStruct = {
  2.0,
  -2.0
} ; 

手順

1. モデル例 InlineBlockParameters を開きます。

2. [モデル化] タブで [モデル データ エディター] をクリックします。モデル データ エディターで、[パラメーター] タブを選択します。

3. モデルで、G1 というラベルの付いた Gain ブロックをクリックします。モデル データ エディターで、[値] 列を使用して、[ゲイン] パラメーターの値を myStruct.G1 に設定します。

4. G2 ブロックの [ゲイン] パラメーターの値を myStruct.G2 に設定します。

5. myStruct.G2 の横にあるアクション ボタン (3 つの縦向きのドット) をクリックし、[作成] を選択します。

6. [新規データの作成] ダイアログ ボックスで、[値]Simulink.Parameter(struct) に設定して [作成] をクリックします。myStruct という名前の Simulink.Parameter オブジェクトがベース ワークスペースに表示されます。

7. Simulink.Parameter プロパティのダイアログ ボックスで、[値] プロパティの横にあるアクション ボタンをクリックし、[変数エディターを開く] を選択します。

8. [フィールド] 列の下にある空白を右クリックして [新規作成] を選択します。新しい構造体フィールドに G1 という名前を付けます。[値] 列を使用して、そのフィールドの値を 2 に設定します。

9. フィールド G2 を追加してから (フィールドの値は -2)、変数エディターを閉じます。

10. Simulink.Parameter プロパティのダイアログ ボックスの [コード生成] タブで、[ストレージ クラス]ExportedGlobal に設定します。構造体 myStruct はグローバル変数として生成されたコードに表示されます。

11.モデルからコードを生成します。

結果

生成されたヘッダー ファイル InlineBlockParameters_types.h は、ランダムな名前の構造体型を定義します。

typedef struct {
  real_T G1;
  real_T G2;
} struct_6h72eH5WFuEIyQr5YrdGuB;

ソース ファイル InlineBlockParameters.c は、構造体変数 myStruct を定義および初期化します。

/* Exported block parameters */
struct_6h72eH5WFuEIyQr5YrdGuB myStruct = {
  2.0,
  -2.0
} ;                                    /* Variable: myStruct
                                        * Referenced by:
                                        *   '<Root>/G1'
                                        *   '<Root>/G2'
                                        */

構造体型の名前の指定

1. オプションで、構造体型定義 (struct) を使用するために名前を指定します。コマンド プロンプトで、関数 Simulink.Bus.createObject を使用して構造体型を表す Simulink.Bus オブジェクトを作成します。

2. オブジェクトの既定の名前は slBus1 です。オブジェクトを新しい MATLAB® 変数にコピーして名前を変更します。

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

4. データ テーブルで myStruct に対応する行を見つけます。[データ型] 列を使用して、myStruct のデータ型を Bus: myStructType に設定します。

5. モデルからコードを生成します。

コードは構造体型 myStructType の定義を生成し、この型を使用してグローバル変数 myStruct を定義します。

myStructType myStruct = {
  2.0,
  -2.0
} ;                                    /* Variable: myStruct

信号の構造体

この例では、生成されたコードで信号データの構造体を作成する方法を示します。

C コンストラクター

typedef struct {
   double signal1;
   double signal2;
   double signal3;
} my_signals_type;

手順

モデルで構造体型を表すには、Simulink.Bus オブジェクトを作成します。このオブジェクトをモデル内のバスのデータ型として使用します。

1. ex_signal_struct モデルを Gain ブロック、Bus Creator ブロック、Unit Delay ブロックを使用して作成します。Gain ブロックと Unit Delay ブロックによって、生成されたコードで構造体がより識別しやすくなります。

2. 3 つの入力を受け入れるように Bus Creator ブロックを設定するには、ブロック ダイアロブ ボックスで [入力数]3 に設定します。

3. ツールストリップの [モデル化] タブの [設計] ギャラリーで、[型エディター] をクリックします。

4. 型エディターで、signal1signal2、および signal3 という名前の要素を含む my_signals_type という名前の Simulink.Bus オブジェクトを作成します。詳細については、Type Editorを参照してください。

5. バス オブジェクトを現在のフォルダーに ex_signal_struct_data.mat として保存します。

このバス オブジェクトは、生成されたコードで使用する構造体型を表します。

6. [Bus Creator ブロック] ダイアログ ボックスで、次を行います。

  • [出力データ型]Bus: my_signals_type に設定します。

  • [非バーチャル バスとして出力] を選択します。非バーチャル バスが生成されたコードに構造体として表示されます。

  • [OK] をクリックします。

7. Simulink Coder アプリを開きます。[C コード] タブで、[コード インターフェイス][個々の要素コードのマッピング] を選択します。

8. [信号/状態] タブを開きます。モデルで Bus Creator ブロックの出力信号を選択し、コード マッピング エディターで [選択した信号をコード マッピングに追加] ボタンをクリックします。

9. 追加された信号について [ストレージ クラス]ExportedGlobal に設定します。

10. プロパティ インスペクターで [コード][Identifier] プロパティを sig_struct_var に設定します。Bus Creator ブロックの出力は生成されたコードに sig_struct_var という名前の個別のグローバル構造体変数として表示されます。

11.モデルからコードを生成します。

結果

生成されたヘッダー ファイル ex_signal_struct_types.h は構造体型 my_signals_type を定義します。

typedef struct {
  real_T signal1;
  real_T signal2;
  real_T signal3;
} my_signals_type;

ソース ファイル ex_signal_struct.c は、Bus Creator ブロックの出力を表すグローバル変数 sig_struct_var にメモリを割り当てます。

/* Exported block signals */
my_signals_type sig_struct_var;        /* '<Root>/Bus Creator' */

同じファイル内のモデルの関数 step で、アルゴリズムは sig_struct_varsig_struct_var のフィールドにアクセスします。

信号の入れ子にされた構造体

生成されたコードで信号データの入れ子にされた構造体を作成できます。

C コンストラクター

typedef struct {
  double signal1;
  double signal2;
  double signal3;
} B_struct_type;

typedef struct {
  double signal1;
  double signal2;
} C_struct_type;

typedef struct {
  B_struct_type subStruct_B;
  C_struct_type subStruct_C;
} A_struct_type;

手順

モデルで構造体型を表すには、Simulink.Bus オブジェクトを作成します。このオブジェクトをモデル内のバスのデータ型として使用します。

別の構造体内に構造体を入れ子にするには、別のバス オブジェクト内でバス オブジェクトを要素のデータ型として使用します。

1. ex_signal_nested_struct モデルを Gain ブロック、Bus Creator ブロック、Unit Delay ブロックで作成します。Gain ブロックと Unit Delay ブロックによって、生成されたコードで構造体がより識別しやすくなります。

3 つの入力を受け入れるように Bus Creator ブロックを設定するには、ブロック ダイアロブ ボックスで [入力数]3 に設定します。

2. ツールストリップの [モデル化] タブの [設計] ギャラリーで、[型エディター] をクリックします。

3. 型エディターで、Simulink.Bus オブジェクトを 3 つ作成します。

  • subStruct_B および subStruct_C という名前の 2 つの要素を含む A_struct_type という名前のバス オブジェクト

  • signal1signal2、および signal3 という名前の 3 つの要素を含む B_struct_type という名前のバス オブジェクト

  • signal1 および signal2 という名前の 2 つの要素を含む C_struct_type という名前のバス オブジェクト

A_struct_type という名前のバス オブジェクトは、生成されたコードで使用する最上位構造体型を表します。

バス オブジェクトとその要素の作成方法については、Type Editorを参照してください。

4. A_struct_type オブジェクトで、他のバス オブジェクトをデータ型として使用します。

  • subStruct_B 要素について、[データ型]Bus: B_struct_type に設定します。

  • subStruct_C 要素について、[データ型]Bus: C_struct_type に設定します。

A_struct_type の各要素は別のバス オブジェクトをデータ型として使用します。これらの要素はサブ構造体を表します。

5. 3 つの Gain ブロックから信号を受け取る Bus Creator ブロックのダイアログ ボックスで、次を行います。

  • [出力データ型]Bus: B_struct_type に設定します。

  • [非バーチャル バスとして出力] を選択します。

  • [OK] をクリックします。

6. 他の下位の Bus Creator ブロックのダイアログ ボックスで、次を行います。

  • [出力データ型]Bus: C_struct_type に設定します。

  • [非バーチャル バスとして出力] を選択します。

  • [OK] をクリックします。

7. 最後の [Bus Creator ブロック] ダイアログ ボックスで、次を行います。

  • [出力データ型]Bus: A_struct_type に設定します。

  • [非バーチャル バスとして出力] を選択します。

  • [OK] をクリックします。

8. Simulink Coder アプリを開きます。[C コード] タブで、[コード インターフェイス][個々の要素コードのマッピング] を選択します。

9. [信号/状態] タブを開きます。モデルで、Unit Delay ブロックに接続する A_struct_type Bus Creator ブロックの出力信号を選択します。コード マッピング エディターで、[選択した信号をコード マッピングに追加] ボタンをクリックします。

10. 追加された信号について [ストレージ クラス]ExportedGlobal に設定します。

11.プロパティ インスペクターで [コード][Identifier] プロパティを sig_struct_var に設定します。Bus Creator ブロックの出力は生成されたコードに sig_struct_var という名前の個別のグローバル構造体変数として表示されます。

12.モデルからコードを生成します。

結果

生成されたヘッダー ファイル ex_signal_nested_struct_types.h は構造体型を定義します。各構造体型は Simulink.Bus オブジェクトに対応します。

typedef struct {
  real_T signal1;
  real_T signal2;
  real_T signal3;
} B_struct_type;

typedef struct {
  real_T signal1;
  real_T signal2;
} C_struct_type;

typedef struct {
  B_struct_type subStruct_B;
  C_struct_type subStruct_C;
} A_struct_type;

生成されたソース ファイル ex_signal_nested_struct.c はグローバル構造体変数 sig_struct_var にメモリを割り当てます。既定では、A_struct_type Bus Creator ブロックの名前は Bus Creator2 です。

/* Exported block signals */
A_struct_type sig_struct_var;          /* '<Root>/Bus Creator2' */

同じファイル内のモデルの関数 step で、アルゴリズムは sig_struct_varsig_struct_var のフィールドにアクセスします。

制限を回避する手法の組み合わせ

各手法の制限を回避するために、構造体化されたストレージ クラスを非バーチャル バスおよびパラメーター構造体と組み合わせることができます。たとえば、次のようなことができます。

  • 信号データの構造体とパラメーター データの構造体を同じ親構造体に含める。

  • 既定の設定で新しいデータの集約し、さらに構造体を入れ子にする。

生成されたコードでは、構造体化されたストレージ クラスに対応するフラットな親構造体に、各バスとパラメーター構造体に対応するサブ構造体が含まれています。次のいずれかの手法の組み合わせを選択します。

  • 構造体化されたストレージ クラスを各バスとパラメーター構造体に直接適用します。たとえば、2 つの非バーチャル バス信号のストレージ クラスを Struct に設定します。各バスは生成されたコードで単一の構造体のフィールド (サブ構造体) として表示されます。

  • 各バスとパラメーター構造体のストレージ クラスを既定の設定 [Auto] または [Model default] のままにし、コード生成最適化によってバスまたはパラメーター構造体が削除されないようにします。次に、信号データとパラメーター データが構造体化されたストレージ クラスを既定で使用するように、既定のストレージ クラスを設定します。

構造体の配列

複数の一貫性のあるバス信号またはパラメーター構造体を配列にさらにパッケージ化できます。バス配列またはパラメーター構造体は構造体の配列として生成されたコードに表示されます。バス配列を作成するには、非バーチャル バスのバス配列へのグループ化を参照してください。パラメーター構造体の配列を作成する場合は、複数のパラメーター構造体を配列にグループ化を参照してください。

構造体のパディング

既定では、コード ジェネレーターは構造体型にパディング フィールドを明示的に追加することはありません。構造体型は、たとえば、標準のデータ構造体 (生成されたコードにおけるデータ構造体を参照)、Simulink.Bus オブジェクトおよびモデルで使用するパラメーター構造体を介して生成されたコードに表示されることがあります。

ただし、Embedded Coder でコード置換ライブラリを使用する場合、データ配置 (構造体のパディングを含む) を置換ライブラリの一部として指定できます。詳細については、Provide Data Alignment Specifications for Compilers (Embedded Coder)を参照してください。

制限

  • 組み込みの Simulink® Coder™ 機能と Embedded Coder 機能では、値がポインターのフィールドが含まれるカスタム構造体を生成または使用することはできません。これは、高度なストレージ クラスを作成し、付随する TLC コードを書き込むことによって手動で行うことができます (ストレージ クラスの TLC コードの記述によるデータ表現の詳細な制御 (Embedded Coder)を参照)。

  • 組み込みストレージ クラス Struct またはカスタム ストレージ クラス デザイナーで作成する構造体化されたストレージ クラスを使用して (ストレージ クラス プロパティ [種類][FlatStructure] に設定)、コード マッピング エディターでデータの既定を設定することはできません。

参考

関連するトピック