最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

生成されたコードへの外部 C/C++ コードの配置

Custom Code ブロックまたはモデル コンフィギュレーション パラメーターで外部コードを指定して、コード ジェネレーターがモデルに対して生成したコードをカスタマイズできます。

  • ルート モデル用に生成されたコードの開始および終了部分にコードを配置します。

  • ルート モデルまたは非バーチャル サブシステムのブロックに対して生成された関数コードに宣言、本体、および終了コードおよび終了コードを配置します。

外部コードで拡張可能な関数は、コード ジェネレーターがモデル内のブロックに対して生成する関数によって異なります。たとえば、モデルまたは Atomic Subsystem に状態をもつブロックが含まれている場合、関数 disable のコードを指定できます。同様に、ブロックでデータの保存、メモリの解放、ターゲット ハードウェアのリセットを実行するためのコードが必要な場合は、関数 terminate のコードを指定します。詳細については、Block Target File Methodsを参照してください。

ワークフロー

コード ジェネレーターがルート モデルとサブシステムに対して生成するコード内の特定の場所に外部 C または C++ コードを配置するには、次の表に示すタスクを反復します。

タスクアクション詳細
1外部 C コードを生成した C++ コードに統合するまたはその逆を行うには、生成コード用に選択した言語に合わせて外部コードの言語を変更します。生成コードに合わせるための外部コードのプログラミング言語の変更
2外部コードの特性と統合要件の評価を確認します。Choose an External Code Integration Workflow (Embedded Coder)
3必要に応じて、コードを C または C++ で書き換えます。 
4外部コードを Simulink モデルに追加する統合方法を選択します。Choose an Integration Approach (Embedded Coder)
5コード生成用のモデル データの表示を定義します。Exchange Data Between External C/C++ Code and Simulink Model or Generated Code (Embedded Coder)
6コードを生成するためにモデルを設定します。Generate Code That Matches Appearance of External Code (Embedded Coder)とモデル コンフィギュレーション (Embedded Coder)
7コードとコード生成レポートを生成します。コード生成 (Embedded Coder)
8生成コード インターフェイスと静的コード メトリクスを確認します。Analyze the Generated Code Interface (Embedded Coder)とStatic Code Metrics (Embedded Coder)
9モデルから実行可能なプログラムをビルドします。Build Integrated Code Within the Simulink Environment (Embedded Coder)
10実行可能なプログラムが予測どおり実行されるか確認します。数値的等価性のテスト (Embedded Coder)とコード実行のプロファイル (Embedded Coder)

統合方法の選択

Simulink® モデリング環境内では、2 つの方法を使用して、外部 C または C++ コードを、コード ジェネレーターが生成するコードのセクションに配置できます。

  • カスタム コード ライブラリからルート モデルまたは Atomic Subsystem にブロックを追加します。

  • [コード生成][カスタム コード] ペインでモデル コンフィギュレーション パラメーターを設定します。

以下の表で、2 つの方法を比較します。統合要件に最適な方法を選択してください。各アプローチの適用方法の詳細については、Integrate External Code by Using Custom Code Blocks (Embedded Coder)およびIntegrate External Code by Using Model Configuration Parameters (Embedded Coder)を参照してください。

要件ブロックモデル コンフィギュレーション パラメーター
モデリング キャンバスに外部コードの表現を含める 
ルート モデル用に生成された関数にコードを配置する
Atomic Subsystem 用に生成された関数にコードを配置する 
モデル コンフィギュレーション セットにコード配置を保存する 
モデル用に生成されたヘッダー ファイルとソース ファイルの上部と下部にコードを配置する
コード ジェネレーターが作成した関数 SystemInitialize および SystemTerminate の宣言、実行および終了セクション内にコードを配置する
コード ジェネレーターが生成した関数 SystemStartSystemEnableSystemDisableSystemOutputsSystemUpdateSystemDerivatives の宣言、実行および終了セクション内にコードを配置する 
生成コードにプリプロセッサ マクロ定義を追加する 
シミュレーション ターゲットに対して指定されているカスタム コード設定を使用する 
ライブラリがリンクしている親モデルの一意のカスタム コード設定を使用するようライブラリ モデルを構成する 

