生成されたコードにおける構造体へのデータの整理
C コードでは、構造体 (struct
) を使用してデータをメモリの連続した位置に格納します。信号や状態などのデータを意味のある名前を使用して整理できます。各構造体は名前空間として機能するため、複数のデータ項目を指定するために名前を再利用できます。配列と同様に、構造体を利用すれば、ポインターの使用によって効率的に大量のデータを転送、操作するコードを記述できます。
既定では、コード ジェネレーターはデータを標準の構造体に集約します (生成されたコードによる内部信号、状態、パラメーター データの保存方法を参照)。これらの構造体の特性を制御したり、異なる構造体を作成してこの既定の動作をオーバーライドしたりする場合は、次の表の情報を使用してください。
目的 | 手法 |
---|---|
標準のデータ構造体の特性を制御する。たとえば、構造体型の名前、構造体変数、フィールド名を指定します。 |
Embedded Coder®を使用する場合、Control Data Type Names in Generated Code(Embedded Coder)を参照してください。 |
たとえば、プラグマまたはその他のコード装飾を挿入して、メモリ内の構造体の配置を制御する。 |
Embedded Coder を使用する場合、Control Data and Function Placement in Memory by Inserting Pragmas(Embedded Coder)を参照してください。 |
名前および他の基本特性が制御可能な構造体にデータを集約する。ブロックおよび信号をモデルに追加すると、結果の新しいデータがこれらの構造体に既定で表示される。 |
Embedded Coder を使用する場合、コード マッピング エディターを使用して、構造化されたストレージ クラスをデータのカテゴリに適用します。
コード マッピング エディターの詳細については、Configure Default C Code Generation for Categories of Data Elements and Functions(Embedded Coder)を参照してください。独自のストレージ クラスを作成するには、Define Storage Classes, Memory Sections, and Function Templates for Software Architecture(Embedded Coder)を参照してください。 |
細かく制御できる特性をもつカスタム構造体に個々のデータ項目を整理して、生成されたコードの可読性を向上する。 |
必要な構造体型を表す
構造体の配列を作成するには、構造体の配列を参照してください。 |
生成されたコードと外部コード間で構造化されたデータを交換する (たとえば、外部コードで既にカスタム構造体型と対応するグローバル変数を定義している場合など)。 |
必要な構造体型を表す |
生成された関数の引数 (仮パラメーター) の数を減らす。 |
|
ルックアップ テーブル データを構造体に整理する。 |
Simulink.LookupTable オブジェクトとSimulink.Breakpoint オブジェクトを使用します。Simulink.LookupTable を参照してください。 |
ビット フィールドを生成する。 | Bitfields(Embedded Coder)およびOptimize Generated Code by Packing Boolean Data into Bitfields(Embedded Coder)を参照してください。 |
構造体を作成する手法
生成されたコードで構造体を作成するには、次の手法を使用します。
コード マッピング エディターを使用して、構造化されたストレージ クラスをデータのカテゴリに適用します。ブロックと信号をモデルに追加すると、既定の設定で新しいデータ要素がこのストレージ クラスを取得します。
モデル データ エディターを使用して、組み込みストレージ クラス
Struct
などの構造化されたストレージ クラスを個々のデータ項目に直接適用します。カスタム非バーチャル バスおよびパラメーター構造体を作成します。
使用する手法を決定するには、次の表の情報を使用してください。
機能 | 構造化されたストレージ クラスの既定の適用 | 構造化されたストレージ クラスの直接適用 | 非バーチャル バスとパラメーター構造体 |
---|---|---|---|
既定の設定で新しいデータ項目を構造体に集約 | あり |
なし | なし |
最適化でターゲット データの削除を回避 (生成されたコードにデータが表示されるように指定) | なし |
あり | ExportedGlobal などのストレージ クラスをバスまたは構造体に直接適用する場合のみ |
ブロック線図の外観を変更せずにデータを構造体に集約 | あり |
あり | なし |
信号、状態、パラメーター データを同じ構造体に配置 | なし | あり | なし |
構造体に状態のデータを含める | あり | あり | なし |
入れ子にされた構造体に構造体を整理 | なし | なし | あり |
構造体の配列に構造体を整理 | なし | なし | あり |
構造体型の名前を制御 | あり |
あり。ただし、型名は指定した変数名から派生する | あり |
生成された関数で引数の数を減らす構造体を作成 | あり。ただし、Embedded Coder ディクショナリを使用して独自のストレージ クラスを作成しなければならない |
なし | あり |
Embedded Coder が必要 | あり | あり | なし |
構造化されたストレージ クラスの既定の適用
既定のストレージ クラスをモデル データのカテゴリに適用できます。モデルにブロックおよび信号を適用すると、関連付けられたデータは指定する既定のストレージ クラスを取得します。既定の設定で新しいデータを構造体に集約するには、構造化されたストレージ クラスを適用します。クイック スタート ツールで作成したストレージ クラスの例ParamStruct
とSignalStruct
を使用するか、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. モデル例rtwdemo_paraminline
を開きます。
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.モデルからコードを生成します。
結果
生成されたヘッダー ファイルrtwdemo_paraminline_types.h
は、ランダムな名前の構造体型を定義します。
typedef struct { real_T G1; real_T G2; } struct_6h72eH5WFuEIyQr5YrdGuB;
ソース ファイルrtwdemo_paraminline.c
は、構造体変数myStruct
を定義および初期化します。
/* Exported block parameters */ struct_6h72eH5WFuEIyQr5YrdGuB myStruct = { 2.0, -2.0 } ; /* Variable: myStruct * Referenced by: * '/G1' * ' /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. バス エディター ツールストリップの、[追加]ギャラリーで、[バス]をクリックしてSimulink.Bus
オブジェクトを作成します。その後、名前をmy_signals_type
にします。my_signals_type
を選択した状態で、[追加]ギャラリーで、[バス要素]を 3 回クリックし、3 つの要素を追加します。名前をsignal1
、signal2
、およびsignal3
にします。詳細については、バス エディターを参照してください。
5. バス オブジェクトを現在のフォルダーにex_signal_struct_data.mat
として保存します。
このバス オブジェクトは、生成されたコードで使用する構造体型を表します。
6. Bus Creator ブロックのダイアログ ボックスで、[出力データ型]をBus: my_signals_type
に設定します。
7.[非バーチャル バスとして出力]を選択します。[OK]をクリックします。非バーチャル バスが生成されたコードに構造体として表示されます。
8.Simulink Coderアプリを開きます。[C コード]タブで、[コード インターフェイス]、[個々の要素コードのマッピング]を選択します。
9.[信号/状態]タブを開きます。モデルで Bus Creator ブロックの出力信号を選択し、コード マッピング エディターで[選択した信号をコード マッピングに追加]ボタンをクリックします。
11.追加された信号について[ストレージ クラス]をExportedGlobal
に設定します。
12.プロパティ インスペクターで[コード]、[Identifier]プロパティをsig_struct_var
に設定します。Bus Creator ブロックの出力は生成されたコードにsig_struct_var
という名前の個別のグローバル構造体変数として表示されます。
13.モデルからコードを生成します。
結果
生成されたヘッダー ファイル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; /* '/Bus Creator' */
同じファイル内のモデルの関数step
で、アルゴリズムはsig_struct_var
とsig_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 ブロックによって、生成されたコードで構造体がより識別しやすくなります。
2. 3 つの入力を受け入れるように Bus Creator ブロックを設定するには、ブロック ダイアロブ ボックスで[入力数]を3
に設定します。
3.ツールストリップの[モデル化]タブの[設計]で、[バス エディター]をクリックします。
バス エディター ツールストリップの、[追加]ギャラリーで、[バス]をクリックしてSimulink.Bus
オブジェクトを作成します。その後、名前をA_struct_type
にします。A_struct_type
を選択した状態で、[追加]ギャラリーで、[バス要素]を 2 回クリックし、2 つの要素を追加します。要素にsubStruct_B
およびsubStruct_C
という名前を付けます。詳細については、バス エディターを参照してください。このバス オブジェクトは、生成されたコードで使用する最上位構造体型を表します。
4. 同様に、Simulink.Bus
オブジェクトB_struct_type
(3 つの要素をもつ) およびC_struct_type
(2 つの要素をもつ) を作成します。
5.A_struct_type
オブジェクトで、subStruct_B
要素について、[データ型]をBus: B_struct_type
に設定します。同様に、subStruct_C
要素について、[データ型]をBus: C_struct_type
に設定します。
A_struct_type
の各要素は別のバス オブジェクトをデータ型として使用します。これらの要素はサブ構造体を表します。
6. 3 つの Gain 信号を収集する Bus Creator ブロックのダイアログ ボックスで、[出力データ型]をBus: B_struct_type
に設定します。[適用]をクリックします。
7.[非バーチャル バスとして出力]を選択し、[OK]をクリックします。
8. 他の下位の Bus Creator ブロック ダイアログ ボックスで、[出力データ型]をBus: C_struct_type
に設定し、[非バーチャル バスとして出力]を選択します。[OK]をクリックします。
9. 最後の Bus Creator ブロック ダイアログ ボックスで、[出力データ型]をBus: A_struct_type
に設定し、[非バーチャル バスとして出力]を選択します。[OK]をクリックします。
10.Simulink Coderアプリを開きます。[C コード]タブで、[コード インターフェイス]、[個々の要素コードのマッピング]を選択します。
11.[信号/状態]タブを開きます。モデルで、Unit Delay ブロックに接続するA_struct_type
Bus Creator ブロックの出力信号を選択します。コード マッピング エディターで、[選択した信号をコード マッピングに追加]ボタンをクリックします。
12.追加された信号について[ストレージ クラス]をExportedGlobal
に設定します。
13.プロパティ インスペクターで[コード]、[Identifier]プロパティをsig_struct_var
に設定します。Bus Creator ブロックの出力は生成されたコードにsig_struct_var
という名前の個別のグローバル構造体変数として表示されます。
14.モデルからコードを生成します。
結果
生成されたヘッダー ファイル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; /* '/Bus Creator2' */
同じファイル内のモデルの関数step
で、アルゴリズムはsig_struct_var
とsig_struct_var
のフィールドにアクセスします。
制限を回避する手法の組み合わせ
各手法の制限を回避するために、構造化されたストレージ クラスを非バーチャル バスおよびパラメーター構造体と組み合わせることができます。たとえば、次のようなことができます。
信号データの構造体とパラメーター データの構造体を同じ親構造体に含める。
既定の設定で新しいデータの集約し,さらに構造体を入れ子にする。
生成されたコードでは、構造化されたストレージ クラスに対応するフラットな親構造体に、各バスとパラメーター構造体に対応するサブ構造体が含まれています。次のいずれかの手法の組み合わせを選択します。
構造化されたストレージ クラスを各バスとパラメーター構造体に直接適用します。たとえば、2 つの非バーチャル バス信号のストレージ クラスを
Struct
に設定します。各バスは生成されたコードで単一の構造体のフィールド (サブ構造体) として表示されます。各バスとパラメーター構造体のストレージ クラスを既定の設定
[Auto]
または[Model default]
のままにし、コード生成最適化によってバスまたはパラメーター構造体が削除されないようにします。次に、信号データとパラメーター データが構造化されたストレージ クラスを既定で使用するように、既定のストレージ クラスを設定します。
構造体の配列
複数の一貫性のあるバス信号またはパラメーター構造体を配列にさらにパッケージ化できます。バス配列またはパラメーター構造体は構造体の配列として生成されたコードに表示されます。バス配列を作成するには、非バーチャル バスのバス配列へのグループ化を参照してください。パラメーター構造体の配列を作成する場合は、複数のパラメーター構造体を配列にグループ化を参照してください。
構造体のパディング
既定では、コード ジェネレーターは構造体型にパディング フィールドを明示的に追加することはありません。構造体型は、たとえば、標準のデータ構造体 (生成されたコードにおけるデータ構造体を参照)、Simulink.Bus
オブジェクトおよびモデルで使用するパラメーター構造体を介して生成されたコードに表示されることがあります。
ただし、Embedded Coder でコード置換ライブラリを使用する場合、データ配置 (構造体のパディングを含む) を置換ライブラリの一部として指定できます。詳細については、Provide Data Alignment Specifications for Compilers(Embedded Coder)を参照してください。
制限
組み込みの金宝app®Coder™機能と Embedded Coder 機能では、値がポインターのフィールドが含まれるカスタム構造体を生成または使用することはできません。これは、高度なストレージ クラスを作成し、付随する TLC コードを書き込むことによって手動で行うことができます (ストレージ クラスの TLC コードの記述によるデータ表現の詳細な制御(Embedded Coder)を参照)。
組み込みストレージ クラス
Struct
またはカスタム ストレージ クラス デザイナーで作成する構造化されたストレージ クラスを使用して (ストレージ クラス プロパティ[種類]を[FlatStructure]
に設定)、コード マッピング エディターでデータの既定を設定することはできません。
参考
関連するトピック
- 生成されたコードによる内部信号、状態、パラメーター データの保存方法
- 外部 C/C++ コードと Simulink モデルまたは生成コード間のデータ交換
- モデル インターフェイス要素の C コード生成の構成(Embedded Coder)
- Control Data and Function Placement in Memory by Inserting Pragmas(Embedded Coder)
- モデルの階層構造の異なるコンテキストに対応する柔軟なストレージ クラス(Embedded Coder)
- 合成信号のタイプ