外部 C 関数の呼び出し
この例について
学習目的
モデル シミュレーションの一部である C 関数を評価する。
生成コードから外部 C 関数を呼び出す。
前提条件
Simulink® モデルとサブシステムを開いて変更する技能。
モデルのコンフィギュレーション パラメーターを構成する技能。
C コードを読む技能。
サポートされている C コンパイラがインストール済み。
必要なファイル
rtwdemo_throttlecntrl_extfunccall
モデル ファイルrtwdemo_ValidateLegacyCodeVrsSim
モデル ファイル/toolbox/rtw/rtwdemos/EmbeddedCoderOverview/stage_4_files/SimpleTable.c
/toolbox/rtw/rtwdemos/EmbeddedCoderOverview/stage_4_files/SimpleTable.h
モデルに外部 C 関数を含める
Simulink モデルはモデル ベース デザインの一部です。多くのアプリケーションの設計には、MATLAB® および Simulink 環境外で作成、テスト (確認)、検証済みの既存の一連の C 関数も含まれています。これらの関数を、モデルと生成コードに簡単に統合することができます。生成コード内で外部 C コードを使用して、ラピッド シミュレーションの実行中にハードウェア デバイスや外部データ ファイルにアクセスできます。
この例では、外部 C 関数を呼び出すカスタム ブロックの作成方法を紹介します。そのブロックがモデルの一部であれば、シミュレーション環境の利点を活かしてシステムのより高度なテストを実行できます。
C 関数を呼び出すブロックの作成
外部 C 関数の呼び出しを指定するには、S-Function ブロックを使用します。Simulink レガシ コード ツールを使用すると、S-Function ブロックの作成プロセスを自動化することができます。このツールを使用して、外部 C 関数とのインターフェイスを指定します。そして、S-Function ブロックの作成を自動化するインターフェイスを使用します。
ファイル
SimpleTable.c
とSimpleTable.h
のコピーを作成します。これらは
(開く) フォルダーに配置されています。作業フォルダーにコピーを置きます。matlabroot
/toolbox/rtw/rtwdemos/EmbeddedCoderOverview/stage_4_filesシミュレーション中の各タイム ステップに指定した関数を呼び出す S-Function ブロックを作成します。
MATLAB コマンド ウィンドウで、関数インターフェイス定義構造体を作成します。
def=legacy_code('initialize')
データ構造体
def
は外部 C コードに対する関数インターフェイスを定義します。def = SFunctionName: '' InitializeConditionsFcnSpec: '' OutputFcnSpec: '' StartFcnSpec: '' TerminateFcnSpec: '' HeaderFiles: {} SourceFiles: {} HostLibFiles: {} TargetLibFiles: {} IncPaths: {} SrcPaths: {} LibPaths: {} SampleTime: 'inherited' Options: [1x1 struct]
以下のコマンドを入力して、関数インターフェイス定義構造体を配置します。
def.OutputFcnSpec=['double y1 = SimpleTable(double u1,',... 'double p1[], double p2[], int16 p3)']; def.HeaderFiles = {'SimpleTable.h'}; def.SourceFiles = {'SimpleTable.c'}; def.SFunctionName = 'SimpTableWrap';
S-Function を作成します。
legacy_code('sfcn_cmex_generate', def)
S-Function をコンパイルします。
legacy_code('compile', def)
S-Function ブロックを作成します。
legacy_code('slblock_generate', def)
SimpTableWrap
ブロックを含む新しいモデル ウィンドウが開かれます。ヒント
S-Function ブロックの作成は 1 回だけのタスクです。1 回ブロックを作成すれば、複数のモデルにも再利用できます。
モデルを
s_func_simptablewrap
の形式で作業フォルダーに保存します。S-Function ブロック用に Target Language Compiler (TLC) ファイルを作成します。
legacy_code('sfcn_tlc_generate', def)
TLC ファイルはコード ジェネレーターによるブロック用コードの生成方法を指定する S-Function のコンポーネントです。
レガシ コード ツールの使用の詳細は、以下を参照してください。
Simulink 環境での外部コードの検証
外部 C コードを Simulink モデルと統合する場合、コードを使用する前に、外部 C 関数がスタンドアロン コンポーネントとして機能することを検証してください。
モデル
rtwdemo_ValidateLegacyCodeVrsSim
を開きます。このモデルは作成した S-Function ブロックを検証します。Sine Wave ブロックは次の範囲の出力値を生成します。[-2 :2]。
ルックアップ テーブルの入力範囲は次のとおりです。[-1 :1]。
ルックアップ テーブルからの出力は入力の絶対値です。
ルックアップ テーブルの出力は、入力の限界値で出力を切り取ります。
モデルのシミュレーションを実行します。
Validation
サブシステムを開き、そのサブシステム内で Scope ブロックをクリックして、検証結果を表示します。次の図に確認結果を示します。外部 C コードと Simulink Lookup Table ブロックでは、同じ出力値になります。
検証モデルを閉じます。
C コードをモデルの一部として検証
外部 C 関数コードの機能を独立したコンポーネントとして確認した後で、モデルの S-Function を確認します。テスト ハーネス モデルを使用して確認作業を完了します。
メモ
次の手順には Stateflow® のライセンスが必要です。
rtwdemo_throttlecntrl_extfunccall
を開いて、MATLAB パスの書き込み可能なフォルダーのthrottlecntrl_extfunccall
にコピーを保存します。PI_ctrl_1
およびPI_ctrl_2
サブシステムを調べます。Lookup ブロックが、レガシ コード ツールを使用して作成したブロックに置き換えられました。
SimpTableWrap
およびSimpTableWrap1
のブロック パラメーターの設定を調べます。[ブロック パラメーター] ダイアログ ボックスと PI サブシステム ウィンドウを閉じます。
テスト ハーネス モデルを開いて、
Unit_Under_Test
Model ブロックを右クリックし、[ブロック パラメーター (ModelReference)] を選択します。[モデル名] を
throttlecntrl_extfunccall
に設定します。[OK] をクリックします。テスト ハーネス モデルのブロック線図を更新します。
テスト ハーネスをシミュレートします。
シミュレーション結果は期待されるゴールデン値と一致しています。
throttlecntrl_extfunccall
およびthrottlecntrl_testharness
を保存して閉じます。
生成コードからの C 関数 の呼び出し
コード ジェネレーターは TLC ファイルを使用して、S-Function ブロックを処理します。S-Function ブロックに組み込まれている C コードを呼び出します。
データ オブジェクトを使用できます。
"式の畳み込み"、つまり複数の計算を単一の出力計算にまとめる操作が行われます。
throttlecntrl_extfunccall
を開きます。モデルのコードを生成します。
ファイル
throttlecntrl_extfunccall.c
内で生成コードを調査します。throttlecntrl_extfunccall
とthrottlecntrl_testharness
を閉じます。
重要なポイント
レガシ コード ツールを使用して、外部関数をモデルと生成コードに簡単に統合することができます。
スタンドアロン コンポーネントとしてモデルに統合した外部 C 関数の機能を検証してください。
外部 C 関数コードの機能を独立したコンポーネントとして確認した後で、モデルの S-Function を確認します。