Main Content

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

割り込みサービス ルーチンの生成

RTOS 例 (VxWorks®) の VME 割り込みレベルに関連付けられている割り込みサービス ルーチン (ISR) を生成するには、Async Interrupt ブロックを使用します。Async Interrupt ブロックは、指定した割り込みレベルを有効にし、接続されている Function-Call Subsystem を呼び出す ISR をインストールします。

シミュレーション時に Async Interrupt ブロックを使うこともできます。これによって、入力端子を有効にして、シミュレーション対象の割り込みソースに接続できます。

メモ

この節に示されているオペレーティング システムの統合手法では、vxlib1 ライブラリの 1 つ以上のブロックを使用します。これらのブロックは、ターゲット環境でカスタム ブロックを開発するのに役立つ開始点の例を提供します。

Async Interrupt ブロックの接続

ISR を生成するには、Async Interrupt ブロックの出力を以下の制御入力に接続します。

  • Function-Call Subsystem

  • Task Sync ブロックの入力

  • 関数呼び出し入力イベントについて設定された Stateflow® チャートへの入力

次の図は、2 つの割り込みソースを有効にするように設定された Async Interrupt ブロックを示しています。出力 (信号幅 2) は 2 つの Function-Call Subsystem に接続されます。

要件と制限

次の要件と制限事項があります。

  • Async Interrupt ブロックは VME 割り込みの 1 から 7 までをサポートします。

  • Async Interrupt ブロックでは、次に示す RTOS 例 (VxWorks) のシステム呼び出しを使用します。

    • sysIntEnable

    • sysIntDisable

    • intConnect

    • intLock

    • intUnlock

    • tickGet

パフォーマンスについて

割り込みレベルで大規模なサブシステムが実行されると、システム内で優先度が同じか、低い割り込みの割り込み応答時間に大きく影響します。一般的に、ISR の保持時間はできるだけ短く指定することを推奨します。ブロック数が少ない Function-Call Subsystem のみを Async Interrupt ブロックに接続します。

大きなサブシステムの場合は Task Sync ブロックを使用して Function-Call Subsystem の実行を RTOS タスクと同期させることをお勧めします。Task Sync ブロックは Async Interrupt ブロックと Function-Call Subsystem 間に配置されます。Async Interrupt ブロックは Task Sync ブロックを ISR としてインストールします。ISR は、同期セマフォをタスクにリリースし (関数 semGive を実行し)、割り込みレベルからすぐに返されます。タスクは、スケジューリングされ、RTOS 例 (VxWorks) によって実行されます。詳細については、RTOS タスクの例の発生と同期を参照してください。

シミュレーションおよびコード生成時の Async Interrupt ブロックの使用

この節では、ISR を含むリアルタイム システムの開発と実装に対する "双対モデル" アプローチについて説明します。このアプローチでは、プラントとシミュレーションのコントローラーを含むモデルと、コード生成のコントローラーのみを含む別のモデルを作成します。Simulink® ライブラリを使用して、2 つのモデルの変更を同時に実装します。次の図は、ライブラリ内のプラントまたはコントローラーの変更がモデルにどのように伝播されるかを示しています。

シミュレーションおよびコード生成のための Async Interrupt ブロックの双対モデルの使用

"単一モデル" アプローチも使用できます。このアプローチでは、モデルの Plant コンポーネントはシミュレーション時にのみアクティブです。コード生成中は、Plant コンポーネントは効率的にシステム外に切り替えられ、コードはモデルの割り込みブロックおよびコントローラー部に対してのみ生成されます。このアプローチの例は、rtwdemo_async モデルを参照してください。

双対モデル アプローチ:シミュレーション

以下のブロック線図は、モデリングに対する双対モデル アプローチを説明する単純なモデルを示しています。シミュレーション時、Pulse Generator ブロックによってシミュレートされた割り込み信号が送られます。

シミュレートされた割り込み信号は、Async Interrupt ブロックの入力端子を使用して送られます。ブロックは、シミュレートされた割り込みを受信すると、接続されているサブシステムを呼び出します。

シミュレーション中、Async Interrupt ブロックの出力に接続されたサブシステムは、RTOS 例 (VxWorks) の優先度の順序に従って実行されます。2 つ以上の割り込み信号が同時に発生するイベントでは、Async Interrupt ブロックによって、割り込みレベル (レベル 7 が最高の優先順位) で指定された順序で下流のシステムが実行されます。最初の入力要素は最初の出力要素にマッピングされます。

