GpioClx DDI のドライバー サポート メソッド
GPIO フレームワーク拡張機能 (GpioClx) は、Windows 8 以降で利用可能です。 GpioClx DDI のシステム提供のメソッドは、GpioClx カーネル モード ドライバー Msgpioclx.sys に実装されます。 このドライバーは、GpioClx ドライバー サポート メソッドのエントリ ポイントをエクスポートします。 Windows 8 以降、Msgpioclx.sys はオペレーティング システムの標準コンポーネントです。
ビルド時に、GPIO コントローラー ドライバーは、GpioClx スタブ ライブラリ Msgpioclxstub.lib 内の DDI エントリ ポイントに静的にリンクします。 実行時に、このライブラリは、Msgpioclx.sys 内の対応するエントリ ポイントに動的にリンクするために必要なドライバー バージョン ネゴシエーションを実行します。
特定のバージョンの Msgpioclx.sys を必要とする GPIO コントローラー ドライバーは、より大きいバージョン番号を持つ Msgpioclx.sys のバージョンに安全にリンクできます。 ただし、このドライバーは、バージョン番号がより小さい Msgpioclx.sys のバージョンにリンクできません。
ドライバーの登録
GpioClx のクライアントとして登録するため、GPIO コントローラー ドライバーは GPIO_CLX_RegisterClient メソッドを呼び出します。 通常、ドライバーは DriverEntry ルーチンからこのメソッドを呼び出します。 この呼び出し中に、ドライバーは登録パケットをメソッドに渡します。 このパケットには、ドライバーによって実装されたイベント コールバック関数のセットへのポインターが含まれています。 これらの関数は、GPIO コントローラー デバイスのハードウェア レジスタにアクセスします。 GpioClx は、I/O 要求を処理し、割り込みを管理するために、これらの関数を呼び出します。
GPIO コントローラー ドライバーは、GPIO_CLX_UnregisterClient メソッドを呼び出して、GpioClx への登録を取り消します。 通常、ドライバーは、EvtDriverUnload イベント コールバック関数からこのメソッドを呼び出します。
デバイス オブジェクトの初期化
GpioClx を初期化するため、GPIO コントローラー ドライバーは EvtDriverDeviceAdd コールバック関数から 2 つの GpioClx メソッドを呼び出す必要があります。 最初のメソッド GPIO_CLX_ProcessAddDevicePreDeviceCreate は、デバイス オブジェクトを作成する WdfDeviceCreate メソッドの呼び出しの前に呼び出す必要があります。 2 番目のメソッド GPIO_CLX_ProcessAddDevicePostDeviceCreate は、WdfDeviceCreate 呼び出しの後に呼び出す必要があります。
割り込みロック
ドライバーによって実装されるイベント コールバック関数の大部分は、IRQL = PASSIVE_LEVEL でのみ GpioClx によって呼び出されます。 ただし、次の一覧のコールバック関数は、CLIENT_QueryControllerBasicInformation コールバック関数が GpioClx に提供するデバイス情報に応じて、PASSIVE_LEVEL または DIRQL で呼び出されます。
- CLIENT_ClearActiveInterrupts
- CLIENT_MaskInterrupts
- CLIENT_QueryActiveInterrupts
- CLIENT_QueryEnabledInterrupts
- CLIENT_UnmaskInterrupt
これらの関数は、GPIO コントローラーのハードウェア レジスタがメモリ マップされているかどうかに応じて、DIRQL または PASSIVE_LEVEL で実行される GpioClx の割り込みサービス ルーチン (ISR) から呼び出されます。
CLIENT_QueryControllerBasicInformation 関数は、CLIENT_CONTROLLER_BASIC_INFORMATION 構造体の形式でデバイス情報を提供します。 MemoryMappedController フラグ ビットがこの構造体の Flags メンバーに設定されている場合、GpioClx ISR は DIRQL で前の一覧のコールバック関数を呼び出します。 それ以外の場合、ISR はドライバーによって実装されたすべてのコールバック関数を PASSIVE_LEVEL で呼び出します。 このフラグ ビットの詳細については、「割り込み関連コールバック」を参照してください。
GpioClx は、PASSIVE_LEVEL で実行され GpioClx ISR から呼び出されない、ドライバーによって実装されるコールバック関数の呼び出しを自動的に同期します。 したがって、一度に実行できる関数は 1 つだけです。 ただし、GpioClx は、これらの PASSIVE_LEVEL コールバックを、GpioClx が ISR から行うコールバックと自動的には同期しません。 GPIO コントローラー ドライバーは、必要に応じて、このような同期を明示的に提供する必要があります。
潜在的な同期エラーを回避するために、GpioClx は、GPIO コントローラー ドライバーが取得して解放できる割り込みロックを実装します。 割り込みロックは、主にドライバーの CLIENT_EnableInterrupt および CLIENT_DisableInterrupt コールバック関数によって使用されます。 ドライバーは、GPIO_CLX_AcquireInterruptLock メソッドを呼び出してロックを取得し、GPIO_CLX_ReleaseInterruptLock メソッドを呼び出してロックを解放します。 ドライバーは、PASSIVE_LEVEL で呼び出され GpioClx の ISR から呼び出されないコールバック関数から、これらのメソッドを呼び出します。 ドライバーがロックを保持している間は、GpioClx ISR を実行できません。 ドライバーは、ISR と同期する必要がある重要な操作中にのみ、一時的にロックを保持する必要があります。
GpioClx ISR がドライバーによって実装されたコールバック関数を呼び出す場合、ISR は既にロックを保持 (および解放) するため、割り込みロックを取得 (または解放) する必要はありません。 この関数による GPIO_CLX_AcquireInterruptLock メソッドと GPIO_CLX_ReleaseInterruptLock メソッドの呼び出しは無効ですが、エラーとして扱われません。