μT-Kernel/SMの割込み管理機能は、外部割込みの禁止や許可、割込み禁止状態の取得、割込みコントローラの制御などを行うための機能である。
割込み関係はハードウェア依存度が高く、システムごとに異なっているため共通化することが難しい。下記を標準仕様として定めるが、システムによってはこの通りに実装することが難しい場合がある。できる限り標準仕様に合わせた実装を求めるが、実装不可能なものは実装しなくてもよい。標準仕様とは別の機能を追加することも許されるが、その場合は関数名などは標準仕様と異なるものでなければならない。ただし、DI, EI, isDI は標準仕様にしたがって、必ず実装しなければならない。
割込み管理機能は、ライブラリ関数またはC言語のマクロで提供され、これらはタスク独立部およびディスパッチ禁止・割込み禁止の状態から呼び出すことができる。
CPU内の外部割込みフラグや割込みマスクレベルを設定する。一般的には、割込みコントローラの制御は行わない。
DI ではすべての外部割込みを禁止し、EI で許可する。DI を発行してから、EI を発行するまで、外部割込み禁止の状態となる。この状態の間は、他の処理に割り込まれることはなく、割込みによるディスパッチも発生しないので、不可分に処理を実行することができる。
CPU割込み制御のAPIおよび外部割込み禁止の状態には以下の制約がある。
CPU割込み制御のAPIは、CPU内の外部割込みフラグや割込みマスクレベルを直接設定するC言語のマクロとして実装される。このため、ハードウェアを制御できる保護レベルでなければ実行できない。具体的な保護レベルは実装依存である。
CPU割込み制御のAPIは、CPU内の外部割込みフラグや割込みマスクレベルを設定するのみである。このため、一部の実装を除き、一般にはこれらのAPIを実行しても遅延ディスパッチは起こらない。
外部割込み禁止の状態では、使用できるAPIが制限される。待ち状態に入るAPIを実行することはできず、E_CTXのエラーとなるべきであるが、この場合のエラーチェックは実装依存である。μT-Kernel/SMの割込み管理機能およびI/Oポートアクセスサポート機能のAPIは、外部割込み禁止の状態でも発行可能である。これら以外のAPIが外部割込み禁止の状態で使用可能かどうかは、実装依存である。
外部割込み禁止の状態では、システムタイマの割込みも禁止される。このため、タイムアウトやタイムイベントハンドラの処理なども実行されない。
補足事項 | |
---|---|
CPU割込み制御のAPIは、デバイスドライバなどにおいて、ハードウェアやそれに近い部分の制御を行う際に、外部割込みを一時的に禁止して不可分な処理を実行するために使用することを想定している。しかし、外部割込みを禁止するとシステムの応答性が低下し、リアルタイム性能にも影響を与えるため、できるだけ速やかに処理を行い、外部割込み禁止の状態を抜ける必要がある。 DIによる外部割込み禁止の状態は、タスク独立部に近い状態であり、この間にディスパッチを起こすようなAPI(例:tk_wup_tsk)を発行した場合にも、ディスパッチは起こらない。また、その後、外部割込み許可の状態に戻すためにEIを発行しても、一般にはEIにおける遅延ディスパッチが起こらない(一部の実装を除く)。その結果として、EIの実行後も、高優先度の実行可能状態のタスクがあるにも関わらず、低優先度のタスクが実行状態を続けるという不正な状態になることがある。 DIとEIの間にディスパッチを起こすようなAPIを発行する場合には、上記のような不正な状態になるのを防ぐために、外部割込み禁止の区間をtk_dis_dspとtk_ena_dspで挟むことを推奨する。すなわち、tk_dis_dsp→DI→ディスパッチを起こすAPI→EI→tk_ena_dspの順にAPIを発行する。この場合、DIとEIの間は割込みもディスパッチも禁止、tk_dis_dspとtk_ena_dspの間はディスパッチのみ禁止となるが、最後のtk_ena_dspで遅延ディスパッチが起こるため、その時点で上記のような不正な状態は解消する。このようにしてAPIを発行することにより、実装に依存しない動作が可能である。 |
なし
CPU内の外部割込みフラグを制御し、intsts
の状態に戻す。すなわち、これ以前に実行された DI(intsts) で割込みを禁止する前の状態に戻す。
DI(intsts) の実行前の状態が外部割込み許可であった場合には、その後の EI(intsts) の実行により、再度外部割込みを許可した状態となる。一方、DI(intsts) で割込みを禁止する以前から割込み禁止状態であった場合には、EI(intsts) を実行しても割込みは許可されない。ただし、intsts
として0を指定した場合は、CPU内の外部割込みフラグが割込み許可状態となる。
intsts
は、DI で保存した値または0のいずれかでなければならない。それ以外の値を指定した場合の動作は保証されない。
実行効率を重視しオーバーヘッドを最小限とするため、一般に本APIはアセンブラやマクロで実装される。また、CPU内の外部割込みフラグを制御するだけであり、それ以外の処理は行わず、エラー情報も返さない。したがって、一部の実装を除き、一般には本APIを実行しても遅延ディスパッチは起こらない。
なし
なし
CPU内の割込みマスクレベルを設定し、level
よりも低い割込み優先度を持つ割込みを禁止する。逆に、level
と同一またはより高い割込み優先度を持つ割込みは許可される。
level
に INTLEVEL_DI を指定した場合は、すべての優先度の外部割込みを禁止した状態となるように割込みコントローラ内の割込みマスクレベルを設定する。これは一般に、DIを実行した後の状態と同じである。
また、level
に INTLEVEL_EI を指定した場合は、すべての優先度の外部割込みを許可した状態となるように割込みコントローラ内の割込みマスクレベルを設定する。これは一般に、EI(0)を実行した後の状態と同じである。
本APIの実行によって割込みを禁止している間は、割込みハンドラ実行中と同じように、割込み禁止が解除されるまでディスパッチを遅延する場合がある。
指定可能なlevel
の範囲、INTLEVEL_DI
の具体値は実装定義である。また、割込み優先度の高低と割込みレベルの数値の大小との関係も実装定義である。一般に、これらの仕様はCPUのアーキテクチャに依存して決められる。
実行効率を重視しオーバーヘッドを最小限とするため、一般に本APIはアセンブラやマクロで実装される。また、CPU内の外部割込みフラグを制御するだけであり、それ以外の処理は行わず、エラー情報も返さない。したがって、一部の実装を除き、一般には本APIを実行しても遅延ディスパッチは起こらない。
「割込みマスクレベル」とは、割込みを許可(マスク)する外部割込み優先度(割込みレベル)の下限を示す値である。割込みマスクレベルと同一またはより高い割込み優先度を持つ外部割込みが許可される。
本APIはCPU内の割込みマスクレベルを設定する機能であり、割込みコントローラ内の割込みマスクレベルを設定する SetCtrlIntLevel とほぼ同一の機能である。ただし、前者は DI, EI で設定した割込み許可・禁止状態に影響を与えるのに対して、後者はそれらの状態とは無関係である点が異なる。
本APIでは、それ以前の状態とは無関係に、単純にCPU内の割込みマスクレベルの設定を行うだけである。本APIの実行により、禁止される割込みの範囲が増える場合と、減る場合の両方があるので注意されたい。
割込みコントローラを制御する。一般的には、CPUの割込みフラグに対しては何もしない。
なし
割込み番号 intno
の割込みを許可する。割込み優先度レベルを指定可能なシステムでは、level
により割込み優先度レベルを指定する。
intno
に指定可能な割込み番号は、tk_def_int で指定可能なもののうち、割り込みコントローラによって管理される割込みの番号に限定される。不正な intno
を指定した場合の動作は保証されない。
level
あり、または level
なしの、いずれか一方を提供する。
本APIでは、割込み関連機能の他のAPIと同様に、エラーのチェックは行わない。
なし
割込み番号 intno
の割込みを禁止する。一般的には、割込み禁止中の割込みはペンディングされ、EnableInt により許可した時に割込みが発生する。割込み禁止中に発生した割込みを無効にしたい場合は、ClearInt を行う必要がある。
intno
に指定可能な割込み番号は、tk_def_int で指定可能なもののうち、割り込みコントローラによって管理される割込みの番号に限定される。不正な intno
を指定した場合の動作は保証されない。
本APIでは、割込み関連機能の他のAPIと同様に、エラーのチェックは行わない。
なし
intno
の割込みが発生していればクリアする。
intno
に指定可能な割込み番号は、tk_def_int で指定可能なもののうち、割り込みコントローラによって管理される割込みの番号に限定される。不正な intno
を指定した場合の動作は保証されない。
本APIでは、実行効率を重視しオーバーヘッドを最小限とするために、エラーのチェックは行わない。
なし
割込みコントローラにEOI(End Of Interrupt)を発行する。intno
は EOI 発行対象の割込みでなければならない。一般的には、割込みハンドラの最後で実行する必要がある。
intno
に指定可能な割込み番号は、tk_def_int で指定可能なもののうち、割り込みコントローラによって管理される割込みの番号に限定される。不正な intno
を指定した場合の動作は保証されない。
本APIでは、実行効率を重視しオーバーヘッドを最小限とするために、エラーのチェックは行わない。
なし
割込み番号 intno
の割込みが発生しているか調べる。intno
の割込みが発生していれば TRUE(0以外の値)、発生していなければ FALSE を返す。
なし
割込み番号 intno
で指定した割込みを mode
で指定したモードに設定する。
intno
に指定可能な割込み番号は、tk_def_int で指定可能なもののうち、割り込みコントローラによって管理される割込みの番号に限定される。不正な intno
を指定した場合の動作は保証されない。
設定可能な機能や mode
の指定方法は実装依存である。以下は、設定可能な機能の一例である。
mode := (IM_LEVEL || IM_EDGE) | (IM_HI || IM_LOW)
#define IM_LEVEL 0x0002 /* レベルトリガ */ #define IM_EDGE 0x0000 /* エッジトリガ */ #define IM_HI 0x0000 /* Hレベル/立ち上がりエッジで割込み */ #define IM_LOW 0x0001 /* Lレベル/立ち下がりエッジで割込み */
不正な mode
を指定した場合の動作は保証されない。
本APIでは、割込み関連機能の他のAPIと同様に、エラーのチェックは行わない。
なし
以下のサービスプロファイルが有効に設定されている場合に限り、本APIはサポートされる。
割込みコントローラ内の割込みマスクレベルを設定し、level
よりも低い割込み優先度を持つ割込みを禁止する。逆に、level
と同一またはより高い割込み優先度を持つ割込みは許可される。
level
に INTLEVEL_DI を指定した場合は、すべての優先度の外部割込みを禁止した状態となるように割込みコントローラ内の割込みマスクレベルを設定する。
また、level
に INTLEVEL_EI を指定した場合は、すべての優先度の外部割込みを許可した状態となるように割込みコントローラ内の割込みマスクレベルを設定する。
本APIの実行によって割込みを禁止している間は、割込みハンドラ実行中と同じように、割込み禁止が解除されるまでディスパッチを遅延する場合がある。
指定可能なlevel
の範囲、INTLEVEL_DI
の具体値は実装定義である。また、割込み優先度の高低と割込みレベルの数値の大小との関係も実装定義である。一般に、これらの仕様はCPUのアーキテクチャに依存して決められる。
SetCpuIntLevel の補足事項を参照のこと
本APIでは、それ以前の状態とは無関係に、単純に割込みコントローラ内のマスクレベルの設定を行うだけである。本APIの実行により、禁止される割込みの範囲が増える場合と、減る場合の両方があるので注意されたい。
本APIでは、実行効率を重視しオーバーヘッドを最小限とするために、エラーのチェックは行わない。
なし
なし
以下のサービスプロファイルが有効に設定されている場合に限り、本APIはサポートされる。
SetCpuIntLevel の補足事項を参照のこと