Custom Code ブロックを使用した外部コードの統合

Custom Code ブロック ライブラリ

Custom Code ブロック ライブラリには、外部 C または C++ コードを、コード ジェネレーターが生成したコード内の特定の場所および関数に配置するために使用できるブロックが含まれています。このライブラリは、コード ジェネレーターが生成するモデル ヘッダー (model.h) およびソース (model.c または model.cpp) ファイルにコードを追加する 10 のブロックで構成されています。

Model Header ブロックと Model Source ブロックは、コード ジェネレーターがルート モデルに対して生成するヘッダーおよびソース ファイルの上部と下部に外部コードを追加します。これらのブロックには、コードを入力または貼り付けることができる 2 つのテキスト フィールドが表示されます。1 つ目のフィールドでは、生成されたヘッダーまたはソース ファイルの上部に配置するコードを指定します。2 つ目のフィールドでは、ファイルの下部に配置するコードを指定します。

残りのブロックでは、コード ジェネレーターがブロックを含むルート モデルまたは Atomic Subsystem に対して生成する関数に外部コードを追加します。これらのブロックには、コード ジェネレーターが生成する関数をカスタマイズするコードを入力または貼り付けることができるテキスト フィールドが表示されます。テキスト フィールドは、特定の関数のコードの宣言、実行、および終了セクションに対応しています。

カスタマイズするコードの内容使用目的
連続状態の計算System Derivatives
状態の無効化 System Disable
状態の有効化System Enable
状態のリセットSystem Initialize
出力の生成System Outputs
1 回実行System Start
データの保存、メモリの解放、ターゲット ハードウェアのリセットSystem Terminate
各メジャー タイム ステップで更新が必要System Update

ブロックとモデル内でのその場所によって、コード ジェネレーターが外部コードを配置する場所が決まります。たとえば、System Outputs ブロックがルート モデル レベルにある場合、コード ジェネレーターはモデルの関数 Outputs にコードを配置します。ブロックが Triggered Subsystem または Enabled Subsystem 内にある場合、コードはそのサブシステムの関数 Outputs 内に置かれます。

コード ジェネレーターで、モデルに含める Custom Code ブロックに対応する関数を生成する必要がない場合、コード ジェネレーターは次のいずれかを実行します。

  • Custom Code ブロックで指定した外部コードを省略する。

  • モデルに関連ブロックが含まれていないことを示すエラーを返す。この場合、モデルから Custom Code ブロックを削除します。

詳細については、Block Target File Methodsを参照してください。

メモ

シミュレーションとコード生成の結果の間の不一致の可能性を回避するには、グローバル Simulink データ (信号、状態およびブロック パラメーター) の読み取りと書き込みにカスタム コード ブロックを使用しないでください。代わりに、適切なモデル化パターン (たとえば、Data Store ReadData Store WriteState Reader および State Writer ブロック) を使用します。

モデリング キャンバスへの Custom Code ブロックの追加

Custom Code ライブラリ ブロックをモデルに追加するには、次を行います。

  1. Simulink ライブラリ ブラウザーで、Custom Code ブロック ライブラリを開きます。

  2. 必要なブロックをモデルまたは Subsystem にドラッグします。Model Header ブロックと Model Source ブロックをルート モデルのみにドラッグします。関数ベースの Custom Code ブロックをルート モデルまたは Atomic Subsystem にドラッグします。

Custom Code ブロックを含むモデルを参照モデルとして使用できます。コード ジェネレーターは、シミュレーション ターゲットのコードを生成するときにこれらのブロックを無視します。コード生成ターゲットのコードを生成するときに、コード ジェネレーターにカスタム コードが含まれ、コンパイルされます。

生成された関数 Start への外部コードの追加

