Métodos de suporte ao driver na DDI gpioClx
A extensão da estrutura GPIO (GpioClx) está disponível a partir do Windows 8. Os métodos fornecidos pelo sistema na DDI gpioClx são implementados no driver gpioClx no modo kernel, Msgpioclx.sys. Esse driver exporta pontos de entrada para os métodos de suporte do driver GpioClx. Começando com Windows 8, Msgpioclx.sys é um componente padrão do sistema operacional.
No momento da compilação, os drivers do controlador GPIO vinculam estaticamente aos pontos de entrada DDI na biblioteca stub gpioClx, Msgpioclxstub.lib. Em tempo de execução, essa biblioteca executa a negociação de versão do driver necessária para vincular dinamicamente aos pontos de entrada correspondentes no Msgpioclx.sys.
Um driver de controlador GPIO que requer uma versão específica do Msgpioclx.sys pode ser vinculado com segurança a uma versão do Msgpioclx.sys que tenha um número de versão mais alto. No entanto, esse driver não pode vincular a uma versão do Msgpioclx.sys que tenha um número de versão inferior.
Registro de Driver
Para se registrar como um cliente do GpioClx, um driver de controlador GPIO chama o método GPIO_CLX_RegisterClient . Normalmente, o driver chama esse método de sua rotina DriverEntry . Durante essa chamada, o driver passa um pacote de registro para o método . Esse pacote contém ponteiros para um conjunto de funções de retorno de chamada de evento implementadas pelo driver. Essas funções acessam os registros de hardware no dispositivo controlador GPIO. GpioClx chama essas funções para lidar com solicitações de E/S e gerenciar interrupções.
Um driver de controlador GPIO chama o método GPIO_CLX_UnregisterClient para cancelar seu registro com GpioClx. Normalmente, o driver chama esse método de sua função de retorno de chamada de evento EvtDriverUnload .
Inicialização de objeto do dispositivo
Para inicializar GpioClx, o driver do controlador GPIO deve chamar dois métodos GpioClx de sua função de retorno de chamada EvtDriverDeviceAdd . O primeiro método, GPIO_CLX_ProcessAddDevicePreDeviceCreate, deve ser chamado antes da chamada para o método WdfDeviceCreate , que cria o objeto do dispositivo. O segundo método, GPIO_CLX_ProcessAddDevicePostDeviceCreate, deve ser chamado após a chamada WdfDeviceCreate .
Bloqueio de interrupção
A maioria das funções de retorno de chamada de evento implementadas pelo driver são chamadas apenas em IRQL = PASSIVE_LEVEL por GpioClx. No entanto, as funções de retorno de chamada na lista a seguir são chamadas em PASSIVE_LEVEL ou DIRQL, dependendo das informações do dispositivo que a função de retorno de chamada CLIENT_QueryControllerBasicInformation fornece ao GpioClx:
- CLIENT_ClearActiveInterrupts
- CLIENT_MaskInterrupts
- CLIENT_QueryActiveInterrupts
- CLIENT_QueryEnabledInterrupts
- CLIENT_UnmaskInterrupt
Essas funções são chamadas da ISR (rotina de serviço de interrupção) no GpioClx, que é executada no DIRQL ou PASSIVE_LEVEL, dependendo se os registros de hardware do controlador GPIO são mapeados na memória.
A função CLIENT_QueryControllerBasicInformation fornece informações do dispositivo na forma de uma estrutura CLIENT_CONTROLLER_BASIC_INFORMATION . Se o bit do sinalizador MemoryMappedController for definido no membro Flags dessa estrutura, o ISR gpioClx chamará as funções de retorno de chamada na lista anterior em DIRQL. Caso contrário, o ISR chamará todas as funções de retorno de chamada implementadas pelo driver em PASSIVE_LEVEL. Para obter mais informações sobre esse bit de sinalizador, consulte Retornos de chamada relacionados à interrupção.
O GpioClx sincroniza automaticamente as chamadas para funções de retorno de chamada implementadas pelo driver que são executadas em PASSIVE_LEVEL e não são chamadas do ISR gpioClx. Portanto, apenas uma dessas funções pode ser executada por vez. No entanto, o GpioClx não sincroniza automaticamente esses PASSIVE_LEVEL retornos de chamada com retornos de chamada que o GpioClx faz de seu ISR. O driver do controlador GPIO deve fornecer explicitamente essa sincronização, se necessário.
Para evitar possíveis erros de sincronização, o GpioClx implementa um bloqueio de interrupção que o driver do controlador GPIO pode adquirir e liberar. O bloqueio de interrupção é usado principalmente pelas funções de retorno de chamada CLIENT_EnableInterrupt e CLIENT_DisableInterrupt do driver. O driver chama o método GPIO_CLX_AcquireInterruptLock para adquirir o bloqueio e chama o método GPIO_CLX_ReleaseInterruptLock para liberar o bloqueio. O driver chama esses métodos de uma função de retorno de chamada que é chamada em PASSIVE_LEVEL e não é chamada do ISR em GpioClx. Enquanto o driver mantém o bloqueio, o ISR gpioClx não pode ser executado. O driver deve manter o bloqueio apenas brevemente e somente durante operações críticas que devem ser sincronizadas com o ISR.
Se o ISR gpioClx chamar uma função de retorno de chamada implementada pelo driver, essa função não precisará adquirir (ou liberar) o bloqueio de interrupção porque o ISR já mantém o bloqueio (e o liberará). As chamadas para os métodos GPIO_CLX_AcquireInterruptLock e GPIO_CLX_ReleaseInterruptLock por essa função não têm efeito, mas não são tratadas como erros.