Partilhar via


Interrupt-Related Retornos de chamada

Como opção, o driver para um controlador de E/S (GPIO) de uso geral pode fornecer suporte para interrupções GPIO. Para suportar interrupções GPIO, um driver controlador GPIO implementa um conjunto de funções de retorno de chamada para gerenciar essas interrupções. O driver inclui referências para as funções de retorno de chamada no pacote de registo que o driver fornece quando se regista como um cliente da extensão do framework GPIO (GpioClx). Para obter mais informações sobre esse pacote de registro, consulte GPIO_CLIENT_REGISTRATION_PACKET.

Como regra, um controlador GPIO que é parte integrada de um chip System on a Chip (SoC) tem registros de hardware mapeados pela memória que podem ser acessados diretamente pelo processador no chip SoC. No entanto, um dispositivo controlador GPIO separado pode ser conectado externamente ao chip SoC através de um barramento serial, conforme mostrado no diagrama a seguir.

Um controlador GPIO integrado e um controlador GPIO externo.

Neste diagrama, o controlador GPIO externo é conectado a um barramento I²C. Este barramento é controlado por um controlador de barramento I²C que é uma parte integrada do chip SoC. A linha de solicitação de interrupção do controlador GPIO externo é conectada a um pino no controlador GPIO integrado. O DDI GpioClx pode acomodar o controlador GPIO integrado e o controlador GPIO externo neste exemplo.

Se um dispositivo de controlador GPIO estiver mapeado em memória, o driver do controlador GPIO poderá acessar diretamente os registros de hardware do controlador no DIRQL. No entanto, se o controlador GPIO estiver conectado em série, o driver do controlador GPIO poderá acessar os registros de hardware somente em IRQL = PASSIVE_LEVEL, conforme discutido em ISRsPassive-Level.

O driver para um controlador GPIO que tem registos de hardware com mapeamento de memória deve definir o bit do sinalizador MemoryMappedController nas informações do dispositivo fornecidas pelo driver ao GpioClx. Caso contrário, o GpioClx assume que os registos de hardware não são mapeados na memória e que o driver pode aceder a estes registos apenas no nível IRQL = PASSIVE_LEVEL. Para obter mais informações sobre esse bit de sinalizador, consulte CONTROLLER_ATTRIBUTE_FLAGS.

O GpioClx implementa uma rotina de serviço de interrupção (ISR) para atender solicitações de interrupção do controlador GPIO. Esse ISR chama as seguintes funções de retorno de chamada relacionadas à interrupção:

CLIENT_ClearActiveInterruptsCLIENT_MaskInterruptsCLIENT_QueryActiveInterruptsCLIENT_QueryEnabledInterruptsCLIENT_UnmaskInterrupt Essas funções são chamadas em DIRQL ou PASSIVE_LEVEL, dependendo se o ISR no GpioClx é executado em DIRQL ou PASSIVE_LEVEL. O ISR chama essas funções em DIRQL se MemoryMappedController = 1 e em PASSIVE_LEVEL se MemoryMappedController = 0. Em ambos os casos, o ISR serializa automaticamente seus retornos de chamada para que uma chamada para uma dessas funções não ocorra no meio de uma chamada para outra dessas funções.

A extensão da estrutura GPIO chama as seguintes funções de retorno de chamada relacionadas à interrupção somente em PASSIVE_LEVEL, independentemente de o sinalizador MemoryMappedController estar definido.

CLIENT_DisableInterruptCLIENT_EnableInterrupt Se o sinalizador MemoryMappedController não estiver definido, todas as funções de retorno de chamada relacionadas à interrupção serão chamadas em PASSIVE_LEVEL. O GpioClx serializa automaticamente chamadas para essas funções para que uma chamada para uma dessas funções não ocorra no meio de uma chamada para outra dessas funções.

No entanto, se o sinalizador MemoryMappedController estiver definido, as funções CLIENT_EnableInterrupt e CLIENT_DisableInterrupt deverão sincronizar explicitamente suas operações de ativação e desativação de interrupção para o ISR GpioClx, que chama as outras quatro funções de retorno de chamada relacionadas à interrupção no DIRQL.

Normalmente, as outras funções de 'callback' CLIENT_Xxx (cujos nomes não contêm "Interrupt") não executam processamento relacionado a interrupções e, portanto, não precisam sincronizar com o ISR GpioClx. No entanto, se qualquer uma dessas funções for chamada em PASSIVE_LEVEL e contiver código que acesse as configurações de interrupção que são acessadas por funções relacionadas a interrupção no DIRQL, esse código deverá ser sincronizado com o ISR.

Para dar suporte à sincronização de interrupções, o GpioClx implementa um conjunto de bloqueios de interrupções. Uma função de retorno de chamada que é executada em PASSIVE_LEVEL pode chamar o método GPIO_CLX_AcquireInterruptLock para adquirir um bloqueio de interrupção e chamar o método GPIO_CLX_ReleaseInterruptLock para liberar o bloqueio. Quando a função mantém o bloqueio de interrupção, o ISR GpioClx não pode ser executado e este ISR não pode chamar qualquer função de retorno de chamada relacionada à interrupção. Para permitir que as interrupções GPIO sejam tratadas em tempo hábil, o motorista deve segurar o bloqueio de interrupção por não mais tempo do que o necessário.

Para obter mais informações, consulte Sincronização de Interrupções para Controladores GPIO.