Main Content

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

シミュレーションおよびコード生成のための再利用可能な外部アルゴリズム コードの呼び出し

コードの再利用は、ビジネスおよび技術面でメリットがあります。ビジネス面では、コードを再利用することで時間とリソースが節約されます。技術的な面では、一貫性が促進され、メモリ要件が軽減されます。その他の考慮事項は以下のとおりです。

  • アプリケーションのモジュール化

  • 最適化されたアルゴリズムの再利用

  • 事前定義されたデータセットとの連携

  • アプリケーション バリアントの開発

シミュレーションやコード生成のために Simulink® 環境へのインポートを検討する再利用可能なハードウェアに依存しないアルゴリズム コードの例は次のとおりです。

  • ユーティリティ関数

  • ルックアップ テーブル

  • デジタル フィルター

  • 特殊な積分器

  • 比例-積分-微分 (PID) 制御モジュール

ワークフロー

シミュレーションとコード生成のために再利用可能な外部アルゴリズム コードを呼び出すには、以下の表に記載されているタスクを反復します。

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

統合方法の選択

再利用可能なアルゴリズム コードをコード生成用の Simulink 環境に統合するための方法がいくつかあります。外部コードを直接統合する方法があります。外部コードをシミュレーション用の Simulink または Stateflow® モデリング要素に変換し、後でモデル化されたデザインからコード生成用に変換する方法もあります。どの統合方法を選択するかは、以下によって決まります。

  • 外部コードのプログラミング言語 — MATLAB®、C、C++ または Fortran

  • プログラミング言語の経験と嗜好

  • パフォーマンス要件

  • アルゴリズムが連続時間のダイナミクスをモデル化しなければならないか、または離散時間および連続時間を使用するアプリケーションにアルゴリズムを統合しているか

  • モデルベース デザインを活用するかどうか

  • コード ジェネレーターで生成されるコードに対して必要な制御のレベル

再利用可能なアルゴリズムのアプローチを選択するには、外部アルゴリズム コードのプログラミング言語と一致するサブセクションを参照してください。

外部 MATLAB コードの統合方法

外部 MATLAB コードを Simulink 環境に統合する方法は複数あります。次の図と表を参照すると、統合要件に基づいてアプリケーションに最適な統合方法を選択できます。

 条件または要件アクション詳細
1アルゴリズムで連続状態のダイナミクスをモデル化しなければならない。MATLAB S-Function と、コードを生成する場合は、アルゴリズムのための対応 TLC ファイルを作成します。S-Function をモデルに追加します。
2外部コードはコード生成サブセットの MATLAB コードに従い、MATLAB コードを Simulink モデルから呼び出す。MATLAB Function ブロックをモデルに追加します。MATLAB コードをそのブロックに組み込みます。
3外部コードはコード生成サブセットの MATLAB コードに従い、MATLAB コードを Simulink モデルから呼び出し、アルゴリズムには、大規模なデータ ストリームを処理する反復的な計算が含まれる。MATLAB System ブロックをモデルに追加します。MATLAB コードを System object™ としてそのブロックに組み込みます。
4外部コードはコード生成サブセットの MATLAB コードに従い、MATLAB コードを Simulink モデルから呼び出し、アルゴリズムにはステート マシンとフロー チャートに基づくデザイン ロジックが含まれる。Stateflow チャートをモデルに追加します。MATLAB をアクション言語として使用して、チャートから外部コードを呼び出します。
5関数 parfor を、並列計算または MATLAB Coder™Simulink Coder、および Embedded Coder® に使用できるインターフェイス データ型に使用する。parfor を使用するには、Parallel Computing Toolbox™ がインストールされていなければなりません。ソフトウェアを使用して C コードを生成します。次に、生成したコードを外部 C コードとして呼び出します。
6C または C++ によるプログラミングの経験があり、外部 MATLAB コードがコンパクトで、主に C または C++ 構造体を使用している。MATLAB コードを C または C++ コードに手動で変換します。C または C++ コードの統合方法を選択します。

外部 C または C++ コードの統合方法 (Embedded Coder)

7外部 MATLAB コードのセクションが組み込みブロックにマッピングする。アプリケーションの組み込みブロックを使用して、モデルのコンテキスト内でアルゴリズムを開発します。

