Treiberunterstützungsmethoden in GpioClx DDI
Die GPIO-Frameworkerweiterung (GpioClx) ist ab Windows 8 verfügbar. Die vom System bereitgestellten Methoden in GpioClx DDI werden im GpioClx-Kernelmodustreiber implementiert, Msgpioclx.sys. Dieser Treiber exportiert Einstiegspunkte für die GpioClx-Treiberunterstützungsmethoden. Ab Windows 8 ist Msgpioclx.sys eine Standardkomponente des Betriebssystems.
Zur Buildzeit verknüpfen GPIO-Controllertreiber statisch mit den DDI-Einstiegspunkten in der GpioClx-Stubbibliothek Msgpioclxstub.lib. Zur Laufzeit führt diese Bibliothek die erforderliche Treiberversionsverhandlung aus, um dynamisch mit den entsprechenden Einstiegspunkten in Msgpioclx.sys zu verknüpfen.
Ein GPIO-Controllertreiber, der eine bestimmte Version von Msgpioclx.sys erfordert, kann sicher mit einer Version von Msgpioclx.sys mit einer höheren Versionsnummer verknüpft werden. Dieser Treiber kann jedoch keine Verknüpfung mit einer Version von Msgpioclx.sys mit einer niedrigeren Versionsnummer herstellen.
Treiberregistrierung
Um sich als GpioClx-Client zu registrieren, ruft ein GPIO-Controllertreiber die GPIO_CLX_RegisterClient-Methode auf. In der Regel ruft der Treiber diese Methode aus seiner DriverEntry-Routine auf. Während dieses Aufrufs übergibt der Treiber ein Registrierungspaket an die -Methode. Dieses Paket enthält Zeiger auf eine Reihe von vom Treiber implementierten Ereignisrückruffunktionen. Diese Funktionen greifen auf die Hardwareregister im GPIO-Controllergerät zu. GpioClx ruft diese Funktionen auf, um E/A-Anforderungen zu verarbeiten und Unterbrechungen zu verwalten.
Ein GPIO-Controllertreiber ruft die GPIO_CLX_UnregisterClient-Methode auf, um die Registrierung bei GpioClx abzubrechen. In der Regel ruft der Treiber diese Methode über seine EvtDriverUnload-Ereignisrückruffunktion auf.
Geräteobjektinitialisierung
Um GpioClx zu initialisieren, muss der GPIO-Controllertreiber zwei GpioClx-Methoden über seine EvtDriverDeviceAdd-Rückruffunktion aufrufen. Die erste Methode , GPIO_CLX_ProcessAddDevicePreDeviceCreate, muss vor dem Aufruf der WdfDeviceCreate-Methode aufgerufen werden, die das Geräteobjekt erstellt. Die zweite Methode , GPIO_CLX_ProcessAddDevicePostDeviceCreate, muss nach dem WdfDeviceCreate-Aufruf aufgerufen werden.
Unterbrechungssperre
Die Meisten der vom Treiber implementierten Ereignisrückruffunktionen werden nur unter IRQL = PASSIVE_LEVEL von GpioClx aufgerufen. Die Rückruffunktionen in der folgenden Liste werden jedoch entweder bei PASSIVE_LEVEL oder DIRQL aufgerufen, abhängig von den Geräteinformationen, die die CLIENT_QueryControllerBasicInformation Rückruffunktion für GpioClx bereitstellt:
- CLIENT_ClearActiveInterrupts
- CLIENT_MaskInterrupts
- CLIENT_QueryActiveInterrupts
- CLIENT_QueryEnabledInterrupts
- CLIENT_UnmaskInterrupt
Diese Funktionen werden von der Interruptdienstroutine (ISR) in GpioClx aufgerufen, die entweder bei DIRQL oder PASSIVE_LEVEL ausgeführt wird, je nachdem, ob die Hardwareregister des GPIO-Controllers arbeitsspeicherseitig zugeordnet sind.
Die CLIENT_QueryControllerBasicInformation-Funktion stellt Geräteinformationen in Form einer CLIENT_CONTROLLER_BASIC_INFORMATION-Struktur bereit. Wenn das Flagbit "MemoryMappedController " im Flags-Element dieser Struktur festgelegt ist, ruft die GpioClx ISR die Rückruffunktionen in der vorherigen Liste unter DIRQL auf. Andernfalls ruft die ISR alle vom Treiber implementierten Rückruffunktionen bei PASSIVE_LEVEL auf. Weitere Informationen zu diesem Flagbit finden Sie unter Interrupt-Related Callbacks.
GpioClx synchronisiert automatisch Aufrufe von vom Treiber implementierten Rückruffunktionen, die bei PASSIVE_LEVEL ausgeführt werden und nicht von der GpioClx ISR aufgerufen werden. Daher kann nur eine dieser Funktionen gleichzeitig ausgeführt werden. GpioClx synchronisiert diese PASSIVE_LEVEL-Rückrufe jedoch nicht automatisch mit Rückrufen, die GpioClx über die ISR durchführt. Der GPIO-Controllertreiber muss eine solche Synchronisierung explizit bereitstellen, wenn dies erforderlich ist.
Um potenzielle Synchronisierungsfehler zu vermeiden, implementiert GpioClx eine Interruptsperre , die der GPIO-Controllertreiber abrufen und freigeben kann. Die Interruptsperre wird in erster Linie von den CLIENT_EnableInterrupt und CLIENT_DisableInterrupt Rückruffunktionen des Treibers verwendet. Der Treiber ruft die GPIO_CLX_AcquireInterruptLock-Methode auf, um die Sperre abzurufen, und ruft die GPIO_CLX_ReleaseInterruptLock-Methode auf, um die Sperre freizugeben. Der Treiber ruft diese Methoden über eine Rückruffunktion auf, die bei PASSIVE_LEVEL aufgerufen wird und nicht von der ISR in GpioClx aufgerufen wird. Während der Treiber die Sperre hält, kann die GpioClx ISR nicht ausgeführt werden. Der Treiber sollte die Sperre nur kurz und nur bei kritischen Vorgängen halten, die mit der ISR synchronisiert werden müssen.
Wenn die GpioClx ISR eine vom Treiber implementierte Rückruffunktion aufruft, muss diese Funktion die Interruptsperre nicht abrufen (oder freigeben), da die ISR die Sperre bereits enthält (und sie freigeben wird). Aufrufe der methoden GPIO_CLX_AcquireInterruptLock und GPIO_CLX_ReleaseInterruptLock von dieser Funktion haben keine Auswirkung, werden aber nicht als Fehler behandelt.