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を開きます。このモデルではtimesNS-Function を使用しています。ブロック線図は次のとおりです。
[コンフィギュレーション パラメーター] ダイアログ ボックスを開き、[ソルバー] ペインを選択します。
[終了時間] を
10.0に設定します。[ソルバー オプション] を設定します。
[タイプ] を
[固定ステップ]に設定する[ソルバー] を
[離散 (連続状態なし)]に設定する[固定ステップ サイズ (基本サンプル時間)] を
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 %endfunctionS-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 シェルから実行可能プログラムを実行します。詳細については、外部コマンド、スクリプト、プログラムの実行を参照してください。