Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

RTOS の非同期イベントを参照モデルの入力として渡す

この例では、リアルタイム マルチタスク システム上の非同期イベントのシミュレーションとコード生成方法について説明します。

モデル例について

モデル例 rtwdemo_async_mdlreftop を開きます。

open_system('rtwdemo_async_mdlreftop');

このモデルは割り込みソースをシミュレーションし、Async Interrupt ブロックと参照モデルを含みます。Async Interrupt ブロックは、参照モデルの Inport ブロック 1 と 2 に割り込み信号を渡す 2 つの Versa Module Eurocard (VME) 割り込みサービス ルーチン (ISR) を作成します。

シミュレートされた割り込みソースと次のいずれか 1 つのモデル要素間に Async Interrupt ブロックを置くことができます。

  • Function Call Subsystem

  • Task Sync ブロック

  • 関数呼び出し入力イベント用に構成された Stateflow チャート

  • 上記のモデル要素の 1 つに接続する Inport ブロックを含む参照モデル

このモデル例では、Async Interrupt ブロックは非同期イベント (関数呼び出しトリガー信号) Interrupt1Interrupt2Inport ブロック 1 と 2 を通じて参照モデルに渡します。

コード ジェネレーターは、VxWorks オペレーティング システムに合わせて調整されたコードを生成します。Async Interrupt ブロックを再構成し、別のアプリケーション実行時環境向けのコードを生成します。

参照モデルを開きます。参照モデルには、それぞれ Asynchronous Task Specification ブロックに接続されている、割り込みを受信する 2 つの Inport ブロック、Function-Call Subsystem の Count と Algorithm および Rate Transition ブロックが含まれます。Asynchronous Task Specification ブロックをルートレベルの Inport ブロックと組み合わせると、参照モデルは非同期の関数呼び出し入力を受信できます。このブロックを使用するには、次のようにします。

  1. Asynchronous Task Specification ブロックを、関数呼び出しトリガーを出力するルートレベルの Inport ブロックの出力端子に接続します。

  2. Inport ブロックの [関数呼び出しの出力] パラメーターを選択して、関数呼び出し信号を受け入れることを指定します。

  3. Asynchronous Task Specification ブロックのパラメーター ダイアログ ボックスで、Inport ブロックに関連付けられた非同期タスクにタスクの優先度を設定します。整数または [] を指定します。整数を指定する場合は、親モデルの Async Interrupt ブロックで開始された割り込みの優先順位と一致しなければなりません。[] を指定する場合、優先順位は一致しなくてかまいません。

優先順位の高い割り込み interrupt1Asynchronous Task Specification ブロックは Function-Call Subsystem Count に接続します。Count は、シンプルな割り込みサービス ルーチン (ISR) を表します。2 番目の Asynchronous Task Specification ブロックは、より多くの実体を含む Algorithm サブシステムに接続します。これは複数のブロックを含み、2 つの出力値を生成します。どちらのサブシステムも割り込みレベルで実行されます。

親モデルで Async Interrupt ブロックに対して指定された割り込みレベルごとに、ブロックは接続されたサブシステム、Task Sync ブロックまたはチャートを実行する VME ISR を生成します。

最上位モデルの例では、Async Interrupt ブロックは、割り込みベクトル オフセット 192 および 193 を使用して、VME 割り込み 1 および 2 について設定されています。割り込み 1 は Trigger サブシステム Count に結線されます。割り込み 2 は Trigger サブシステム Algorithm に結線されます。

Rate Transition ブロックが、さまざまなレートで動作する端子間でのデータ転送を処理します。2 つのインスタンスで、ブロックはデータ転送を保護します (データ転送がプリエンプトされ破損するのを防ぎます)。他のインスタンスでは、特別な動作は行われません。

データ転送の仮定

  • データ転送は、1 つの読み取りタスクと 1 つの書き込みタスクの間に行われる。

  • バイト単位の変数の読み取りと書き込み操作はアトミックである。

  • 2 つのタスクが相互作用する場合、一方だけがプリエンプトできる。

  • 周期的タスクの場合、速いレートのタスクの方が、遅いレートのタスクよりも優先順位が高くなる。速いレートのタスクは、遅いレートのタスクをプリエンプトする。

  • タスクは 1 つのプロセッサ上で実行される。タイム スライスは許可されない。

  • プロセスは、特にデータがタスク間で転送されているときはクラッシュまたは再起動しない。

モデルのシミュレーション

モデルのシミュレーションを実行します。既定の設定では、モデルはサンプル時間を異なる色で表示します。入力と出力の離散サンプル時間は、それぞれ赤と緑で表示されます。定数はマゼンタです。非同期割り込みは紫です。ハイブリッド (入力と出力のサンプル時間が異なる可能性がある) の Rate Transition ブロックは黄色で表示されます。

コードとレポートの生成

モデルのコードとコード生成レポートを生成します。Async Interrupt ブロックと Task Sync ブロックの生成コードは RTOS 例 (VxWorks) 用です。ただし、ブロックを変更して別の実行時環境用にコードを生成できます。

1. ビルドと検査プロセス用に一時フォルダーを作成します。

currentDir = pwd;
[~,cgDir] = rtwdemodir();

2. モデルを作成します。

slbuild('rtwdemo_async_mdlreftop');
### Starting serial model reference code generation build
Warning: Simulink Coder: The tornado.tlc target will be removed in a future release.

### Successfully updated the model reference code generation target for: rtwdemo_async_mdlrefbot
### Starting build procedure for: rtwdemo_async_mdlreftop
Warning: Simulink Coder: The tornado.tlc target will be removed in a future release.

### Successful completion of code generation for: rtwdemo_async_mdlreftop

Build Summary

Code generation targets built:

