callback Interrupt-Related

Come opzione, il driver per un controller di I/O per utilizzo generico (GPIO) può fornire supporto per gli interrupt GPIO. Per supportare gli interrupt GPIO, un driver del controller GPIO implementa un set di funzioni di callback per gestire questi interrupt. Il driver include puntatori a queste funzioni di callback nel pacchetto di registrazione fornito dal driver quando si registra come client dell'estensione del framework GPIO (GpioClx). Per altre informazioni su questo pacchetto di registrazione, vedere GPIO_CLIENT_REGISTRATION_PACKET.

Di regola, un controller GPIO che è una parte integrata di un chip SoC (System on a Chip) dispone di registri hardware mappati alla memoria a cui è possibile accedere direttamente dal processore nel chip SoC. Tuttavia, un dispositivo controller GPIO separato potrebbe essere connesso esternamente al chip SoC tramite un bus seriale, come illustrato nel diagramma seguente.

un controller gpio integrato e un controller gpio esterno.

In questo diagramma il controller GPIO esterno è connesso a un bus I²C. Questo autobus è controllato da un controller bus I²C che è una parte integrata del chip SoC. La riga di richiesta di interrupt dal controller GPIO esterno è connessa a un pin nel controller GPIO integrato. GpioClx DDI può contenere sia il controller GPIO integrato che il controller GPIO esterno in questo esempio.

Se un dispositivo controller GPIO è mappato alla memoria, il driver del controller GPIO può accedere direttamente ai registri hardware del controller in DIRQL. Tuttavia, se il controller GPIO è connesso in modo seriale, il driver del controller GPIO può accedere ai registri hardware solo in IRQL = PASSIVE_LEVEL, come descritto in ISR a livello passivo.

Il driver per un controller GPIO con registri hardware mappati alla memoria deve impostare il bit del flag MemoryMappedController nelle informazioni sul dispositivo fornite dal driver a GpioClx. In caso contrario, GpioClx presuppone che i registri hardware non siano mappati alla memoria e che il driver possa accedere a questi registri solo in IRQL = PASSIVE_LEVEL. Per altre informazioni su questo bit di flag, vedere CONTROLLER_ATTRIBUTE_FLAGS.

GpioClx implementa una routine del servizio di interruzione (ISR) per gestire le richieste di interruzione dal controller GPIO. Questo ISR chiama le funzioni di callback correlate all'interrupt seguenti:

CLIENT_ClearActiveInterruptsCLIENT_MaskInterruptsCLIENT_QueryActiveInterrupts CLIENT_QueryEnabledInterruptsCLIENT_UnmaskInterrupt Queste funzioni vengono chiamate a DIRQL o PASSIVE_LEVEL, a seconda che l'ISR in GpioClx venga eseguito in DIRQL o PASSIVE_LEVEL. L'ISR chiama queste funzioni in DIRQL se MemoryMappedController = 1 e in PASSIVE_LEVEL se MemoryMappedController = 0. In entrambi i casi, l'ISR serializza automaticamente i relativi callback in modo che una chiamata a una di queste funzioni non si verifichi al centro di una chiamata a un'altra di queste funzioni.

L'estensione del framework GPIO chiama le funzioni di callback correlate agli interrupt seguenti solo in PASSIVE_LEVEL, indipendentemente dal fatto che il flag MemoryMappedController sia impostato:

CLIENT_DisableInterruptCLIENT_EnableInterrupt Se il flag MemoryMappedController non è impostato, tutte le funzioni di callback correlate all'interrupt vengono chiamate in PASSIVE_LEVEL. GpioClx serializza automaticamente le chiamate a queste funzioni in modo che una chiamata a una di queste funzioni non si verifichi al centro di una chiamata a un'altra di queste funzioni.

Tuttavia, se il flag MemoryMappedController è impostato, le funzioni CLIENT_EnableInterrupt e CLIENT_DisableInterrupt devono sincronizzare in modo esplicito le operazioni di abilitazione e disabilitazione delle operazioni con GpioClx ISR, che chiama le altre quattro funzioni di callback correlate agli interrupt in DIRQL.

In genere, le altre funzioni di callback CLIENT_Xxx (i cui nomi non contengono "Interrupt") non eseguono l'elaborazione correlata agli interrupt e pertanto non è necessario eseguire la sincronizzazione con L'ISR GpioClx. Tuttavia, se una di queste funzioni viene chiamata in PASSIVE_LEVEL e contiene codice che accede alle impostazioni di interrupt a cui accedono le funzioni correlate agli interrupt in DIRQL, questo codice deve essere sincronizzato con l'ISR.

Per supportare la sincronizzazione degli interrupt, GpioClx implementa un set di blocchi di interrupt. Una funzione di callback eseguita in PASSIVE_LEVEL può chiamare il metodo GPIO_CLX_AcquireInterruptLock per acquisire un blocco di interrupt e chiamare il metodo GPIO_CLX_ReleaseInterruptLock per rilasciare il blocco. Quando la funzione mantiene il blocco di interrupt, l'ISR GpioClx non può essere eseguito e questo ISR non può chiamare alcuna funzione di callback correlata agli interrupt. Per consentire la gestione tempestiva degli interrupt GPIO, il driver deve contenere il blocco di interrupt per non più di quanto sia necessario.

Per altre informazioni, vedere Interrupt Synchronization for GPIO Controller Drivers.For more information, see Interrupt Synchronization for GPIO Controller Drivers.