SPB 接続周辺機器からの割り込み
PCI などのバスとは異なり、I2C や SPI などの単純な周辺機器バス (SPB) は、周辺機器からプロセッサに割り込み要求を伝達するための標準化されたバス固有の手段は提供されません。 代わりに、SPB に接続された周辺機器は、SPB と SPB コントローラー両方の外側にある別のハードウェア パスを介して割り込みを通知します。 この割り込みパスの詳細は、ハードウェア プラットフォームによって異なる傾向がありますが、Windows では、SPB に接続された周辺機器のドライバーからこれらの詳細を非表示にして、ドライバーがさまざまなハードウェア プラットフォームで動作できるようにします。
通常、SPB 接続周辺機器からの割り込み要求の行は、汎用 I/O (GPIO) コントローラーのピンに接続され、GPIO コントローラーはデバイスからプロセッサに割り込みを中継します。 詳しくは、「GPIO の割り込み」をご覧ください。
周辺機器ドライバーは、この GPIO 割り込みを抽象 Windows 割り込みリソース (CmResourceTypeInterrupt) として取得し、ドライバーの割り込みサービス ルーチン (ISR) に割り込みを接続します。 割り込みリソースの抽象化により、ドライバーからの割り込みのプラットフォーム固有の詳細が非表示になります。 たとえば、ドライバーは、割り込みが GPIO ピンまたは他のソースから受信されるかどうかなどの詳細を無視できます。 この抽象化をメインするには、DIRQL で実行されるカーネルの割り込みトラップ ハンドラーが、GPIO ピンで割り込みをクリアまたは一時的にマスクすることによって、アクティブな割り込み要求を沈黙させる必要がある場合があります。 GPIO コントローラーのハードウェア レジスタは通常、メモリ マップされ、DIRQL でアクセスできます。
これに対し、SPB に接続された周辺機器はメモリ マップされず、通常はこのデバイスの ISR は IRQL = PASSIVE_LEVELで実行する必要があります。 デバイスのハードウェア レジスタにアクセスするため、ISR は SPB 経由でシリアル転送を実行する I/O 要求を送信します。 このような転送は比較的低速で、DIRQL で実行される ISR では実行できません。 ただし、パッシブ レベルの ISR は I/O 要求を同期的に送信し、要求が完了するまでブロックできます。
エッジ トリガーされる割り込みの場合、カーネルのトラップ ハンドラーは、GPIO ピンで割り込み要求を自動的にクリアにし、パッシブ レベルで実行するようにデバイスの ISR をスケジュールします。 トラップ ハンドラーが戻った後に同じ割り込みが再度発生しないように、トラップ ハンドラーは割り込みをクリアする必要があります。
レベルによってトリガーされる割り込みの場合、カーネルの割り込みトラップ ハンドラーは、GPIO ピンで割り込み要求を自動的にマスクし、パッシブ レベルで実行するようにデバイスの ISR をスケジュールします。 ISR は、デバイスからの割り込み要求をクリアする必要があります。 ISR から制御が戻った後、カーネルは GPIO ピンで割り込み要求のマスクを解除します。
デバイスのパッシブ レベルの ISR は、割り込みの初期サービスのみを実行し、他のデバイスのパッシブ レベルの ISR が遅延しないように戻る必要があります。 通常、ドライバーは割り込みワーカー スレッドに割り込み関連の追加処理を延期する必要があります。これは ISR よりも低い優先順位で実行されます。
Windows 8 以降、ユーザー モード ドライバー フレームワーク (UMDF) は UMDF ドライバーの ISR をサポートしています。 SPB 周辺機器の UMDF ドライバーは、IWDFDevice3::CreateInterrupt メソッドを呼び出して、ISR をデバイスからの割り込みに接続します。 デバイスが割り込み要求を通知すると、カーネルのトラップ ハンドラーは ISR をパッシブ レベルで実行するようにスケジュールします。 詳細については、「ハードウェアへのアクセスと割り込みの処理」を参照してください。
Windows 8 以降、カーネル モード ドライバー フレームワーク (KMDF) ではパッシブ レベルの ISR がサポートされています。 SPB 周辺機器の KMDF ドライバーは、WdfInterruptCreate メソッドを呼び出して、パッシブ レベルの ISR をデバイスからの割り込みに接続します。 このメソッドへの入力パラメーターの 1 つは、割り込みの構成情報を含む WDF_INTERRUPT_CONFIG 構造体へのポインターです。 パッシブ レベルで実行するように ISR を構成するには、この構造体の PassiveHandling メンバーを TRUE に 設定します。 詳細については、「パッシブ レベルの割り込みのサポート」を参照してください。