このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
TLC での S-Function のインライン化
timesN
チュートリアルの概要
目的: TLC で S-Function を扱う方法を理解する。
次の例を開きます。
openExample('simulinkcoder/AdviceAboutTLCTutorialsExample')
cd(tlctutorial/timesN)
このチュートリアルでは、既存の S-Function timesN
の C コード バージョンを生成します。
チュートリアルのステップは次のとおりです。
インラインでないコードの生成 — SimStruct と汎用 API を使用
TLC を使用して S-Function をインライン化する理由 — インライン化の利点
インライン化 S-Function の作成 — カスタム TLC コードを使用
S-Function の "ラップ" に関する情報と手法については、この後のチュートリアルで扱います。
インラインでないコードの生成
作業フォルダーのチュートリアル フォルダー tlctutorial/timesN
に Simulink® S-Function timesN.c
が用意されています。
この演習では、モデル sfun_xN
からインラインでないコードを生成します。
tlctutorial/timesN
でファイルrename_timesN.tlc
を見つけます。このファイルの名前をtimesN.tlc
に変更します。これにより、コードを生成できるようになります。MATLAB® コマンド ウィンドウで、S-Function の MEX ファイルを作成します。
mex timesN.c
これにより、Simulink に付属しているバージョンが選択されなくなります。
モデル
sfun_xN
を開きます。このモデルではtimesN
S-Function を使用しています。ブロック線図は次のとおりです。[コンフィギュレーション パラメーター] ダイアログ ボックスを開き、[ソルバー] ペインを選択します。
[終了時間] を
10.0
に設定します。[ソルバー オプション] を設定します。
[タイプ] を
Fixed-step
[ソルバー] を
Discrete (no continuous states)
[固定ステップ サイズ] を
0.01
[最適化] ペインを選択し、[既定のパラメーター動作] が
[調整可能]
に設定されていることを確認します。[コード生成] 、 [コメント] ペインを選択し、[コメントを含める] が既定でオンになっていることを確認します。
[コード生成] ペインを選択し、[コード生成のみ] をオンにします。
[適用] をクリックします。
Ctrl+B を押してモデルの C コードを生成します。
結果のファイル
sfun_xN_grt_rtw/sfun_xN.c
を開き、次に示すsfun_xN_output
の部分を確認します。
/* Model output function */ static void sfun_xN_output(int_T tid) { /* Sin: '<Root>/Sin' */ sfun_xN_B.Sin = sin(sfun_xN_M->Timing.t[0] * sfun_xN_P.Sin_Freq + sfun_xN_P.Sin_Phase) * sfun_xN_P.Sin_Amp + sfun_xN_P.Sin_Bias; /* S-Function Block: <Root>/S-Function */ /* Multiply input by 3.0 */ sfun_xN_B.timesN_output = sfun_xN_B.Sin * 3.0; /* Outport: '<Root>/Out' */ sfun_xN_Y.Out = sfun_xN_B.timesN_output; UNUSED_PARAMETER(tid); }
[コンフィギュレーション パラメーター] ダイアログ ボックスの [コード生成] 、 [コメント] ペインで [コメントを含める] が既定でオンになっているため、コードにコメントが表示されています。
TLC を使用して S-Function をインライン化する理由
コード ジェネレーターには、ユーザー記述のアルゴリズムやドライバーを呼び出すために使用できる汎用 API があります。API には、初期化、出力、導関数、終了などのさまざまなコールバック関数のほか、データ構造体も含まれます。これらのコードを記述すると、メモリ内でインスタンス化され、実行時に間接的な関数呼び出しを介して呼び出されます。これらを呼び出すたびに、スタック フレームやその他のオーバーヘッドが発生し、実行時間が長くなります。
リアルタイム環境では、ソリューションで呼び出されるステップが多い場合は特に、汎用 API の呼び出しが容認できないほど遅くなることがあります。コード ジェネレーターでは、S-Function を汎用 API から間接的に呼び出すのではなく、ユーザー記述のアルゴリズムを自動生成される関数内に組み込むことで、スタンドアロン アプリケーションを生成して S-Function を高速化できます。この形式の最適化を "インライン化" と呼びます。TLC で S-Function をインライン化すると、より高速で最適化されたコードが得られます。
TLC は C コード S-Function を記述する代わりにはならないことに注意してください。シミュレーションでは TLC ファイルは使用されないため、カスタム ブロックを Simulink で呼び出すには、引き続き S-Function を C で (または MATLAB ファイルとして) 記述しなければなりません。ただし、指定した S-Function をインライン化する TLC ファイルを準備すれば、ターゲット コードをはるかに効率的にすることができます。
インライン化 S-Function の作成
TLC では、S-Function と同じ名前の .tlc
ファイルを検出した場合は常に "インライン化 S-Function" を作成します。.tlc
ファイルが想定される形式になっていると仮定し、API のオーバーヘッドを発生させることなく、外部の S-Function と機能的に重複しているコードの作成を行います。以下の手順を実行して、このプロセスの仕組みを確認します。
まだ準備していない場合は、
tlctutorial/timesN
でファイルrename_timesN.tlc
を見つけます。コードの生成に使用できるように、このファイルの名前をtimesN.tlc
に変更します。ファイルの実行可能部分は次のとおりです。%implements "timesN" "C" %% Function: Outputs =========================================================== %% %function Outputs(block, system) Output %assign gain =SFcnParamSettings.myGain /* %<Type> Block: %<Name> */ %% /* Multiply input by %<gain> */ %assign rollVars = ["U", "Y"] %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars %<LibBlockOutputSignal(0, "", lcv, idx)> = \ %<LibBlockInputSignal(0, "", lcv, idx)> * %<gain>; %endroll %endfunction
S-Function のインライン バージョンを作成します。
[コンフィギュレーション パラメーター] ダイアログ ボックスの [最適化] ペインで、[既定のパラメーター動作] を
[インライン]
に設定し、[適用] をクリックします。ブロック線図のラベルを
model: sfun_xN
からmodel: sfun_xN_ilp
に変更します。モデルを
sfun_x2_ilp
として保存します。Ctrl+B を押します。ソース ファイルが
sfun_xN_ilp_grt_rtw
という名前の新しいサブフォルダーに作成されます。生成されたファイル
sfun_xN_ilp.c
のコードを調べます。/* Model output function */ static void sfun_xN_ilp_output(int_T tid) { /* Sin: '<Root>/Sin' */ sfun_xN_ilp_B.Sin = sin(sfun_xN_ilp_M->Timing.t[0]); /* S-Function Block: <Root>/S-Function */ /* Multiply input by 3.0 */ sfun_xN_ilp_B.timesN_output = sfun_xN_ilp_B.Sin * 3.0; /* Outport: '<Root>/Out' */ sfun_xN_ilp_Y.Out = sfun_xN_ilp_B.timesN_output; UNUSED_PARAMETER(tid); }
メモ
コード ジェネレーターでは、コードを生成して実行可能ファイルをビルドするときに、特定のサブフォルダー (ビルド フォルダーと呼ばれる) を作成または使用してソース ファイル、オブジェクト ファイル、make ファイルを格納します。既定では、ビルド フォルダーに
という名前が付けられます。model
_grt_rtw[既定のパラメーター動作] を
[インライン]
に設定してもコードが変わっていないことに注目してください。これは、S-Function が TLC でインライン化されるためです。
スタンドアロンのシミュレーションを作成して演習を続けます。
[コンフィギュレーション パラメーター] ダイアログ ボックスの [コード生成] ペインで、[コード生成のみ] をオフにし、[適用] をクリックします。
[コンフィギュレーション パラメーター] ダイアログ ボックスの [データのインポート/エクスポート] ペインで、[出力] をオンにします。
これを指定すると、モデルの出力データのログが MATLAB ワークスペースに記録されます。
Ctrl+B を押してコードを生成します。モデルがコンパイルされ、
sfun_xN_ilp.exe
(UNIX® システムの場合はsfun_xN_ilp
) という名前の実行可能ファイルにリンクされます。スタンドアロンの実行可能ファイルを実行して、
timesN.tlc
ファイルで想定した出力が生成されることを確認します。実行するには、MATLAB コマンド ウィンドウで次のように入力します。!sfun_xN_ilp
次のような応答が表示されます。
** starting the model ** ** created sfun_xN_ilp.mat **
sfun_xN_ilp.mat
ファイルの内容を表示またはプロットして、スタンドアロンのモデルで生成された正弦の出力範囲が -3 ~ +3 であることを確認します。MATLAB コマンド ウィンドウで次のように入力します。load sfun_xN_ilp.mat plot (rt_yout)
ヒント
UNIX プラットフォームの場合、コマンド ウィンドウで構文 !./
executable_name
を使用して実行可能プログラムを実行します。必要に応じて、構文 ./
executable_name
を使用して OS シェルから実行可能プログラムを実行します。詳細については、外部コマンド、スクリプト、プログラムの実行を参照してください。