このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
カスタマイズされた非同期ライブラリの作成
このトピックでは、Async Interrupt ブロックと Task Sync ブロックを開始点として使用して、ターゲット RTOS で使用する非同期ブロックを実装する方法について説明します。Rate Transition ブロックはターゲットから独立するブロックであるため、カスタマイズされたレート変換ブロックを作成する必要はありません。
メモ
このトピックに示されているオペレーティング システムの統合手法では、Interrupt Templates ブロック ライブラリのブロックを使用します。そのライブラリのブロックは、特定のターゲット環境でカスタム ブロックを開発するのに役立つ例となります。
非同期ブロックの実装について
非同期ライブラリ ブロックをカスタマイズするには、ブロックの実装を変更します。次のファイルが対象です。
ブロックの元になっている S-Function MEX ファイル
ブロックのコード生成を制御する TLC ファイル
また、ブロック マスクを変更して、RTOS 例 (VxWorks®) 固有の参照を削除し、ターゲット RTOS によって要求されたパラメーターを組み込む必要があります。
カスタム ブロックの実装は、最新のトピックで、Simulink® MEX S-Function 形式と API および Target Language Compiler (TLC) について熟知している必要があります。これらのトピックは、次のドキュメントで説明します。
Simulink のトピック、S-Function とは、モデルでの S-Function の使用、S-Function の動作およびImplementing S-Functionsは、MEX S-Function と S-Function API の概要について説明します。
S-Function のインライン化、C MEX S-Function のインライン化およびS-Function とコード生成は、コード生成に使用する TLC ブロックの実装の作成方法について説明します。
以下の節では、TLC 非同期サポート ライブラリ (asynclib.tlc
) の必須 SimStruct
マクロおよび関数を含む非同期ライブラリ ブロックの C/C++ および TLC の実装について説明します。
Async Interrupt ブロックの実装
Async Interrupt ブロックのソース ファイルは、
(開く) にあります。matlabroot
/rtw/c/tornado/devices
vxinterrupt1.c
:C MEX ファイル ソース コード。構成とシミュレーションに使用します。vxinterrupt1.tlc
:TLC 実装。コード生成に使用します。asynclib.tlc
: TLC サポート関数のライブラリ。ブロックの TLC 実装によって呼び出されます。このライブラリ呼び出しについては、asynclib.tlc サポート ライブラリを参照してください。
C MEX ブロックの実装
vxinterrupt1.c
のほとんどのコードは、非同期サポートと無関係な通常の関数を実行します (たとえば、ブロック マスクからパラメーターを取得して検証し、パラメーターを調整できないようにマークを付け、パラメーター データを
ファイルに渡します)。model
.rtw
関数 mdlInitializeSizes
は、以下で説明するように、非同期ブロックに必要な特殊な SimStruct
マクロと SS_OPTIONS
設定を使用します。
次のマクロは、関数 ssSetOutputPortWidth
を呼び出す前に呼び出すことはできません。
ssSetTimeSource
ssSetAsyncTimerAttributes
ssSetAsyncTimerResolutionEl
ssSetAsyncTimerDataType
ssSetAsyncTimerDataTypeEl
ssSetAsyncTaskPriorities
ssSetAsyncTaskPrioritiesEl
上記のマクロのいずれかが関数 ssSetOutputPortWidth
の前に呼び出された場合、次のエラー メッセージが表示されます。
SL_SfcnMustSpecifyPortWidthBfCallSomeMacro { S-function '%s' in '%<BLOCKFULLPATH>' must set output port %d width using ssSetOutputPortWidth before calling macro %s }
ssSetAsyncTimerAttributes. ssSetAsyncTimerAttributes
は、ブロックでタイマーが必要なことを宣言し、ブロック パラメーター [タイマー分解能 (秒)] の指定に従い、タイマーの分解能を設定します。
関数のプロトタイプは次のとおりです。
ssSetAsyncTimerAttributes(SimStruct *S, double res)
ここで
S は、Simstruct ポインターです。
パラメーター [タイマー分解能 (秒)] を
res
に設定します。
次のコード例は、ssSetAsyncTimerAttributes の呼び出しを示しています。
/* Setup Async Timer attributes */ ssSetAsyncTimerAttributes(S,mxGetPr(TICK_RES)[0]);
ssSetAsyncTaskPriorities. ssSetAsyncTaskPriorities
は、ブロック パラメーター [Simulink タスクの優先順位] に指定された、各割り込みレベルで実行するブロックの Simulink タスクの優先順位を設定します。
関数のプロトタイプは次のとおりです。
ssSetAsyncTaskPriorities(SimStruct *S, int numISRs, int *priorityArray)
ここで
S
は、SimStruct
ポインターです。numISRs
はブロック パラメーター [VME 割り込み番号] に指定された割り込みの数です。priorityarray
はブロック パラメーター [VME 割り込み番号] で指定された割り込み数を含んでいる整数配列です。
次のコード例は、関数 ssSetAsyncTaskPriorities
の呼び出しを示しています。
/* Setup Async Task Priorities */ priorityArray = malloc(numISRs*sizeof(int_T)); for (i=0; i<numISRs; i++) { priorityArray[i] = (int_T)(mxGetPr(ISR_PRIORITIES)[i]); } ssSetAsyncTaskPriorities(S, numISRs, priorityArray); free(priorityArray); priorityArray = NULL; }
SS_OPTION の設定. 以下のコード例は、vxinterrupt1.c
の SS_OPTION
設定を示しています。Function-Call Subsystem が割り込みに接続されている場合、SS_OPTION_ASYNCHRONOUS_INTERRUPT
を使用しなければなりません。詳細については、
の matlabroot
/simulink/include/simstruc.hSS_OPTION
および SS_OPTION_ASYNCHRONOUS
のドキュメンテーションを参照してください。
ssSetOptions( S, (SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME | SS_OPTION_ASYNCHRONOUS_INTERRUPT));
S-Function で SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME
オプションを指定し、Inf
のサンプル時間を継承すると、コード ジェネレーターは、ブロックが不変かどうかに基づいてブロックのコードを生成する方法を決めます。端子信号が不変である場合、ブロックは不変です。シミュレーション全体においてブロックに定数値がある場合、信号は不変です。Constant ブロックのサンプル時間を指定する場合は、端子信号が不変であると想定しないでください。詳細については、インライン不変信号を参照してください。ブロックが不変でない場合、コード ジェネレーターは、エントリポイント関数の初期化でのみコードを生成します。ブロックが不変の場合、コード ジェネレーターはブロックのコードを生成しません。
TLC 実装
この節では、ターゲット RTOS のコードを生成するために変更する必要があるターゲット固有の特徴に重点を置きながら、vxinterrupt1.tlc
の各関数について説明します。
#include 命令の生成. vxinterrupt1.tlc
begins with the statement
%include "vxlib.tlc"
vxlib.tlc
は、RTOS 例 (VxWorks) のヘッダー ファイルを含めるという命令を生成するターゲット固有のファイルです。このファイルは、ターゲット RTOS のインクルード機能を生成するファイルと置き換えなければなりません。
関数 BlockInstanceSetup. 関数 BlockInstanceSetup
は、接続された Async Interrupt ブロックの出力ごとに、生成コードの対応する ISR の関数名を定義します。関数名は次の形式になります。
isr_num_vec_offset
ここで、
はブロック パラメーター [VME 割り込み番号] で定義された ISR 数で、num
はブロック パラメーター [VME 割り込みベクトル オフセット] で定義された割り込みテーブル オフセットです。offset
カスタム実装の場合、必ずしもこの規則に従って名前を付ける必要はありません。
関数名は、関数 Outputs
によって使用される場合はキャッシュされ、実際の ISR コードを生成します。
関数 Outputs. 関数 Outputs
は、接続されている Async Interrupt ブロックの出力を反復します。ISR は、このような出力ごとに生成されます。
ISR コードは、生成コードの "Functions"
セクションでキャッシュされます。関数 Outputs
は、ISR の生成前に次の処理を実行します。
下流ブロックの呼び出し (一時的なバッファーにキャッシュされます) を生成します。
ISR をロックする必要があるかどうかを決定します (ブロック パラメーター [プリエンプション フラグ] で指定)。
Async Interrupt ブロックに接続されているブロックが Task Sync ブロックかどうかを特定します (この情報は、
asynclib
呼び出し (関数LibGetFcnCallBlock
および関数LibGetBlockAttribute
) を使用して取得します)。このとき、以下のようになります。ISR のプリエンプション フラグは、
1
に設定されなければなりません。それ以外の場合、エラーになります。整数のみのコード生成のモデルが設定されていない場合、浮動小数点コンテキストを保存および復元する RTOS (VxWorks) 呼び出しが生成されます。
ISR コードを生成すると、関数 Outputs
によって asynclib
関数 LibNeedAsyncCounter
が呼び出され、接続されているサブシステムによってタイマーが要求されます。このとき、時間ソースが関数 ssSetTimeSource
によって SS_TIMESOURCE_SELF
に設定されている場合、関数 LibSetAsyncCounter
が呼び出され、RTOS (VxWorks) 関数 tickGet
呼び出しが生成され、カウンターが更新されます。実装時、ターゲット RTOS と同等の呼び出しを生成するか、コードを生成して、ターゲット ハードウェアのタイマー レジスタを読み取ります。
関数 Start. 関数 Start
は、各 ISR に接続して有効にするために必要な RTOS (VxWorks) 呼び出し (int_connect
および sysInt_Enable
) を生成します。この呼び出しは、ターゲット RTOS の呼び出しと置き換えなければなりません。
関数 Terminate. 関数 Terminate
は、各 ISR を無効にするための呼び出し sysIntDisable
を生成します。この呼び出しは、ターゲット RTOS の呼び出しと置き換えなければなりません。
Task Sync ブロックの実装
Task Sync ブロックのソース ファイルは、
(開く) にあります。内容は以下のとおりです。matlabroot
/rtw/c/tornado/devices
vxtask1.cpp
:MEX ファイル ソース コード。構成とシミュレーションに使用します。vxtask1.tlc
:TLC 実装。コード生成に使用します。asynclib.tlc
: TLC サポート関数のライブラリ。ブロックの TLC 実装によって呼び出されます。このライブラリ呼び出しについては、asynclib.tlc サポート ライブラリを参照してください。
C MEX ブロックの実装
Task Sync ブロックは、Async Interrupt ブロックと同様に、タイマーを設定します (この場合、固定分解能)。このブロックに関連付けられたタスクの優先順位は、ブロック パラメーター [Simulink タスクの優先順位] から取得されます。SS_OPTION
設定は、Async Interrupt ブロックに使用される設定と同じです。
ssSetAsyncTimerAttributes(S, 0.01); priority = (int_T) (*(mxGetPr(PRIORITY))); ssSetAsyncTaskPriorities(S,1,&priority); ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_ASYNCHRONOUS | SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME)); }
TLC 実装
#include 命令の生成. vxtask1.tlc
begins with the statement
%include "vxlib.tlc"
vxlib.tlc
は、RTOS 例 (VxWorks) のヘッダー ファイルを含めるという命令を生成するターゲット固有のファイルです。このファイルは、ターゲット RTOS のインクルード機能を生成するファイルと置き換えなければなりません。
関数 BlockInstanceSetup. 関数 BlockInstanceSetup
は、後でコード生成に使用するタスク名、ブロック名および他の識別子を導出します。また、未接続のブロックの条件をチェックして、警告を生成し、割り込みオーバーフロー条件で使用されるセマフォ (stopSem
) のストレージ宣言を生成します。
関数 Start. 関数 Start
は、Task Sync ブロックによって発生したタスクの管理に使用されるセマフォのストレージを定義するために必要な RTOS (VxWorks) 呼び出しを生成します。ターゲットの CodeFormat
TLC 変数の値に応じて、静的なストレージ宣言または動的メモリ割り当て呼び出しが生成されます。また、この関数によって、セマフォ (semBCreate
) が作成され、RTOS タスク (taskSpawn
) が発生します。これらの呼び出しは、ターゲット RTOS の呼び出しで置き換えなければなりません。
関数 Outputs. 関数 Outputs
は、セマフォを待機する RTOS 例 (VxWorks) タスクを生成します。この関数は、セマフォを取得すると、ブロックのタイマー目盛りを更新し、下流のサブシステム コードを呼び出します。また、関数 Outputs
でも、セマフォを許可するコード (割り込みレベルから呼び出されます) を生成します。
関数 Terminate. 関数 Terminate
は、RTOS 例 (VxWorks) 呼び出し taskDelete
を生成して、ブロックによって発生したタスクの実行を終了します。この呼び出しは、ターゲット RTOS の呼び出しと置き換えなければなりません。
また、ターゲット RTOS によってタスクに関連付けられたメモリが動的に割り当てられている場合、関数 Terminate
はメモリの割り当てを解除します。
asynclib.tlc サポート ライブラリ
asynclib.tlc
は、非同期ブロックの実装をサポートする TLC 関数のライブラリです。一部の関数は、非同期ブロック専用に設計されています。たとえば、関数 LibSetAsyncCounter
は、非同期ブロックのタイマーを更新する呼び出しを生成します。また、別の関数は、非同期ブロックによって要求された情報 (接続された Function-Call Subsystem の情報など) を返すユーティリティです。
次の表は、ライブラリのパブリックな呼び出しをまとめたものです。詳細は、ライブラリ ソース コードと、ライブラリ関数を呼び出す vxinterrupt1.tlc
ファイルおよび vxtask1.tlc
ファイルを参照してください。
asynclib.tlc ライブラリ関数のまとめ
関数 | 説明 |
---|---|
| 関数呼び出し出力をもつインライン S-Function によって使用されます。Function-Call Subsystem を実行するコードを生成します。 |
| ブロック レコードのフィールド値を返します。 |
| S-Function ブロックと呼び出しインデックスが指定されている場合、下流の Function-Call Subsystem ブロックのブロック レコードを返します。 |
| 上流の非同期タスクの時間カウンターへのアクセスを可能にします。 |
| 上流の非同期タスクの時間カウンターの上位ワードへのアクセスを可能にします。 |
| 非同期タスクがカウンターを必要とし、独自のタイマーを管理するかどうかを決定します。 |
| 呼び出し側のブロックは、非同期カウンターが必要な場合、 |
| 非同期タスクによって維持される |
| ブロックの非同期カウンターの目盛り値を設定するコードを生成します。 |
| ブロックの非同期カウンターの上位ワードの目盛り値を設定するコードを生成します。 |