第12章  割り込み管理機能


本章では,RI600PXが提供している割り込み管理機能について解説しています。

12.1 割り込みの種類

割り込みは,カーネル管理割り込みとカーネル管理外割り込みに分類されます。

- カーネル管理割り込み
カーネル割込マスクレベルより割り込み優先レベルが低い割り込みをカーネル管理割り込みといいます。
カーネル管理割り込みハンドラでは,サービス・コールを呼び出すことができます。
サービス・コール処理中にカーネル管理割り込みが発生した場合,カーネル管理割り込みを受け付け可能となるまで割り込み受理が遅延されます。




- カーネル管理外割り込み
カーネル割込マスクレベルより割り込み優先レベルが高い割り込みをカーネル管理外割り込みといいます。ノンマスカブル割り込みは,カーネル管理外割り込みの扱いとなります。
カーネル管理外割り込みハンドラでは,サービス・コールを呼び出してはなりません。
サービス・コール処理中にカーネル管理外割り込みが発生した場合でも,直ちに割り込み受理が受理されるため,カーネル処理に依存しない高速な割り込み応答が可能です。




備考 カーネル割り込みマスクレベルは,システム情報(system)カーネル割り込みマスクレベル(system_IPL)で定義します。

12.2 RX MCUの高速割り込み

RX MCUは「高速割り込み」機能をサポートしています。ひとつの割り込み要因だけを高速割り込みとすることができます。高速割り込みは,割り込み優先レベル15として扱われます。高速割り込みを使用する場合は,割り込み優先レベル15の割り込み要因をひとつに限定する必要があります。

RI600PXで高速割り込みを使用する場合は,その割り込みはカーネル管理外割り込みとして扱う必要があります。つまり,カーネル割り込みマスクレベル(system.system_IPL)は,14以下に設定する必要があります。

システム・コンフィギュレーション・ファイルで高速割り込みを定義する際には,os_intにNOを指定し,さらにpragma_switchにFを指定する必要があります。

また,ブート処理関数(PowerON_Reset_PC( ))でRX-MCUのFINTVレジスタをそのハンドラの開始アドレスに初期化する必要があります。

12.3 CPU例外の扱い

以下のCPU例外はカーネル管理外割り込みの扱いとなります。

- 無条件トラップ(INT,BRK命令)
なお,INT #1〜#8はRI600PXで予約されています。


- 未定義命令例外

- 特権命令例外

- 浮動小数点例外

一方,アクセス例外ハンドラはカーネル管理割り込みの扱いとなります。

12.4 基本クロック用タイマ割り込み

時間管理機能は,一定周期で発生する基本クロック用タイマ割り込みを利用して実現されています。基本クロック用タイマ割り込みが発生した際には,RI600PXが提供している時間管理用割り込みハンドラが起動し,時間に関連した処理(システム時刻の更新,タスクの遅延起床/タイムアウト,周期ハンドラの起動など)が実行されます。

12.5 多重割り込み

RI600PXでは,割り込みハンドラ内で再び割り込みが発生することを“多重割り込み”と呼んでいます。

多重割り込みを許可するかどうかは,可変ベクタの割り込みハンドラごとに設定できます。詳細は,「20.21 可変ベクタ情報(interrupt_vector[])」を参照してください。

12.6 割り込みハンドラ

割り込みハンドラは,割り込みが発生した際に起動される割り込み処理専用ルーチンです。

なお,RI600PXでは,割り込みハンドラを“タスクとは独立したもの(非タスク)”として位置づけています。このため,割り込みが発生した際には,システム内で最高優先度を持つタスクが処理を実行中であっても,その処理は中断され,割り込みハンドラに制御が移ります。

12.6.1 割り込みハンドラの基本型

以下に,割り込みハンドラを記述する場合の基本型を示します。

 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 
 void Inthdr1 ( void )
 {
         ............
         ............
 
         return;                         /*割り込みハンドラの終了*/
 }


備考 ハンドラ関数のプロトタイプ宣言および#pragma interruptディレクテブは,cfg600pxがkernel_id.hに出力します。

- スタック
割り込みハンドラは,システム・スタックを使用します。


- サービス・コールの発行
RI600PXでは,割り込みハンドラを“タスクとは独立したもの(非タスク)”として位置づけています。
カーネル管理割り込みハンドラでは,“発行有効範囲”が“非タスク”のサービスコールを発行可能です。なお,カーネル管理外割り込みハンドラでは,サービス・コールを呼び出してはなりません。



