Visão geral dos drivers de dispositivos periféricos SPB
Um driver de dispositivo periférico SPB controla um dispositivo periférico conectado a um SPB (barramento periférico simples). Os registros de hardware deste dispositivo estão disponíveis apenas através do SPB. Para ler ou gravar no dispositivo, o driver deve enviar solicitações de E/S ao controlador SPB. Apenas esse controlador pode iniciar transferências de dados de e para o dispositivo através do SPB.
A partir do Windows 8, o Windows fornece suporte de driver para dispositivos periféricos em SPBs (barramentos periféricos simples). SPBs, como I2C e SPI, são amplamente usados para conectar dispositivos sensores de baixa velocidade, como acelerômetros, dispositivos GPS e monitores de nível de bateria. Esta visão geral descreve como um driver de dispositivo periférico SPB, em cooperação com outros componentes do sistema, controla um dispositivo periférico conectado ao SPB.
Um driver de dispositivo periférico SPB pode ser criado para usar o UMDF (User-Mode Driver Framework) ou o KMDF (Kernel-Mode Driver Framework). Para obter mais informações sobre como desenvolver um driver UMDF, consulte Introdução ao UMDF. Para obter mais informações sobre como desenvolver um driver KMDF, consulte Introdução à estrutura de driver do modo kernel.
Informações de configuração do dispositivo
Os registros de hardware de um dispositivo periférico conectado ao SPB não são mapeados na memória. O dispositivo pode ser acessado somente por meio do controlador SPB, que transfere dados serialmente de e para o dispositivo pelo SPB. Para executar operações de E/S, o driver de dispositivo periférico SPB envia solicitações de E/S para o dispositivo e o controlador SPB executa as transferências de dados necessárias para concluir essas solicitações. Para obter mais informações sobre as solicitações de E/S que podem ser enviadas a dispositivos periféricos em SPBs, consulte Usando a interface de solicitação de E/S do SPB.
O diagrama a seguir mostra um exemplo de configuração de hardware na qual um SPB (neste caso, um barramento I2C) conecta dois dispositivos periféricos a um módulo SoC (System on a Chip). Os dispositivos periféricos são externos ao módulo SoC e se conectam a quatro pinos no módulo. O módulo SoC contém o processador principal (não mostrado), além de um controlador I2C e um controlador de E/S de uso geral (GPIO). O processador usa o controlador I2C para transmitir dados em série de e para os dois dispositivos periféricos. As linhas de solicitação de interrupção desses dispositivos são conectadas a dois pinos GPIO configurados como entradas de interrupção. Quando um dispositivo sinaliza uma solicitação de interrupção, o controlador GPIO retransmite a interrupção ao processador.
Como o controlador GPIO e o controlador I2C neste exemplo estão integrados ao módulo SoC, seus registros de hardware são mapeados na memória e podem ser acessados diretamente pelo processador. No entanto, o processador só pode acessar os registros de hardware dos dois dispositivos periféricos indiretamente, através do controlador I2C.
Um SPB não é um barramento PnP (Plug and Play) e, portanto, não pode ser usado para detectar e configurar automaticamente novos dispositivos conectados ao barramento. As conexões de barramento e interrupção de um dispositivo conectado ao SPB são frequentemente permanentes. Mesmo que o dispositivo possa ser desconectado de um slot, esse slot geralmente é dedicado ao dispositivo. Além disso, um SPB não fornece um caminho de hardware em banda para retransmitir solicitações de interrupção de um dispositivo periférico no barramento ao controlador de barramento. Em vez disso, o caminho de hardware de interrupções é separado do controlador de barramento.
O fornecedor da plataforma de hardware armazena as informações de configuração de um dispositivo periférico conectado ao SPB no firmware ACPI da plataforma. Durante a inicialização do sistema, o driver ACPI enumera os dispositivos no barramento para o gerenciador PnP. Para cada dispositivo enumerado, a ACPI fornece informações sobre as conexões de barramento e interrupção do dispositivo. O gerenciador PnP armazena essas informações em um armazenamento de dados chamado hub de recursos.
Quando o dispositivo é inicializado, o gerenciador PnP fornece ao driver do dispositivo um conjunto de recursos de hardware que encapsulam as informações de configuração que o hub de recursos armazena para o dispositivo. Esses recursos incluem uma ID de conexão e um número de interrupção. O ID de conexão encapsula informações de conexão de barramento, como o controlador SPB, o endereço do barramento e a frequência do clock do barramento. Antes que as solicitações de E/S possam ser enviadas ao dispositivo, o driver deverá usar a ID de conexão para abrir uma conexão lógica com o dispositivo. O número de interrupção é um recurso de interrupção do Windows ao qual o driver pode conectar sua ISR (rotina de serviço de interrupção). O driver pode ser facilmente transferido de uma plataforma de hardware para outra porque a ID da conexão e o número de interrupção são abstrações de alto nível que ocultam informações específicas da plataforma sobre o barramento físico e as conexões de interrupção.
Camadas de software e hardware
O diagrama de blocos a seguir mostra as camadas de software e hardware que conectam um dispositivo periférico em um SPB a um programa de aplicativo que usa o dispositivo. O driver de dispositivo periférico SPB neste exemplo é um driver UMDF. O dispositivo periférico (na parte inferior do diagrama) é um dispositivo sensor (por exemplo, um acelerômetro). Como no diagrama anterior, o dispositivo periférico está conectado a um barramento I2C e sinaliza solicitações de interrupção por meio de um pino em um controlador GPIO.
Os três blocos mostrados em cinza são módulos fornecidos pelo sistema. A partir do Windows 7, a extensão de classe de sensor está disponível como uma extensão específica de sensor para o UMDF. A partir do Windows 8, a extensão da estrutura SPB (SpbCx) e a extensão da estrutura GPIO (GpioClx) estão disponíveis como extensões para KMDF que executam funções específicas para controladores SPB e controladores GPIO, respectivamente.
Na parte superior do diagrama anterior, o aplicativo chama os métodos na API do Sensor ou na API de Localização para se comunicar com o dispositivo do sensor. Por meio dessas chamadas, o aplicativo pode enviar solicitações de E/S para o dispositivo e receber notificações de eventos do dispositivo. Para obter mais informações sobre essas APIs, consulte Introdução à plataforma de sensor e localização no Windows.
Quando o aplicativo chama um método que requer comunicação com o driver de dispositivo periférico SPB, a API do Sensor ou a API de Localização cria uma solicitação de E/S e a envia para o driver de dispositivo periférico SPB. O módulo de extensão de classe de sensor ajuda o driver a lidar com essas solicitações de E/S. Quando o driver recebe uma nova solicitação de E/S, ele imediatamente a entrega à extensão da classe do sensor, que enfileira a solicitação até que o driver esteja pronto para lidar com ela. Se uma solicitação de E/S do aplicativo exigir a transferência de dados de ou para o dispositivo periférico, o driver de dispositivo periférico SPB criará uma solicitação de E/S para essa transferência e a enviará para o controlador I2C. Essas solicitações são tratadas em conjunto pelo SpbCx e pelo driver do controlador I2C.
O SpbCx é um componente fornecido pelo sistema que gerencia as filas de solicitações de E/S para um controlador SPB, como o controlador I2C neste exemplo. O driver do controlador I2C, que é fornecido pelo fornecedor de hardware para o controlador, gerencia todas as operações específicas de hardware no controlador I2C. Por exemplo, o driver do controlador acessa os registros de hardware mapeados na memória do controlador para iniciar transferências de dados de e para o dispositivo periférico pelo barramento I2C.
O dispositivo periférico sinaliza uma solicitação de interrupção quando ocorre um evento de hardware que requer atenção do driver de dispositivo periférico SPB ou do aplicativo de modo de usuário. A linha de interrupção do dispositivo periférico é conectada a um pino GPIO configurado para receber solicitações de interrupção. Quando o dispositivo sinaliza uma interrupção para o pino GPIO, o controlador GPIO sinaliza uma interrupção para o processador. Em resposta a essa interrupção, o manipulador de interceptação de interrupção do kernel chama o ISR do GpioClx. Esse ISR consulta o driver do controlador GPIO, que acessa os registros de hardware mapeados em memória do controlador GPIO para identificar o pino GPIO de interrupção. Para silenciar a interrupção, o driver do controlador GPIO limpa (se a interrupção for acionada por borda) ou mascara (se acionada por nível) a solicitação de interrupção no pino GPIO. A interrupção deve ser silenciada para evitar que o processador faça a mesma interrupção novamente quando o manipulador de interceptação retornar. Para uma interrupção acionada por nível, o ISR no driver de dispositivo periférico SPB deve acessar os registros de hardware do dispositivo periférico para limpar a interrupção antes que o pino GPIO possa ser desmascarado.
Antes que o manipulador de interceptação de interrupção do kernel retorne, ele agenda o ISR no driver de dispositivo periférico SPB para ser executado em IRQL = PASSIVE_LEVEL. A partir do Windows 8, um driver UMDF pode conectar seu ISR a uma interrupção que o driver recebe como um recurso de interrupção abstrato do Windows. Para obter mais informações, consulte Manipular interrupções. Para determinar qual ISR chamar, o sistema operacional procura a interrupção virtual atribuída ao pino GPIO de interrupção e localiza o ISR conectado à interrupção. Essa interrupção virtual é rotulada como uma interrupção secundária no diagrama anterior. Por outro lado, a interrupção de hardware do controlador GPIO é rotulada como uma interrupção primária.
Como o ISR no driver de dispositivo periférico SPB é executado no nível passivo, o ISR pode usar solicitações de E/S síncronas para acessar os registros de hardware no dispositivo periférico. O ISR pode bloquear até que essas solicitações sejam concluídas. O ISR, que é executado com uma prioridade relativamente alta, deve retornar o mais rápido possível e adiar todo o processamento em segundo plano para uma interrupção em uma rotina de trabalho que é executada com uma prioridade mais baixa.
Em resposta à interrupção secundária, o driver de dispositivo periférico SPB publica um evento na extensão de classe do sensor, que notifica o aplicativo no modo de usuário do evento por meio da API do Sensor ou da API de Localização.