外部 MATLAB コードを MATLAB Function ブロックに組み込んだり、MATLAB Coder ソフトウェアを使用して C または C++ コードを MATLAB コードから生成するために、MATLAB コードは C/C++ コード生成でサポートされる関数とクラスを使用しなければなりません。

外部 C または C++ コードの統合方法

ほとんどの場合、レガシ コード ツールで S-Function および TLC ファイルを生成して、C または C++ で記述された外部コードを Simulink 環境に統合できます。このツールでは、MATLAB コードとして指定する仕様を使用して、既存の MATLAB 関数を、Simulink モデルに含めて、生成されたコードから呼び出すことができる関数 C MEX S に変換します。詳細については、レガシ コード ツールを使用したアルゴリズムの実装Import Calls to External Code into Generated Code with Legacy Code Tool (Embedded Coder)を参照してください。

他の方法と比べて、レガシ コード ツールは、組み込みシステム用に十分に最適化されたコードを生成するのに最適です。以下の 1 つ以上の条件に該当する場合は、他の方法を検討してください。

  • 外部コードでグローバル変数を使用してデータを交換している。

  • プログラミング経験が限定的である。

  • アルゴリズムで分散状態および連続状態のダイナミクスをモデル化しなければならない。

  • 統合された外部コードを Stateflow チャートに含める。

  • 外部コードに固定小数点インターフェイスが必要。

  • コード ジェネレーターで生成するコードを制御する最大限の柔軟性が必要。

  • MATLAB Function ブロックに組み込まれる関数 coder.ceval の呼び出しに外部コードの呼び出しを迅速に組み込む必要があり、パフォーマンスは重要ではない。

以下の図と表を参照して、統合要件に基づく最適な統合方法を選択できます。

 条件または要件アクション詳細
1外部 C コードを生成された C++ コードに統合する、またはその反対を行う外部コードの言語を変更して、生成コードの言語選択を一致させます。生成コードに合わせるための外部コードのプログラミング言語の変更 (Embedded Coder)
2アルゴリズムに、ステート マシンおよびフロー チャートに基づく設計ロジックが含まれる。または、統合する関数でグローバル変数を使用してモデルとデータを交換しなければならない。関数はグローバル変数を定義し、それらの変数を使用して、値を返したり出力を引数に書き込むのではなく、出力を作成する。Stateflow チャートをモデルに追加します。C をアクション言語として使用して、チャートから外部コードを呼び出します。チャートで、外部関数を呼び出し、グローバル変数に対して読み書きを実行するコードを作成します。外部コードの出力で計算を実行するために、モデルは実行時にグローバル変数から読み込まなければなりません。Stateflow チャートへの外部コードの挿入 (Embedded Coder)
3シミュレーションおよびコード生成のために外部 C または C++ コードを Stateflow チャートに含める。外部 C または C++ コードを適用するチャートが含まれるモデルを構成します。
4モデルに外部 C または C++ コードの呼び出しを迅速に組み込む。パフォーマンスは重要ではない。MATLAB Function ブロック内から関数 coder.ceval で C または C++ コードを呼び出します。
5通常コード ジェネレーターで生成される、model_stepmodel_initializemodel_terminate などのコードよりも多くのエントリポイント関数がアプリケーションに必要。コード ジェネレーターで生成するコードを制御する最大限の柔軟性が必要。S-Function と TLC ファイルを手動で作成します。
6離散時間アプリケーション用に外部コードをシミュレートおよび生成する。生成コードの最適化は必須。コード ジェネレーターで生成されるコードの制御について中程度の柔軟性をもつ使いやすさが必要。C または C++ プログラミング経験があるが、コードをモデルに追加するファイルを生成する方法を選択する。

レガシ コード ツールを使用して S-Function と TLC ファイルを生成します。必要に応じて、アプリケーション要件を満たすよう生成コードを手動で調整します (生成コードを変更する場合、S-Function と TLC ファイルを再生成すると、変更内容が失われます)。

C で記述されたシンプルなアルゴリズムの場合は、Simulink C Caller ブロックの使用を検討してください。