備考 RI600PXでは,カーネル管理割り込みハンドラ内の処理を高速に終了させる目的から,カーネル管理割り込みハンドラ内の処理が完了するまでの間,スケジューラの起動を遅延しています。したがって,カーネル管理割り込みハンドラ内でディスパッチ処理(タスクのスケジューリング処理)を伴うサービス・コール(isig_semiset_flgなど)が発行された際には,キュー操作などといった処理が行われるだけであり,実際のディスパッチ処理の実行はカーネル管理割り込みハンドラが終了するまで遅延され,一括して行うようにしています。

- 処理開始時のPSW

表12−1  割り込みハンドラ処理開始時のPSW

ビット



備考

I

登録時にpragma_switchに“E”を指定した場合は1,そうでない場合は0

IPL

割り込み:当該割り込み優先レベル

CPU例外:例外発生前と同じ

処理開始時より下げてはなりません。

PM

0

スーパバイザ・モード

U

0

システム・スタック

C, Z, S, O

不定

その他

0



12.6.2 割り込みハンドラの登録

RI600PXでは,割り込みハンドラの静的な登録のみサポートしています。処理プログラムからサービス・コールを発行して動的に登録することはできません。

割り込みハンドラの静的登録とは,システム・コンフィギュレーション・ファイルで静的API“interrupt_vector[]”(可変ベクタ割り込みハンドラの登録),および“interrupt_fvector[]”(固定ベクタ/例外ベクタ割り込みハンドラの登録)を使用して割り込みハンドラを定義することをいいます。

静的API“interrupt_vector[]”の詳細は,「20.21 可変ベクタ情報(interrupt_vector[])」を,静的API“interrupt_fvector[]”の詳細は,「20.22 固定ベクタ/例外ベクタ情報(interrupt_fvector[])」を参照してください。

12.7 処理プログラム内におけるマスカブル割り込み受け付け状態

RX MCUのマスカブル割り込みの受け付け状態は,PSW.I,PSW.IPLの値で変わります。詳細はハードウエアのマニュアルを参照してください。

初期状態は処理プログラムごとに決まっています。その詳細は,表12−2を参照してください。

表12−2  処理プログラム起動時のマスカブル割り込み受け付け状態

処理プログラム名

PSW.I

PSW.IPL

タスク

1

0

タスク例外処理ルーチン

1

タスク例外処理ルーチン起動直前のタスク本体と同じ

周期ハンドラ,

アラーム・ハンドラ

1

割り込みハンドラ

登録時にpragma_switchに“E”を指定した場合は1,そうでない場合は0

割り込み:当該割り込み優先レベル

CPU例外:例外発生前と同じ



12.8 マスカブル割り込みの受け付け禁止

マスカブル割り込みの受け付け禁止には,以下の方法があります。

- loc_cpuiloc_cpuを使用してCPUロック状態にする

- chg_imsichg_imsを使用してPSW.IPLを変更する

- PSW.I,PSW.IPLを直接変更する(ハンドラ限定)

12.8.1 loc_cpu, iloc_cpuを使用してCPUロック状態にする

CPUロック状態では,PSW.IPLはカーネル割り込みマスクレベル(system_IPL)となります。つまり,CPUロック状態で禁止される割り込みは,カーネル管理割り込みのみです。

また,CPUロック状態では使用可能なサービス・コールに制限があります。詳細は,「11.4 CPUロック状態への移行と解除」を参照してください。

12.8.2 chg_ims,ichg_imsを使用してPSW.IPLを変更する

chg_imsichg_imsでは,PSW.IPLを任意の値に変更することができます。

タスクでchg_imsを用いてPSW.IPLを0以外に変更すると,同時にディスパッチ禁止状態に移行し,chg_imsを用いてPSW.IPLを0に戻すと,同時にディスパッチ許可状態に戻ります。

タスクがchg_imsによってPSW.IPLを0以外に変更している間は,ena_dspを呼び出さないようにしてください。ena_dspを呼び出すと,その時点でディスパッチ許可状態に遷移します。タスク・ディスパッチが発生すると,PSWはディスパッチ先のタスクの状態に更新されるので,意図せずにIPL値が下がってしまうことがあります。

ハンドラでは,PSW.IPLを処理開始時より下げてはなりません。

12.8.3 PSW.I, PSW.IPLを直接変更する(ハンドラ限定)

ハンドラでは,PSW.I,PSW.IPLを直接変更することができます。この方法は,ichg_imsよりも高速です。

ハンドラでは,PSW.IPLを処理開始時より下げてはなりません。

なお,コンパイラではPSWを操作する以下の組み込み関数を用意しています。組み込み関数の詳細は,「CubeSuite+ RXコーディング編」を参照してください。

- set_ipl() :PSWレジスタのIPLビットの変更

- get_ipl() :PSWレジスタのIPLビットの参照

- set_psw() :PSWレジスタの設定

- get_psw() :PSWレジスタの参照