Condividi tramite


Metodi di supporto driver nell'DDI GpioClx

L'estensione del framework GPIO (GpioClx) è disponibile a partire da Windows 8. I metodi forniti dal sistema nell'DDI GpioClx vengono implementati nel driver in modalità kernel GpioClx Msgpioclx.sys. Questo driver esporta punti di ingresso per i metodi di supporto del driver GpioClx. A partire da Windows 8, Msgpioclx.sys è un componente standard del sistema operativo.

In fase di compilazione, i driver del controller GPIO si collegano staticamente ai punti di ingresso DDI nella libreria stub GpioClx, Msgpioclxstub.lib. In fase di esecuzione, questa libreria esegue la negoziazione necessaria per la versione driver per collegare dinamicamente i punti di ingresso corrispondenti in Msgpioclx.sys.

Un driver del controller GPIO che richiede una versione specifica di Msgpioclx.sys può collegarsi in modo sicuro a una versione di Msgpioclx.sys con un numero di versione superiore. Tuttavia, questo driver non può collegarsi a una versione di Msgpioclx.sys con un numero di versione inferiore.

Registrazione driver

Per registrare come client di GpioClx, un driver controller GPIO chiama il metodo GPIO_CLX_RegisterClient . In genere, il driver chiama questo metodo dalla routine DriverEntry . Durante questa chiamata, il driver passa un pacchetto di registrazione al metodo. Questo pacchetto contiene puntatori a un set di funzioni di callback degli eventi implementate dal driver. Queste funzioni accedono ai registri hardware nel dispositivo controller GPIO. GpioClx chiama queste funzioni per gestire le richieste di I/O e gestire gli interruzioni.

Un driver del controller GPIO chiama il metodo GPIO_CLX_UnregisterClient per annullarne la registrazione con GpioClx. In genere, il driver chiama questo metodo dalla sua funzione di callback degli eventi EvtDriverUnload .

Inizializzazione dell'oggetto dispositivo

Per inizializzare GpioClx, il driver del controller GPIO deve chiamare due metodi GpioClx dalla relativa funzione evtDriverDeviceAdd callback. Il primo metodo, GPIO_CLX_ProcessAddDevicePreDeviceCreate, deve essere chiamato prima della chiamata al metodo WdfDeviceCreate , che crea l'oggetto device. Il secondo metodo, GPIO_CLX_ProcessAddDevicePostDeviceCreate, deve essere chiamato dopo la chiamata WdfDeviceCreate .

Blocco di interruzione

La maggior parte delle funzioni di callback degli eventi implementate dal driver viene chiamata solo in IRQL = PASSIVE_LEVEL da GpioClx. Tuttavia, le funzioni di callback nell'elenco seguente vengono chiamate in PASSIVE_LEVEL o DIRQL, a seconda delle informazioni sul dispositivo fornite dalla funzione di callback CLIENT_QueryControllerBasicInformation a GpioClx:

Queste funzioni vengono chiamate dalla routine del servizio di interruzione (ISR) in GpioClx, che viene eseguita in DIRQL o PASSIVE_LEVEL, a seconda che i registri hardware del controller GPIO siano mappati alla memoria.

La funzione CLIENT_QueryControllerBasicInformation fornisce informazioni sul dispositivo sotto forma di una struttura CLIENT_CONTROLLER_BASIC_INFORMATION . Se il bit del flag MemoryMappedController è impostato nel membro Flags di questa struttura, GpioClx ISR chiama le funzioni di callback nell'elenco precedente in DIRQL. In caso contrario, l'ISR chiama tutte le funzioni di callback implementate dal driver in PASSIVE_LEVEL. Per altre informazioni su questo bit di flag, vedere Callback correlati all'interruzione.

GpioClx sincronizza automaticamente le chiamate alle funzioni di callback implementate dal driver eseguite in PASSIVE_LEVEL e non vengono chiamate dall'ISR GpioClx. Pertanto, solo una di queste funzioni può essere eseguita alla volta. Tuttavia, GpioClx non sincronizza automaticamente questi callback PASSIVE_LEVEL con callback che GpioClx esegue dal relativo ISR. Il driver del controller GPIO deve fornire in modo esplicito tale sincronizzazione, se necessario.

Per evitare potenziali errori di sincronizzazione, GpioClx implementa un blocco di interruzione che il driver del controller GPIO può acquisire e rilasciare. Il blocco di interruzione viene usato principalmente dalle funzioni di CLIENT_EnableInterrupt del driver e CLIENT_DisableInterrupt callback. Il driver chiama il metodo GPIO_CLX_AcquireInterruptLock per acquisire il blocco e chiama il metodo GPIO_CLX_ReleaseInterruptLock per rilasciare il blocco. Il driver chiama questi metodi da una funzione di callback chiamata in PASSIVE_LEVEL e non viene chiamata dall'ISR in GpioClx. Mentre il driver contiene il blocco, non è possibile eseguire GpioClx ISR. Il driver deve contenere il blocco solo brevemente e solo durante le operazioni critiche che devono essere sincronizzate con ISR.

Se GpioClx ISR chiama una funzione di callback implementata dal driver, questa funzione non deve acquisire (o rilasciare) il blocco di interruzione perché l'ISR contiene già il blocco (e lo rilascia). Le chiamate ai metodi GPIO_CLX_AcquireInterruptLock e GPIO_CLX_ReleaseInterruptLock di questa funzione non hanno alcun effetto, ma non vengono considerati errori.