この例では、System Start ブロックを使用して、離散フィルターを含むモデルに対してコード ジェネレーターが生成するコードに外部 C コードを配置する方法を示します。

  1. 以下のモデルを作成します。

  2. コードを生成するためにモデルを設定します。

  3. System Start ブロックをダブルクリックします。

  4. [ブロック パラメーター] ダイアログ ボックスで、[System Start Function 宣言コード] フィールドに次のコードを入力します。

    unsigned int *ptr = 0xFFEE;
  5. [System Start Function 実行コード] フィールドに、次のコードを入力します。

    /* Initialize hardware */
    *ptr = 0;
  6. [OK] をクリックします。

  7. コードとコード生成レポートを生成します。

  8. 生成された model.c ファイルを表示します。文字列 start function を検索します。手順 4 と 5 で入力した外部コードを含む次のコードを見つけます。

      {
        {
          /* user code (Start function Header) */
          /* System '<Root>' */
          unsigned int *ptr = 0xFFEE;
      
          /* user code (Start function Body) */
          /* System '<Root>' */
          /* Initialize hardware */
          *ptr = 0;
        }
      }
    

他の例については、Integrate External C Code Into Generated Code By Using Custom Code Blocks and Model Configuration Parameters (Embedded Coder)を参照してください。

モデル コンフィギュレーション パラメーターを使用した外部コードの統合

モデル コンフィギュレーション パラメーターを使用して、外部 C または C++ コードを、コード ジェネレーターが生成したコード内の特定の場所および関数に配置できます。

目的選択
生成された model.c または model.cpp ファイルの最上部付近に外部コードを挿入します。

[ソース ファイル] を選択し、挿入する外部コードを入力します。

サブシステム コードを別のファイルに生成すると、そのコードは [ソース ファイル] パラメーターで指定した外部コードにアクセスできません。たとえば、インクルード ファイルを [ソース ファイル] 設定として指定すると、コード ジェネレーターでは model.c または model.cpp ファイルの最上部付近に #include が挿入されます。コード ジェネレーターが別のファイルに配置するサブシステム コードは、インクルード ファイル内の宣言にアクセスできません。この場合は、外部コードを [ヘッダー ファイル] パラメーターで指定することを検討してください。

生成された model.h ファイルの最上部付近に外部コードを挿入する[ヘッダー ファイル] を選択し、挿入する外部コードを入力します。
model.c または model.cpp ファイルでモデルの初期化関数内に外部コードを挿入する[初期化関数] を選択し、挿入する外部コードを入力します。
model.c または model.cpp ファイルでモデルの終了関数内に外部コードを挿入する[終了関数] を選択し、挿入する外部コードを入力します。また、[インターフェイス] ペインの [終了関数の生成] パラメーターも選択します。
プリプロセッサ マクロ定義の追加 [定義] を選択し、生成コードに追加するプリプロセッサ マクロ定義のリストをスペースで区切って入力します。リストには単純な定義 (-DEF1 など) と値をもつ定義 (-DDEF2=1 など) を含めることができます。定義では -D を省略できます (たとえば -DFOO=1FOO=1 は同じです)。定義に -D が含まれる場合、ツールチェーンは、定義に別のフラグを使用している場合、フラグをオーバーライドできます。
MATLAB Function ブロック、Stateflow® チャートおよび Truth Table ブロックのシミュレーションに指定された設定と同じカスタム コード パラメーター設定を使用する

[シミュレーション ターゲットと同じカスタム コードの設定を使用] を選択します。

このパラメーターは、[コンフィギュレーション パラメーター] ダイアログ ボックスの [シミュレーション ターゲット] ペインを参照します。

ライブラリがリンクしている親モデルから一意のカスタム コード設定をライブラリ モデルで使用できるようにする

ローカルなカスタム コード設定を使用 (メイン モデルから継承しません)

このパラメーターは、MATLAB Function ブロック、Stateflow チャートまたは Truth Table ブロックを含むライブラリ モデルに対してのみ使用可能です。

外部ヘッダー ファイルにヘッダー ファイルを含めるには、#ifndef コードを追加します。このコードを使用すると、複数回のインクルードを防止できます。たとえば、rtwtypes.h の場合には、次の #include の追加によって防止しています。

