Compartilhar via


Interrupções de dispositivos periféricos conectados ao SPB

Ao contrário de um barramento, como o PCI, um SPB ( barramento periférico simples ), como i2C ou SPI, não fornece meios padronizados e específicos do barramento para transmitir solicitações de interrupção de dispositivos periféricos para o processador. Em vez disso, um dispositivo periférico conectado ao SPB sinaliza uma interrupção por meio de um caminho de hardware separado que está fora do SPB e do controlador SPB. Os detalhes desse caminho de interrupção tendem a variar de uma plataforma de hardware para outra, mas o Windows oculta esses detalhes do driver de um dispositivo periférico conectado ao SPB para permitir que o driver trabalhe em várias plataformas de hardware.

Normalmente, a linha de solicitação de interrupção de um dispositivo periférico conectado a SPB é conectada a um pino em um controlador de E/S de uso geral (GPIO) e o controlador GPIO retransmite interrupções do dispositivo para o processador. Para obter mais informações, consulte Interrupções de GPIO.

O driver de dispositivo periférico adquire essa interrupção GPIO como um recurso abstrato de interrupção do Windows (CmResourceTypeInterrupt) e conecta a interrupção à rotina de serviço de interrupção (ISR) do driver. A abstração de recursos de interrupção oculta do driver os detalhes específicos da plataforma da interrupção. Por exemplo, o driver pode ignorar detalhes, como se a interrupção é recebida de um pino GPIO ou de alguma outra origem. Para manter essa abstração, o manipulador de interceptação de interrupção do kernel, que é executado em DIRQL, pode precisar silenciar uma solicitação de interrupção ativa limpando ou mascarando temporariamente a interrupção no pino gpio. Os registros de hardware do controlador GPIO normalmente são mapeados pela memória e podem ser acessados no DIRQL.

Por outro lado, um dispositivo periférico conectado ao SPB não é mapeado para memória, e o ISR para esse dispositivo normalmente deve ser executado em IRQL = PASSIVE_LEVEL. Para acessar os registros de hardware no dispositivo, o ISR envia solicitações de E/S para executar transferências seriais pelo SPB. Essas transferências são relativamente lentas e não podem ser executadas em um ISR executado no DIRQL. No entanto, um ISR de nível passivo pode enviar uma solicitação de E/S de forma síncrona e, em seguida, bloquear até que a solicitação seja concluída.

Para uma interrupção disparada por borda, o manipulador de interceptação do kernel limpa automaticamente a solicitação de interrupção no pino gpio e agenda o ISR do dispositivo para ser executado em nível passivo. O manipulador de interceptação deve limpar a interrupção para evitar que a mesma interrupção ocorra novamente após o manipulador de interceptação retornar.

Para uma interrupção disparada em nível, o tratador de interrupção do kernel mascara automaticamente a solicitação de interrupção no pino GPIO e, em seguida, agenda a ISR (Rotina de Serviço de Interrupção) do dispositivo para ser executada em nível passivo. O ISR deve remover a solicitação de interrupção do dispositivo. Depois que o ISR retorna, o kernel libera a solicitação de interrupção no pino GPIO.

O ISR de nível passivo do dispositivo deve realizar somente o atendimento inicial da interrupção e, em seguida, retornar para não atrasar os ISRs de nível passivo de outros dispositivos. Normalmente, o driver deve adiar o processamento adicional relacionado à interrupção para o thread de trabalho de interrupção, que é executado com uma prioridade menor do que o ISR.

A partir do Windows 8, o User-Mode Driver Framework (UMDF) dá suporte a ISRs para drivers UMDF. O driver UMDF para um dispositivo periférico SPB chama o método IWDFDevice3::CreateInterrupt para conectar um ISR à interrupção do dispositivo. Quando o dispositivo sinaliza uma solicitação de interrupção, o manipulador de interceptação do kernel agenda o ISR para ser executado em nível passivo. Para obter mais informações, consulte Como acessar o hardware e lidar com interrupções.

A partir do Windows 8, o KMDF (Kernel-Mode Driver Framework ) dá suporte a ISRs de nível passivo. O driver KMDF de um dispositivo periférico SPB chama o método WdfInterruptCreate para estabelecer a conexão de um ISR de nível passivo à interrupção do dispositivo. Um dos parâmetros de entrada para esse método é um ponteiro para uma estrutura de WDF_INTERRUPT_CONFIG que contém informações de configuração para a interrupção. Para configurar o ISR a ser executado no nível passivo, defina o membro PassiveHandling dessa estrutura como TRUE. Para obter mais informações, consulte a Suporte de Interrupções Passive-Level.