共有ユーティリティ コードの生成
共有ユーティリティ コードを生成する場合
モデルのブロックには、アルゴリズムを実装するための共通の機能が必要になることがあります。この機能をスタンドアロンのサポート関数または補助関数にモジュール化することを検討します。この方法は、各ブロック インスタンスにこの機能のコードをインライン化するよりも効率的な場合があります。ライブラリと共有ユーティリティのどちらを使用するか決定するには、以下の点を考慮してください。
関数が静的に定義される場合、複数の呼び出し元をもつ可能性のある関数をライブラリにパッケージングする。コード ジェネレーターを使用してモデルのコードを生成する前からこの関数のソース コードはファイルに存在します。
関数を静的に定義できない場合、複数の呼び出し元をもつ可能性のある関数を共有ユーティリティとしてパッケージングする (コード生成の最中に生成されます)。たとえば、複数のモデル固有およびブロック固有のプロパティによって、使用される関数とその動作を指定します。また、これらのプロパティが共有ユーティリティ ヘッダー ファイルの型定義 (
typedefなど) を決定します。一意の動作を決定するプロパティの可能な組み合わせの数が多い場合、使われる可能性のある関数のファイルをコード生成の前に静的に定義することは現実的でなくなります。
生成された関数の命名の構成
生成された共有ユーティリティ関数の既定の命名規則を次のいずれかの方法で構成します。
| 構成 | アクション |
|---|---|
| コード マッピング エディター – C またはコード マッピング プログラミング インターフェイスを使用して既定のカスタマイズ設定をマッピングした新しいモデルまたは既存のモデル | Embedded Coder ディクショナリで、カスタムの関数命名規則を指定する関数カスタマイズ テンプレートを定義します。次に、コード マッピング エディターで、またはコード マッピング プログラミング インターフェイスを使用して、[共有ユーティリティ] 関数カテゴリをそのテンプレートにマッピングします。詳細については、Configure Default C Code Generation for Categories of Data Elements and Functionsを参照してください。 |
| R2018a より前のリリースで作成され、コード マッピング エディター – C またはコード マッピング プログラミング インターフェイスで構成されていないモデル | モデル コンフィギュレーション パラメーター [共有ユーティリティ識別子の形式] (CustomSymbolsStrUtil) をカスタムの関数命名規則に設定します。詳細については、Identifier Format Controlを参照してください。 |
コード マッピング エディター – C またはコード マッピング プログラミング インターフェイスを使用してモデルを設定すると、モデル コンフィギュレーション パラメーター [共有ユーティリティ識別子の形式] を設定してもコード生成に影響しません。この設定は、次の指定で構成されたモデルには適用できません。
| システム ターゲット ファイル | プログラミング言語 |
|---|---|
ert.tlc | C++ |
autosar.tlc | C |
autosar_adaptive.tlc | C++ |
共有ユーティリティ関数の命名規則には、条件付きチェックサム トークン $C を含めなければなりません。コード ジェネレーターで生成されるチェックサムの長さをカスタマイズするには、パラメーター [共有チェックサム長] (SharedChecksumLength) を使用します。チェックサムの長さを増やすと、競合の可能性が軽減します。
この例では、C コード生成のための共有ユーティリティ関数名のカスタマイズを示します。
モデル例
ConfigurationInterfaceを開きます。openExample('ConfigurationInterface')Embedded Coder アプリを開きます。
モデル コンフィギュレーション パラメーター [共有コードの配置] を [
Shared location] に設定します。Embedded Coder ディクショナリを開きます。[C コード] タブで [コード インターフェイス] 、 [Embedded Coder ディクショナリ] を選択します。
[関数カスタマイズ テンプレート] を選択し、[作成] をクリックして新規の関数カスタマイズ テンプレートを追加します。
関数カスタマイズ テンプレートについて、次の構成を指定します。
名前:
[exSharedUtility]関数の命名規則:
mymodel_$N$Cstring を使用してこの形式をカスタマイズできます。トークン
$Cを含めなければなりません。
コード マッピング エディターを開きます。[C コード] タブで、[コード インターフェイス] 、 [既定のコード マッピング] を選択します。
[関数の既定の設定] タブで、[共有ユーティリティ] カテゴリについて、[関数カスタマイズ テンプレート] を
[exSharedUtility]として設定します。コードとコード生成レポートを生成します。
レポートの左のナビゲーション ペインで、[共有ファイル] の共有ユーティリティに対して生成されたファイルのリストを確認します。
共有ユーティリティ コードの配置の制御
モデル コンフィギュレーション パラメーター [共有コードの配置] で共有ユーティリティ コードの配置を制御します。オプションの既定値は [自動] です。この設定では、モデルに既存の共有ユーティリティ コードまたは次のブロックのいずれも含まれていない場合、コード ジェネレーターは固定小数点などのユーティリティに必要なコードを ファイル、model.c ファイル、またはビルド フォルダー内の個別のファイル (model.cppvdp_grt_rtw など) に配置します。
Model ブロック
Simulink Function ブロック
Function Caller ブロック
Stateflow または MATLAB Function ブロックからの Simulink Function の呼び出し
パラメーター [チャート レベルの関数をエクスポート] を選択した場合の Stateflow グラフィカル関数
モデルにこれらのブロックが 1 つ以上含まれている場合、コード ジェネレーターは、slprj 内に共有ユーティリティ フォルダーを作成して使用します。共有ユーティリティ フォルダーの命名規則は、slprj/target/_sharedutils です。target は、Model ブロックを使用するシミュレーションでは sim になり、コード生成ではシステム ターゲット ファイルの名前になります。
slprj/sim/_sharedutils % folder used with simulation slprj/grt/_sharedutils % folder used with grt.tlc STF slprj/ert/_sharedutils % folder used with ert.tlc STF slprj/mytarget/_sharedutils % folder used with mytarget.tlc STF
現在のモデルに既存の共有ユーティリティ コードまたは上記のブロックのいずれも含まれていない場合でも、共有ユーティリティ生成用の slprj フォルダーを使用してモデルをビルドするように強制するには、パラメーター [共有コードの配置] を [共有場所] に設定します。コード ジェネレーターは、通常のビルド フォルダーではなく、slprj フォルダーにユーティリティを配置します。この設定は、モデル間での記号の競合を回避するので、複数のモデルから手動でコードを結合する場合に便利です。
共有ユーティリティ コード用の rtwtypes.h の配置の制御
コンフィギュレーション パラメーター [データ型置換] が [Coder の typedef を使用] に設定されている場合、生成されたヘッダー ファイル #define は、基本的な型定義、rtwtypes.h ステートメントおよび列挙を提供します。詳細については、rtwtypes.hを参照してください。
ビルド プロセスが共有ユーティリティ フォルダーを使用するかどうかを選択することによって rtwtypes.h ファイルの配置を制御します。モデル ビルドが共有ユーティリティ フォルダーを使用する場合、ビルド プロセスで rtwtypes.h は slprj/ に配置されます。それ以外の場合は、ソフトウェアが target/_sharedutilsrtwtypes.h を に配置します。model_target_rtw
モデルをモデル階層に追加するか、階層内の既存のモデルを変更すると、コードの生成時に共有 rtwtypes.h ファイルが更新されることがあります。更新が行われた場合は再コンパイルを行い、開発プロセスによっては、以前に生成されたコードを再確認します。ファイル rtwtypes.h への更新を最小限にするために、次のモデル コンフィギュレーション パラメーターの変更を行います。
モデルで複素数データ型を現在使用していない場合でもモデル コンフィギュレーション パラメーター [サポート: 複素数] を選択します。このパラメーターを選択しておくと、将来、コード統合に際して複素数データ型のサポートを追加する要件が生じた場合の対応策となります。
パラメーター [インラインでない S-Function のサポート] をオフにします。インラインでない S-Function がモデルで使用されている場合は、このオプションによりエラーが発生します。
エクスポート データの重複するヘッダー ファイルの回避
次の場合にエクスポートされたヘッダー ファイルが共有ユーティリティ フォルダーに置かれます。
信号、パラメーターおよび状態の宣言のファイル配置を、ストレージ クラスを定義および適用することによって制御する。
コード ジェネレーターがユーティリティ コードを共有場所に配置する。
たとえば、以下を使用してデータのヘッダー ファイルを指定できます。
Embedded Coder ディクショナリで定義し、コード マッピング エディター – C でモデル データのカテゴリにマッピングしたストレージ クラス。
[信号プロパティ] ダイアログ ボックスの [コード生成] タブ。
データ オブジェクトの
HeaderFileプロパティ。データ オブジェクトはクラスSimulink.SignalおよびSimulink.Parameterのオブジェクトです。
宣言がファイル に現れるようにするには、ヘッダー ファイルの名前を指定せずにおくのがベスト プラクティスです。既定では、コード ジェネレーターはデータ宣言を model.h に配置します。model.h
ヘッダー ファイル名として を指定し、コード ジェネレーターがユーティリティ コードを共有場所に配置する場合は、モデルからコードを生成することはできません。コード ジェネレーターはファイル model.h を、モデルのビルド フォルダーと共有ユーティリティ フォルダーの両方に作成することはできません。model.h
インクリメンタル ビルドによる共有ユーティリティ コードの生成の削減
モデルのビルドによって共有ユーティリティ フォルダー内の C ソース ファイルを生成するように指定できます。共有ユーティリティ コードの配置の制御を参照してください。これらのファイルには関数定義とヘッダー ファイル (マクロ定義を含む) を含む C ソース ファイルが含まれています。この節の説明では、「関数」という言葉は、関数とマクロを意味します。
モデル参照を使用する場合、または同じ開始ビルド フォルダーから複数のスタンドアロンのモデルを作成する場合、同じモデル内のブロックおよび異なるモデル内のブロックは共有関数を使用できます。コード ジェネレーターは、最初にコード生成がトリガーされたブロックに対して一度だけ指定の関数のコードを生成します。この製品は、後のブロックの関数コードを生成する必要があるかどうかを決定するときに、ファイル存在チェックを実行します。ファイルが存在する場合、モデル ビルドによって関数は再生成されません。共有ユーティリティ コードのメカニズムでは、どのブロックまたはモデルで関数が生成されるのかにかかわらず、指定された関数とファイル名は同じ機能動作を表す必要があります。この要件を満たすには、以下が必要です。
関数の動作を決定するモデルのプロパティが、共有ユーティリティのチェックサムに寄与するか、または関数名とファイル名を決定します。
関数の動作を決定するブロック プロパティは、関数とファイル名も決定します。
コンパイル中、共有ユーティリティ フォルダーの makefile 規則によって、新しい C ファイルのみをコンパイルするように選択され、オブジェクト ファイルが共有ユーティリティ ライブラリ、rtwshared.lib または rtwshared.a に段階的にアーカイブされます。インクリメンタル コンパイルも実行されます。
共有ユーティリティ コード チェックサムの管理
モデル コンフィギュレーション パラメーター [共有コードの配置] を [共有場所] に設定する場合、またはモデルに Model ブロックが含まれる場合、コード ジェネレーターは共有コードを共有ユーティリティ フォルダーに配置します。ビルド プロセスによって、共有コードに対するコード生成構成の共有ユーティリティ チェックサムが生成されます。
以降のコード生成の最中に、現在のフォルダーに関連するチェックサム ファイル slprj/ が存在する場合、コード ジェネレーターはそのファイルを読み取ります。コード ジェネレーターは、ビルドしている現在のモデルに、共有ユーティリティ モデルのプロパティのチェックサムと一致するコンフィギュレーション プロパティがあるかどうかを検証します。target/_sharedutils/checksummap.matchecksummap.mat で定義されているプロパティと現在のモデル プロパティの間で不一致が発生した場合は、エラーが表示されます。エラー メッセージを使用してチェックサムを管理します (現在のモデルの構成の問題を診断して解決するなど)。
共有ユーティリティのチェックサム ハッシュ テーブルの表示
チェックサムに寄与するプロパティ値を表示すると便利です。この例では、LctStartTermActions モデルを使用します。checksum.mat ファイルを MATLAB® に読み込み、チェックサム関連のプロパティを定義する targetInfoStruct を表示するには、次を行います。
LctStartTermActionsモデルを開きます。コマンド ウィンドウで以下のように入力します。openExample('LctStartTermActions')モデルを作成します。モデルは共有ユーティリティを生成するように設定されます。
[アプリ] タブの [コード生成] の下で、[Simulink Coder] をクリックします。
[C コード] タブの [コードの生成] セクションで、[ビルド] ボタンをクリックします。
ビルド プロセスによって作成された
_sharedutilsフォルダーに移動します。cd slprj\grt\_sharedutilschecksummap.matファイルを MATLAB に読み込みます。load checksummaphashTbl.targetInfoStructの内容を表示し、チェックサム関連のプロパティ値を調べます。hashTbl.targetInfoStruct
以下の例では、コマンド ウィンドウに、モデルから生成された共有ユーティリティの hashTbl.targetInfoStruct が表示されます。
ans =
struct with fields:
ShiftRightIntArith: 'on'
ProdShiftRightIntArith: 'on'
Endianess: 'LittleEndian'
ProdEndianess: 'LittleEndian'
wordlengths: '8,16,32,32,64,32,64,64,64,64'
Prodwordlengths: '8,16,32,32,64,32,64,64,64,64'
TargetWordSize: '64'
ProdWordSize: '64'
TargetHWDeviceType: 'Custom Processor->Custom Processor'
ProdHWDeviceType: 'Custom Processor->Custom Processor'
TargetIntDivRoundTo: 'Zero'
ProdIntDivRoundTo: 'Zero'
UseDivisionForNetSlopeComputation: 'on'
PurelyIntegerCode: 'off'
PortableWordSizes: 'off'
SupportNonInlinedSFcns: ''
RTWReplacementTypes: ''
MaxIdInt8: 'MAX_int8_T'
MinIdInt8: 'MIN_int8_T'
MaxIdUint8: 'MAX_uint8_T'
MaxIdInt16: 'MAX_int16_T'
MinIdInt16: 'MIN_int16_T'
MaxIdUint16: 'MAX_uint16_T'
MaxIdInt32: 'MAX_int32_T'
MinIdInt32: 'MIN_int32_T'
MaxIdUint32: 'MAX_uint32_T'
MaxIdInt64: 'MAX_int64_T'
MinIdInt64: 'MIN_int64_T'
MaxIdUint64: 'MAX_uint64_T'
BooleanTrueId: 'true'
BooleanFalseId: 'false'
TypeLimitIdReplacementHeaderFile: ''
SharedCodeRepository: ''
TargetLang: 'C'
TargetLangStd: 'C89/C90 (ANSI)'
InstructionSetExtions: 'None'
PreserveExternInFcnDecls: 'on'
ImplementImageWithCVMat: 'off'
EnableSignedRightShifts: 'on'
EnableSignedLeftShifts: 'on'
TflName: 'None'
TflCheckSum: [616363766 197828711 1.4161e+09 4.1794e+09]
UtilMemSecPreStatement: ''
UtilMemSecPostStatement: ''
UtilMemSecComment: ''
CodeCoverageChecksum: [3.6498e+09 78774415 2.5508e+09 2.1183e+09]
TargetLargestAtomicInteger: 'Char'
TargetLargestAtomicFloat: 'None'
ProdLargestAtomicInteger: 'Char'
ProdLargestAtomicFloat: 'None'
LongLongMode: 'on'
ProdLongLongMode: 'on'
DataTypeReplacement: 'CoderTypedefs'
ExistingSharedCodeUsingClassicNonFinite: 0
HeaderGuardPrefix: ''
HardwareBoard: 'None'
toolchainOrTMF: 'Microsoft Visual C++ 2022 v17.0 | nmake (64-bit Windows)'
共有ユーティリティのチェックサムのコンフィギュレーション パラメーターへの関連付け
共有ユーティリティ モデルからの targetInfoStruct ハッシュ テーブルを調べます。一部のキーと値のペアはモデル プロパティに直接関連しています。その他のペアはプロパティのグループに関連しています。
以下の表にキーと値のペアを示します。
| キーの名前 | モデル プロパティ |
|---|---|
ShiftRightIntArith | TargetShiftRightIntArith |
ProdShiftRightIntArith | ProdShiftRightIntArith |
Endianess | TargetEndianess |
ProdEndianess | ProdEndianess |
wordlengths | TargetBitPerChar, TargetBitPerShort, TargetBitPerInt, TargetBitPerLong, TargetBitPerLongLong, TargetBitPerFloat, TargetBitPerDouble,TargetWordSize, TargetBitPerPointer, TargetBitPerSizeT, TargetBitPerPtrDiffT |
Prodwordlengths | ProdBitPerChar, ProdBitPerShort, ProdBitPerInt, ProdBitPerLong, ProdBitPerLongLong, ProdBitPerFloat, ProdBitPerDouble,ProdWordSize, ProdBitPerPointer, ProdBitPerSizeT, ProdBitPerPtrDiffT |
TargetWordSize | TargetWordSize |
ProdWordSize | ProdWordSize |
TargetHWDeviceType | TargetHWDeviceType |
ProdHWDeviceType | ProdHWDeviceType |
TargetIntDivRoundTo | TargetIntDivRoundTo |
ProdIntDivRoundTo | ProdIntDivRoundTo |
UseDivisionForNetSlopeComputation | UseDivisionForNetSlopeComputation |
PurelyIntegerCode | PurelyIntegerCode |
PortableWordSizes | PortableWordSizes |
SupportNonInlinedSFcns | SupportNonInlinedSFcns |
RTWReplacementTypes | EnableUserReplacementTypes, ReplacementTypes |
MaxIdInt8 | MaxIdInt8 |
MinIdInt8 | MinIdInt8 |
MaxIdUint8 | MaxIdUint8 |
MaxIdInt16 | MaxIdInt16 |
MinIdInt16 | MinIdInt16 |
MaxIdUint16 | MaxIdUint16 |
MaxIdInt32 | MaxIdInt32 |
MinIdInt32 | MinIdInt32 |
MaxIdUint32 | MaxIdUint32 |
MaxIdInt64 | MaxIdInt64 |
MinIdInt64 | MinIdInt64 |
MaxIdUint64 | MaxIdUint64 |
BooleanTrueId | BooleanTrueId |
BooleanFalseId | BooleanFalseId |
TypeLimitIdReplacementHeaderFile | TypeLimitIdReplacementHeaderFile |
SharedCodeRepository | 予約済み (内部使用専用) |
TargetLang | TargetLang |
TargetLangStd | TargetLangStandard |
InstructionSetExtions | InstructionSetExtensions |
PreserveExternInFcnDecls | PreserveExternInFcnDecls |
ImplementImageWithCVMat | ImplementImageWithCVMat |
EnableSignedRightShifts | EnableSignedRightShifts |
EnableSignedLeftShifts | EnableSignedLeftShifts |
TflName | CodeReplacementLibrary |
TflCheckSum | 予約済み (内部使用専用) |
UtilMemSecPreStatement | MemSecFuncSharedUtil, MemSecPackage |
UtilMemSecPostStatement | MemSecFuncSharedUtil, MemSecPackage |
UtilMemSecComment | MemSecFuncSharedUtil, MemSecPackage |
CodeCoverageChecksum | 予約済み (内部使用専用) |
TargetLargestAtomicInteger | TargetLargestAtomicInteger |
TargetLargestAtomicFloat | TargetLargestAtomicFloat |
ProdLargestAtomicInteger | ProdLargestAtomicInteger |
ProdLargestAtomicFloat | ProdLargestAtomicFloat |
LongLongMode | TargetLongLongMode |
ProdLongLongMode | ProdLongLongMode |
DataTypeReplacement | DataTypeReplacement |
ExistingSharedCodeUsingClassicNonFinite | 予約済み (内部使用専用) |
HeaderGuardPrefix | HeaderGuardPrefix |
HardwareBoard | HardwareBoard |
toolchainOrTMF | 次の名前です。
|
MATLAB 関数の共有ユーティリティ コードの生成
コード ジェネレーターは、MATLAB Function ブロックまたは Stateflow® ブロック内で定義した main 関数またはサブ関数の共有ユーティリティ コードを生成しません。
別のファイルで定義した MATLAB 関数をブロックで使用した場合、既定では、コード ジェネレーターはその関数の共有ユーティリティ コードを生成します。ただし、その関数が次の条件のいずれかを満たしている場合、コード ジェネレーターは関数を非共有としてマークし、共有ユーティリティ コードを生成しません。
persistentまたはglobal変数を使用する。Simulink® 関数を呼び出す。
関数呼び出し出力をもつブロックで使用されている。
Stateflow Chart (Stateflow) の入力、出力、またはローカル変数を参照する。
DataScopeプロパティが'Auto'に設定されていて、HeaderFileプロパティが空であるバスまたは列挙を使用する。可変サイズのデータを使用する。
coder.cevalを使用してカスタム C/C++ 関数を呼び出す。ここに挙げたいずれかの理由のためにコード ジェネレーターが既に非共有としてマークした別の MATLAB 関数を呼び出す。このルールは間接的に適用されます。たとえば、
foo1がfoo2を呼び出し、後者がfoo3を呼び出すとします。関数foo3のみがglobalまたはpersistent変数を使用する場合でも、コード ジェネレーターは 3 つの関数すべてを非共有としてマークします。