シミュレーション時にシミュレーション入力を有効にせずに Async Interrupt ブロックを使用することもできます。このような場合、Async Interrupt ブロックは、モデルの基本レートを継承し、RTOS で優先度の順序で接続されているサブシステムを呼び出します (この場合、Async Interrupt ブロックは、すべての入力が 1 を同時に受信した場合と同様に動作します)。

双対モデル アプローチ:コード生成

サンプル モデルの生成コードで、次の内容が実行されます。

  • Ground ブロックは Environment Controller ブロックに入力信号を送ります。

  • Async Interrupt ブロックはそのシミュレーション入力を使用しません。

Ground ブロックは、Environment Controller ブロックの制御入力を駆動し、その信号パスについてコードが生成されないようにします。コード ジェネレーターは、Environment Controller ブロックへのシミュレーション制御入力を駆動するブロックのコードについては、そのパスがコード生成中に選択されないため、生成しません。ただし、Environment Controller ブロックへのシミュレーション入力の駆動ブロックのサンプル時間は、生成されたコードでサポートされるサンプル時間に影響を与えます。生成されたコードに不要なサンプル時間が含まれないようにするには、生成コードの対象のモデルでシミュレーション入力を駆動するブロックのサンプル時間を使用します。

スタンドアロン関数は ISR としてインストールされます。このときの割り込みベクトル テーブルは次のとおりです。

オフセット 
192&isr_num1_vec192()
193&isr_num2_vec193()

以下の図のように Async Interrupt ブロック パラメーターが設定されているという前提で、このモデルから生成されたコードについて検討します。

初期化コード

生成されたコードでは、Async Interrupt ブロックは、割り込みサービス ルーチンとして Subsystem ブロックにコードをインストールします。IRQ1 および IRQ2 の割り込みベクトルは、[VME interrupt vector offset(s)] パラメーターの指定に従い、割り込みベクトル テーブルのベースに関連する場所 192 および 193 に格納されます。

ISR をインストールする場合、2 つの RTOS (VxWorks) 呼び出し (関数 int_connect および関数 sysInt_Enable) が必要です。Async Interrupt ブロックは、次のコード例で示すように、関数 model_initialize にこれらの呼び出しを挿入します。

/* 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);

割り込みを生成するハードウェアは、Async Interrupt ブロックによっては構成されません。通常、割り込みソースは VME I/O ボードで、特定のイベントの割り込みを生成します (A/D 変換の終了など)。VME 割り込みのレベルとベクトルは、レジスタで設定するか、ボード上のジャンパーを使用して設定します。レジスタを設定するか、ボード上の割り込み生成を有効にするには、ユーザー記述デバイス ドライバー (S-Function) の mdlStart ルーチンを使用します。Async Interrupt ブロック ダイアログで指定された割り込みレベルとベクトルは、I/O ボードで設定されたレベルとベクトルと一致しなければなりません。

生成された ISR コード

RTOS (VxWorks) で実際に生成された IRQ1 の ISR を以下に示します。

/* VxWorks Interrupt Block: '<Root>/Async Interrupt' */

void isr_num1_vec192(void)
{
  int_T lock;
  FP_CONTEXT context;

   /* Use tickGet() as a portable tick counter example. 
      A much higher resolution can be achieved with a 
      hardware counter */
   Async_Code_M->Timing.clockTick2 = tickGet();

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

   /* save floating point context */
   fppSave(&context);
 
   /* Call the system: <Root>/Subsystem A */
   Count(0, 0);

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

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

ISR には、次のような注目すべき特徴があります。

  • ISR は、[Preemption Flag] パラメーターの設定に従い、ロックされます。すなわち、さらに優先度の高い割り込みによってプリエンプトされません。ISR をロックおよびロックを解除するには、RTOS 例 (VxWorks) の関数 int_lock と関数 int_unlock を使用します。

  • 接続されたサブシステム Count は、ISR 内から呼び出されます。

  • 関数 Count は、アルゴリズム (モデル) コードを実行します。したがって、浮動小数点コンテキストは、関数 Count の呼び出し全体で保存および復元されます。

  • ISR では、システム内の他の周期的な基本レートまたはサブレート カウンターとは異なる独自の絶対時間カウンターを保持します。タイミング データは、絶対時間または経過時間を必要とする ISR 内で実行されたブロックを使用するために維持されます。

    詳細については、非同期タスクにおけるタイマーを参照してください。

モデル終了コード

次のように、モデルの終了関数によって RTOS (VxWorks) で割り込みが無効になります。

/* Model terminate function */
void Async_Code_terminate(void)
{
   /* 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);
}

関連するトピック