7アルゴリズムは、シミュレーションおよびラピッド プロトタイピング用に離散状態および連続状態のダイナミクスをモデル化しなければならない。外部コードに固定小数点インターフェイスが必要。プログラミング経験が限定的である。ラピッド プロトタイピング用にコード ジェネレーターで生成されるコードを制御するために基本の柔軟性をもつ使いやすさが必要。S-Function Builder を使用して、S-Function および TLC ビルドを生成します。必要に応じて、アプリケーション要件を満たすよう生成コードを手動で調整します (生成コードを変更する場合、S-Function と TLC ファイルを再生成すると、変更内容が失われます)。

生成コードに合わせるための外部コードのプログラミング言語の変更

外部 C コードを生成された C++ コードに統合するまたはその逆を行うには、生成されたコード用のプログラミング言語選択に合わせて外部コードの言語を変更します。プログラミング言語を一致させるオプションは次のとおりです。

  • 生成されたコード用に選択した言語で外部コードを記述するまたは書き換える。

  • C++ コードを生成していて、外部コードが C コードの場合は、C 関数ごとに、関数をプロトタイプするヘッダー ファイルを作成する。次の形式を使用します。

    #ifdef __cplusplus
    extern "C" {
    #endif
    int my_c_function_wrapper();
    #ifdef __cplusplus
    }
    #endif

    プロトタイプは関数ラッパーの役割を果たします。コンパイラで C++ コードがサポートされている場合、__cplusplus の値が定義されます。リンケージ指定 extern "C" により、名前マングリングを使用しない C リンケージが指定されます。

  • C コードを生成していて、外部コードが C++ コードの場合は、extern "C" リンケージ仕様を各 .cpp ファイルに含める。たとえば、次の例は、my_func.cpp ファイルの C++ コードを示します。

    extern "C" {
    
    int my_cpp_function()
    {
      ...
    }
    }

外部 Fortran コードの統合方法

外部 Fortran コードを統合するには、S-Function と対応する TLC ファイルを作成します。

C/C++ S-Function の基礎Fortran コードを使用したアルゴリズムの実装S-Functions and Code Generation (Embedded Coder)およびFortran S-Function Examplesを参照してください。

Stateflow チャートへの外部コードの挿入

ライブラリ チャート用の外部コードの統合

コード生成用の Stateflow ライブラリ チャートのみに適用される外部コードを統合するには、チャートをメイン モデルに提供するライブラリ モデルごとに以下の手順を実行します。次に、コードを生成します。

  1. Stateflow エディターで、モデル コンフィギュレーション ダイアログ ボックスを開きます。パラメーター [ローカルなカスタム コード設定を使用 (メイン モデルから継承しません)] を選択します。

    ライブラリ モデルはコード生成中に独自のカスタム コード設定を保持します。

  2. サブペインで、カスタム コードを指定します。

    カスタム コードへの相対パスの指定 (Stateflow)のガイドラインに従ってください。

    シミュレーションのカスタム コード設定を指定した場合、この設定をコード生成に適用することができます。同じ情報を再び入力せずにすむように、[シミュレーション ターゲットと同じカスタム コードの設定を使用] チェック ボックスをオンにします。

  3. [OK] をクリックします。

ライブラリ モデルごとにこれらの手順を完了してから、コードを生成します。

すべてのチャート用の外部コードの統合

コード生成用のチャートすべてに適用される外部コードを統合するには、以下を行います。

  1. メイン モデルのコード生成用のカスタム コード オプションを指定します。

    1. [モデル コンフィギュレーション パラメーター] ダイアログ ボックスで、[コード生成][カスタム コード] を選択します。

    2. カスタム コード テキスト フィールドで、カスタム コードを指定します。

      カスタム コードへの相対パスの指定 (Stateflow)のガイドラインに従ってください。

      シミュレーションのカスタム コード設定を指定した場合、この設定をコード生成に適用することができます。同じ情報を再び入力せずにすむように、[シミュレーション ターゲットと同じカスタム コードの設定を使用] チェック ボックスをオンにします。

  2. チャートをメイン モデルに提供する各ライブラリ モデルのコード生成を設定します。Stateflow エディターで、[モデル コンフィギュレーション] ダイアログ ボックスを開きます。パラメーター [ローカルなカスタム コード設定を使用 (メイン モデルから継承しません)] をオフにします。ライブラリ チャートはメイン モデルのカスタム コード設定を継承します。[OK] をクリックします。

  3. コードを生成します。

モデルおよび生成コードからの外部 C コードの呼び出し

レガシ コード ツールを使用して、既存の外部関数をシミュレーションまたは生成されたコードから呼び出します。

