デバイスドライバをはじめ、デバイスにかかわるお困りごとの際はお気軽にお問い合わせください。
【 デバドラ講座31 : 割り込みサービスルーチン(ISR)の処理 】
ISRの処理は非常に簡潔です。まず、デバイスから発生した割り込みが自分の管理するデバイスからであるかを確認します。自分の管理するデバイスからの割り込みだった場合、最小限の情報を保存して、DpcForIsrに割り込み処理を要求します。ISRはDIRQレベルで処理が実行されるため、実行可能な関数が制限されています。例えば、IoCompleteRequest関数はISRでは実行できません。ISRは非ページプールメモリにのみアクセス可能です。
割り込みが発生すると、ISRが呼ばれます。IoConnectInterrupt関数から得られる割り込みオブジェクトとServiceContextを引数としてISRに渡されます。ISRは呼び出されると次の処理が行われます。
- 割り込みの識別
- 割り込みの応答
- 割り込み情報の保存
- DpcForIsrの要求
- カスタムDPCの要求
- ISRの完了
ISRが呼び出されると、ドライバは割り込み通知を行ったデバイスが、自分の管理するデバイスかどうかを識別します。自分の管理外のデバイスからの割り込みであった場合、ISRはFALSE値を返します。割り込みが共有される場合、I/Oマネージャは同じ割り込みラインに存在するドライバのISRをTRUE値が返ってくるまで呼び出し続けます。自分が管理するデバイスからの割り込みだった場合、ISRは処理を継続します。
ISRが割り込みの認識を行った後、同じデバイスからの割り込みが発生しないように処理を行う必要があります。通常、デバイスレジスタのビット数を操作することにより、ドライバはデバイスの割り込みの発生を禁止します。この処理を行うことによって、ISRは別の割り込みに割り込まれることはありません。また、割り込み要因のクリア方法はデバイスのハードウェア仕様書に書かれています。
割り込みの応答処理後、ISRはDPCルーチンで処理を完了させるために必要なコンテキスト情報を収集します。収集した情報はServiceContext引数に保存します。ServiceContextはデバイスオブジェクトのデバイスエクステンションへのポインタであることを覚えておく必要があります。また、このコンテキストはIoRequestDpc関数の実行の際に引数として渡すことも可能です。
割り込み情報の保存後、ISRはDpcForIsrの処理を要求するためにIoRequestDpc関数を呼び出します。この関数はDpcForIsrのDPCオブジェクトはキューに登録します。Context引数はISR内で設定されていない場合、NULLを指定します。また、Context値は非ページプールメモリに存在する必要があります。カスタムDPCが存在する場合、カスタムDPCのDPCオブジェクトをキューに登録します。カスタムDPCのDPCオブジェクトはKeInsertQueueDpc関数によってキューに登録されます。
以上の処理の終了後、割り込みが自分の管理するデバイスからであったことを知らせるためにTRUEを返しISRの処理は完了します。ISRの処理の流れを図1に示します。
参考資料
- 「NTドライバプログラミング」
- Peter G. Viscarola、W. Anthony Mason著 久保雅俊、三浦秀朗訳 サイエンスパーク株式会社 監修
- 「WDMデバイスドライバプログラミング完全ガイド」上
- Edword N. Dekker, Jpseph M. Newcomer著 株式会社クイック訳