Model                    Action          Rebuild Reason                             
====================================================================================
rtwdemo_async_mdlrefbot  Code generated  rtwdemo_async_mdlrefbot.c does not exist.  

Top model targets built:

Model                    Action          Rebuild Reason                                    
===========================================================================================
rtwdemo_async_mdlreftop  Code generated  Code generation information file does not exist.  

2 of 2 models built (0 models already up to date)
Build duration: 0h 0m 52.643s

初期化コードのレビュー

生成されたソース ファイル rtwdemo_async_mdlreftop.c を開きます。初期化コードは、割り込み 1 では ISR isr_num1_vec192、割り込み 2 では ISR isr_num2_vec193 に接続して有効にします。

cfile = fullfile(cgDir, 'rtwdemo_async_mdlreftop_tornado_rtw', 'rtwdemo_async_mdlreftop.c');
rtwdemodbtype(cfile, ...
    'static void rtwdemo_async_mdlreftop_initialize(void)', ...
    '/* Model terminate function */', ... 
    1, 0);
static void rtwdemo_async_mdlreftop_initialize(void)
{
  /* Start for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

  /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
  /* Connect and enable ISR function: isr_num1_vec192 */
  if (intConnect(INUM_TO_IVEC(192), isr_num1_vec192, 0) != OK) {
    printf("intConnect failed for ISR 1.\n");
  }

  sysIntEnable(1);

  /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
  /* Connect and enable ISR function: isr_num2_vec193 */
  if (intConnect(INUM_TO_IVEC(193), isr_num2_vec193, 0) != OK) {
    printf("intConnect failed for ISR 2.\n");
  }

  sysIntEnable(2);

  /* End of Start for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

  /* SystemInitialize for ModelReference: '<Root>/Model' incorporates:
   *  Inport: '<Root>/In1_60hz'
   *  Inport: '<Root>/In2_60_hz'
   *  Inport: '<Root>/In3_60hz'
   *  Outport: '<Root>/Out1'
   *  Outport: '<Root>/Out2'
   *  Outport: '<Root>/Out3'
   */
  rtwdemo_async_mdlrefbot_Init(&rtwdemo_async_mdlreftop_Y.Out1);
  rtwdemo_async_mdlrefbot_Enable();
}

ISR コードのレビュー

生成されたソース ファイル rtwdemo_async_mdlreftop.c で、ISR isr_num1_vec192 および isr_num2_vec293 のコードをレビューします。各 ISR は次を行います。

  • 割り込みを無効にする。

  • 浮動小数点コンテキストを保存する。

  • 割り込みを受信する参照モデル Inport ブロックに接続されているサブシステムで生成されたコードを呼び出す。

  • 浮動小数点コンテキストを復元する。

  • 割り込みを再度有効にする。

cfile = fullfile(cgDir, 'rtwdemo_async_mdlreftop_tornado_rtw', 'rtwdemo_async_mdlreftop.c');
rtwdemodbtype(cfile, ...
    'void isr_num1_vec192(void)', ...
    'time_T rt_SimUpdateDiscreteEvents', ... 
    1, 0);
void isr_num1_vec192(void)
{
  int_T lock;
  FP_CONTEXT context;

  /* disable interrupts (system is configured as non-preemptive) */
  lock = intLock();

  /* save floating point context */
  fppSave(&context);

  /* Call the system: '<Root>/Model' */
  {
    /* S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

    /* ModelReference: '<Root>/Model' incorporates:
     *  Inport: '<Root>/In1_60hz'
     *  Inport: '<Root>/In2_60_hz'
     *  Inport: '<Root>/In3_60hz'
     *  Outport: '<Root>/Out1'
     *  Outport: '<Root>/Out2'
     *  Outport: '<Root>/Out3'
     */
    rtwdemo_async_mdlrefbot_Interrupt1(&rtwdemo_async_mdlreftop_Y.Out1);

    /* End of Outputs for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */
  }

  /* restore floating point context */
  fppRestore(&context);

  /* re-enable interrupts */
  intUnlock(lock);
}

/* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
void isr_num2_vec193(void)
{
  FP_CONTEXT context;

  /* save floating point context */
  fppSave(&context);

  /* Call the system: '<Root>/Model' */
  {
    /* S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

    /* ModelReference: '<Root>/Model' incorporates:
     *  Inport: '<Root>/In1_60hz'
     *  Inport: '<Root>/In2_60_hz'
     *  Inport: '<Root>/In3_60hz'
     *  Outport: '<Root>/Out1'
     *  Outport: '<Root>/Out2'
     *  Outport: '<Root>/Out3'
     */
    rtwdemo_async_mdlrefbot_Interrupt2();

    /* End of Outputs for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */
  }

  /* restore floating point context */
  fppRestore(&context);
}

タスク終了コードのレビュー

Task Sync ブロックは、次の終了コードを生成します。

cfile = fullfile(cgDir, 'rtwdemo_async_mdlreftop_tornado_rtw', 'rtwdemo_async_mdlreftop.c');
rtwdemodbtype(cfile, ...
    'static void rtwdemo_async_mdlreftop_terminate(void)', ...
    '/*========================================================================*', ... 
    1, 0);
static void rtwdemo_async_mdlreftop_terminate(void)
{
  /* Terminate for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */

  /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
  /* Disable interrupt for ISR system: isr_num1_vec192 */
  sysIntDisable(1);

  /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
  /* Disable interrupt for ISR system: isr_num2_vec193 */
  sysIntDisable(2);

  /* End of Terminate for S-Function (vxinterrupt1): '<Root>/Async Interrupt' */
}

関連情報

bdclose('rtwdemo_async_mdlreftop');
rtwdemoclean;
cd(currentDir)

関連するトピック