#ifndef RTW_HEADER_rtwtypes_h_ 
#define RTW_HEADER_rtwtypes_h_ 
... 
#endif /* RTW_HEADER_rtwtypes_h_ */

ヘッダー ファイル、ソース ファイルおよび共有ライブラリ ファイルのファイル名と場所をビルド プロセスに追加する方法の詳細については、Build Integrated Code Within the Simulink Environment (Embedded Coder)を参照してください。

メモ:

コード ジェネレーターは、ソフトウェアインザループ (SIL) およびプロセッサインザループ (PIL) シミュレーション用にコードを生成するときに、コンフィギュレーション セットに含める外部コードを含めます。ただし、コード ジェネレーターは、S-Function、ラピッド シミュレーションまたはシミュレーション システム ターゲット ファイルでコードを生成するときは、コンフィギュレーション セットに含める外部コードを無視します。

[カスタム コード] パラメーターの詳細については、モデル コンフィギュレーション パラメーター: コード生成のカスタム コードを参照してください。例については、Integrate External C Code Into Generated Code By Using Custom Code Blocks and Model Configuration Parameters (Embedded Coder)を参照してください。

カスタム コード ブロックとモデル コンフィギュレーション パラメーターを使用した外部 C コードの生成コードへの統合

この例では、カスタム コード ブロックとモデル コンフィギュレーション パラメーターを使用して生成コードに外部コードを配置する方法を示します。

1. モデル rtwdemo_slcustcode を開きます。

open_system('rtwdemo_slcustcode')

2. Simulink Coder アプリまたは Embedded Coder アプリを開きます。

3.[モデル コンフィギュレーション パラメーター] ダイアログ ボックスを開いて [カスタム コード] ペインに移動します。

4.モデル コンフィギュレーション パラメーター [ソース ファイル][初期化関数] の設定を確認します。

  • [ソース ファイル] にはコメントを指定し、変数 GLOBAL_INT2 を -1 に設定します。

  • [初期化関数] は変数 GLOBAL_INT2 を 1 に初期化します。

5.ダイアログ ボックスを閉じます。

6.Model Source ブロックをダブルクリックします。ブロック パラメーター [Model Source の最上位] では、コード ジェネレーターが変数 GLOBAL_INT1 を宣言して生成ファイル rtwdemo_slcustcode.c の先頭でその変数を 0 に設定することを指定します。

7.Triggered Subsystem Amplifier を開きます。サブシステムには System Outputs ブロックが含まれます。そのブロックで指定したコードを、コード ジェネレーターが、最も近い親 Atomic サブシステムの生成コード内に配置します。この場合、コードジェネレーターは Amplifier サブシステム用の生成コード内に外部コードを配置します。外部コードは次のようになります。

  • ポインター変数 *intPtr を宣言し、変数 GLOBAL_INT1 の値で初期化する。

  • 実行中はポインター変数を -1 に設定する。

  • 終了前にポインター変数を 0 にリセットする。

8.コードとコード生成レポートを生成します。

9. 生成されたソース ファイル rtwdemo_slcustcode.c のコードを調べます。ファイルの先頭、#include ステートメントの後に、次の宣言コードがあります。この例では、[ソース ファイル] コンフィギュレーション パラメーターによる最初の宣言と Model Source ブロックによる 2 番目の宣言が指定されています。

int_T GLOBAL_INT2 = -1;

int_T GLOBAL_INT1 = 0;

サブシステム Amplifier の出力関数には次のコードが含まれています。外部コードが、ゲインを適用する生成コードと統合されているのがわかります。この例では、サブシステム Amplifier 内に System Output ブロックによるポインター変数の 3 行のコードが指定されています。

int_T *intPtr = &GLOBAL_INT1;

*intPtr = -1;

rtwdemo_slcustcode_Y.Output = rtwdemo_slcustcode_U.Input << 1;

*intPtr = 0;

次の代入がモデルの初期化エントリポイント関数に表示されます。この例では、[初期化関数] コンフィギュレーション パラメーターによるこの代入が指定されています。

GLOBAL_INT2 = 1;

関連するトピック