以下の方法について説明します。

  • Simulink® モデル シミュレーションの一部である C 関数を評価する。

  • C 関数をモデルから生成したコードから呼び出す。

モデル例の詳細については、C コード生成のためのコントロール アルゴリズム モデルの準備 (Embedded Coder)を参照してください。

置換プロセス

モデル例 rtwdemo_PCG_Eval_P4 を開きます。

Simulink® モデルだけでなく、多くのモデルベース デザイン アプリケーションの設計に含まれる既存の C 関数のセットは、テストおよび検証が行われています。これらの関数を Simulink® モデルと統合し、関数を使用するコードを生成できます。

この例では、既存の C 関数を呼び出すカスタム Simulink® ブロックを作成します。その後、ブロックをモデルに追加し、Simulink® のモデル シミュレーションを介してシステム全体をテストをすることができます。

モデル例では、PI コントローラーの Lookup ブロック (ルックアップ テーブル) を既存の C 関数への呼び出しと置き換えることができます。この関数はファイル SimpleTable.cSimpleTable.h で定義されています。

SimpleTable.c を表示します。

SimpleTable.h を表示します。

C 関数を呼び出すブロックの作成

既存の C 関数の呼び出しを指定するには、S-Function ブロックを使用します。レガシ コード ツールを使用すると、S-Function ブロックの作成を自動化することができます。このツールを使用して、最初に既存の C 関数とのインターフェイスを指定します。そして、そのインターフェイスを使用して S-Function ブロックを作成します。

レガシ コード ツールを使用して SimpleTable.c 内の既存の C 関数用の S-Function ブロックを作成します。

1. 関数インターフェイスの定義を含む構造体を作成します。

def = legacy_code('initialize')

構造体 def を使用して既存の C コードとの関数インターフェイスを定義できます。

2. 構造体のフィールドに入力します。

3. S-Function を作成します。

legacy_code('sfcn_cmex_generate',def)

4. S-Function をコンパイルします。

legacy_code('compile',def)

5. S-Function ブロックを作成します。

legacy_code('slblock_generate',def)

生成された S-Function ブロックにより、SimpleTable.c で C 関数が呼び出されます。これで、この S-Function ブロックをモデル内で使用できます。

6. TLC ファイルを作成します。

legacy_code('sfcn_tlc_generate',def)

このコマンドは、ブロック用コードの生成方法を指定する S-Function のコンポーネントである TLC ファイルを作成します。

シミュレーションによる外部コードの確認

Simulink® モデル内で既存の C コードを統合する場合、生成された S-Function ブロックを確認します。

Lookup ブロックの置換を確認するために、Lookup ブロックで生成されたシミュレーション結果を新しい S-Function ブロックで生成された結果と比較します。

1. 確認モデルを開きます。

  • Sine Wave ブロックは範囲が [-2 : 2] の出力値を生成します。

  • ルックアップ テーブルの入力範囲は次のとおりです。[-1 :1]。

  • ルックアップ テーブルは入力の絶対値を出力します。

  • ルックアップ テーブルは、入力の限界値で出力を切り取ります。

2. 確認モデルを実行します。

次の図に検証結果を示します。既存の C コードと Simulink® テーブル ブロックは同じ出力値を生成します。

C コードを Simulink® モデルの一部として検証

既存の C 関数コードをスタンドアロン コンポーネントとして検証した後、S-Function をモデル内で検証します。検証作業を完了するには、テスト ハーネス モデルを使用します。

1. テスト ハーネスを開きます。

2. テスト ハーネスを実行します。

シミュレーション結果はゴールデン値と一致しています。

生成コードからの C 関数の呼び出し

コード ジェネレーターは S-Function ブロックをシステムの他のブロックと同様に処理するために TLC ファイルを使用します。コード ジェネレーターは、S-Function ブロックによって、複数の計算を単一の出力計算にまとめる演算である "式の畳み込み" を実装することができます。

1. フル モデルをビルドします。

2. 生成コードを PI_Control_Reusable.c で調査します。

生成コードは C 関数 SimpleTable を呼び出します。

次の図に、C コードを統合する前後の生成コードを示します。統合前は、コードは生成されたルックアップ ルーチンを呼び出します。統合後は、生成コードは C 関数 SimpleTable を呼び出します。

関連するトピック