メインコンテンツ

C Function ブロックを使用した外部 C/C++ コードの Simulink への統合

C Function ブロックを使用して、外部 C コードを呼び出し、Simulink® モデルに統合することができます。C Function ブロックでは、外部 C コードを呼び出し、ブロック パラメーター ダイアログ ボックスの [出力] ペイン、[開始] ペイン、[初期化条件] ペイン、[終了] ペインを使用してコードの統合をカスタマイズできます。C Function ブロックを使用して以下のことを行います。

  • 名前空間の下に定義されている関数を含む外部 C コードから関数を呼び出し、コードを Simulink モデル用にカスタマイズする。

  • C 関数を呼び出すためにデータを前処理し、関数呼び出し後にデータを後処理する。

  • シミュレーションとコード生成とで別のコードを指定する。

  • 複数の関数を呼び出す。

  • ブロックにキャッシュされた永続データを初期化したり操作したりする。

  • メモリの割り当てと割り当て解除を行う。

変更する外部 C アルゴリズムを Simulink 内に呼び出すには、C Function ブロックを使用します。Simulink モデルから 1 つの C 関数を呼び出すには、C Caller ブロックを使用します。連続状態または状態の変化をもつ動的システムを統合するには、S-Function ブロックを使用します。

メモ

Simulink へのカスタム C コード統合でサポートされる C 言語の標準バージョンは C99 です。

以下の例では、C Function ブロックを使用して入力の合計と平均を計算します。

外部ソース ファイルの書き込み

まず、外部ソース ファイルを作成します。

  1. data_array.h という名前のヘッダー ファイルを作成します。

    /* Define a struct called DataArray */
    typedef struct DataArray_tag {
        /* Define a pointer called pData */
        const double* pData;
        /* Define the variable length */
        int length;
    } DataArray;
    
    /* Function declaration */
    double data_sum(DataArray data);

  2. 同じフォルダーで新しいファイル data_array.c を作成します。このファイルには、入力された数値の合計を計算する C 関数を記述します。

    #include "data_array.h"
    
    /* Define a function that takes in a struct */
    double data_sum(DataArray data)
    {
        /* Define 2 local variables to use in the function */
        double sum = 0.0;
        int i;
        /* Calculate the sum of values */
        for (i = 0; i < data.length; i++) {
            sum = sum + data.pData[i];
        }
        /* Return the result to the block */
        return sum;
    }

Simulink への外部コードの入力

  1. 新しい空のモデルを作成し、C Function ブロックを追加します。C Function ブロックは、ライブラリ ブラウザーの [User-Defined Functions] ライブラリにあります。

  2. C Function ブロックをダブルクリックして、ブロック ダイアログ ボックスを開きます。

  3. カスタム ヘッダー ファイルとソース ファイルを定義します。

    • ヘッダー ファイルの定義 — ブロック ダイアログ ボックスで、[カスタム コード設定を構成します] ボタン の横にある矢印をクリックし、[コンフィギュレーション パラメーターのカスタム コードを使用] を選択します。次に、 ボタンをクリックして [コンフィギュレーション パラメーター] ダイアログ ボックスを開き、[シミュレーション ターゲット] ペインの [コード情報] タブの [インクルード ヘッダー] フィールドにファイル名を指定します。 (R2024a 以降)

      Specify custom header file in model Configuration Parameters dialog box. The following text is entered in the field: #include "data_array.h".

      R2024a より前: [カスタム コード設定を構成します] ボタン をクリックし、[シミュレーション ターゲット] ペインの [コード情報] タブの [インクルード ヘッダー] フィールドにファイル名を指定します。詳細については、Specify and Configure Custom C/C++ Codeを参照してください。

    • ソース ファイルの定義 — ブロック ダイアログ ボックスで、[カスタム コード設定を構成します] ボタン の横にある矢印をクリックし、[コンフィギュレーション パラメーターのカスタム コードを使用] を選択します。次に、 ボタンをクリックしてダイアログ ボックスを開き、[シミュレーション ターゲット] ペインの [コード情報] タブの [ソース ファイル] フィールドにファイル名を指定します。 (R2024a 以降)

      Specify custom source file in Configuration Parameters dialog box. The following text is entered in the field: data_array.c.

      R2024a より前: [カスタム コード設定を構成します] ボタン をクリックし、[シミュレーション ターゲット] ペインの [コード情報] タブの [ソース ファイル] フィールドにファイル名を指定します。詳細については、Specify and Configure Custom C/C++ Codeを参照してください。カスタム コードを正常に解析してビルドできることを確認するには、[カスタム コードの検証] をクリックします。

  4. C Function ブロック パラメーターのダイアログ ボックスの [シミュレーション] タブの [出力] ペインで、シミュレーション中にブロックで実行するコードを記述します。この例では、外部 C 関数で合計を計算します。[出力] ペインで、data_array.c 関数を呼び出して合計を計算し、その後、平均を計算するコードを記述します。

    /* declare the struct dataArr */
    DataArray dataArr;
    /* store the length and data coming in from the input port */
    dataArr.pData = &data[0];
    dataArr.length = length;
    
    /* call the function from the external code to calculate sum */
    sum = data_sum(dataArr);
    
    /* calculate the mean */
    mean = sum / length;

    シミュレーション開始時に実行するコードを [開始] ペインに、シミュレーション終了時に実行するコードを [終了] ペインに指定できます。

  5. [端子とパラメーター] テーブルを使用して、ブロックのコードで使用されるシンボルを定義します。[追加] ボタンと [削除] ボタンを使用してシンボルを追加または削除します。端子を正しく表示するため、[出力][開始][初期化条件][終了] ペインで使用されるすべてのシンボルを定義します。

    Use the Ports and Parameters table to specify the symbols.

    [端子とパラメーター] テーブルで、ブロックのコードで使用される各シンボルについて、[名前][スコープ][ラベル][タイプ][次元]、および [端子] を適宜定義します。

    [ブロック パラメーター] ダイアログ ボックスを閉じます。テーブルへのデータ入力後、C Function ブロックには、テーブルに指定したラベルをもつ 1 つの入力端子と 2 つの出力端子が含まれます。

  6. C Function ブロックへの入力となる Constant ブロックを Simulink キャンバスに追加します。Constant ブロック内に、100 の要素をもつランダムな行配列を作成します。結果を表示するため、C Function ブロックの出力に Display ブロックを付加します。

    Add Constant block that provides the input data to the model.

メモ

モデルにカスタム コードが含まれる場合、モデルが更新または実行されると、読み込まれたカスタム コードのシミュレーション実行可能ファイルが原因で slprj フォルダーがロックされる場合があります。ロックされているフォルダーは削除できません。実行可能ファイルをアンロードして、slprj フォルダーのロックを解除するには、clear mex コマンドを使用します。clearを参照してください。

シミュレーション用コードまたはコード生成用コードの指定

R2024a 以降のバージョンで、シミュレーションとコード生成に異なる出力コードを指定する必要がある場合、ブロック ダイアログ ボックスから [シミュレーションと同じコードを使用] パラメーターを使用することをお勧めします。異なる出力コードを指定するには、[コード生成] タブで [シミュレーションと同じコードを使用] チェック ボックスをオフにし、[シミュレーション] タブと [コード生成] タブの [出力] フィールドに出力コードを指定します。詳細については、シミュレーションと同じコードを使用を参照してください。これは、MATLAB_MEX_FILE を使用する代わりに異なるコードを指定する別の方法です。 (R2024a 以降)

R2024a より前: ブロック ダイアログ ボックスの [出力コード] フィールドに MATLAB_MEX_FILE を定義することで、C Function ブロックのシミュレーションとコード生成に異なる出力コードを指定できます。たとえば、モデルのシミュレーション中にのみ実行されるコードを指定するには、以下を使用します。

#ifdef MATLAB_MEX_FILE
/* Enter simulation code */
#else 
/* Enter code generation code */
#endif

コード生成のためのターゲット固有関数の宣言の指定

R2024a 以降のバージョンでは、ブロックの [コード生成] タブの [コードをそのまま生成 (最適化オフ)] チェック ボックスがオフになっている場合にのみ、ヘッダー ファイルを宣言する必要があります。この場合、[シミュレーション] タブの [出力] フィールドに、適切なシグネチャをもつ宣言を含め、コードを生成できます。 (R2024a 以降)

R2024a より前: コード生成のために、C Function ブロックから呼び出す関数 (ターゲット固有のデバイス ドライバーなど) の宣言を含む外部ヘッダー ファイルがない場合は、ブロックの [出力コード] フィールドに、適切なシグネチャをもつ宣言を含めることができます。

この操作により、次の例のように、コードが生成されるときに必要な関数に対する関数呼び出しが作成されます。

#ifndef MATLAB_MEX_FILE
extern void driverFcnCall(int16_T in, int16_T * out);
driverFcnCall(blockIn, &blockOut);
#endif

参考

関数

オブジェクト

ブロック

トピック