Quando é necessário um driver de dispositivo e quando é bom ler / gravar diretamente na porta?


8

Estou tendo dificuldades para entender quando os drivers de dispositivo são necessários e quando é bom conversar diretamente com um controlador de porta por meio do serial / paralelo / USB / etc fornecido pelo sistema operacional. motorista.

Por exemplo, Exemplo 1 : tomemos o OpenBCI , um BCI de hardware de código aberto que permite ler leituras de EEG + EKG ("ondas cerebrais"). O headset OpenBCI envia sinais de RF para uma unidade USB conectada à sua máquina e, em seguida, você pode escrever seu próprio software para ler os dados que entram nessa porta; assim, permite que você leia suas próprias ondas cerebrais e interprete dados de ondas cerebrais na camada de aplicativos. Muito legal. Para ler seus dados de ondas cerebrais de "streaming", você precisa não apenas ler da sua porta serial (usando o driver serial fornecido pelo sistema operacional), mas também interpretar os dados de acordo com as especificações do OpenBCI . Portanto, a pilha fica assim:

insira a descrição da imagem aqui

Mas em nenhum lugar aqui temos um "driver de dispositivo" específico para o headset OpenBCI. Apenas o driver serial necessário para ler bytes de dados e, em seguida, você precisa interpretar o significado desses bytes dentro do aplicativo. Por exemplo, se eu quisesse que um aplicativo Java interpretasse dados de ondas cerebrais, poderia usar o JSerialComm para ler os dados da minha porta COM local (ou qualquer USB que esteja no sistema local). Caberia ao meu aplicativo interceptar esses dados de acordo com as especificações listadas acima.

Agora, Exemplo 2 : uma webcam USB da Logitech como esta . Aqui, você precisa instalar os drivers de dispositivo da webcam em sua máquina para poder usá-la. Eu estou me perguntando o porquê. Vamos fingir (basta pressionar o botão " Eu acredito! " Por um momento)) que a pinagem dessa webcam era estúpida e simples:

PIN #       Meaning
===================
1           Power
2           Ground
3           Send data (if 1 then the camera will start "streaming" its video data over data pins)
4           Data pin 1
5           Data pin 2

Este é um dispositivo USB, assim como o OpenBCI. Então, por que não consegui escrever um aplicativo (em qualquer idioma) que também apenas lesse / gravasse diretamente na porta USB / serial (novamente, talvez usando JSerialComm ou similar)? Quando quero que o aplicativo comece a capturar dados de vídeo da webcam, envio bytes para a porta serial ( novamente via JSerialComm, etc.) que ativam o Pin # 3 alto e ativam subsequentemente a leitura dos dados de vídeo dos pinos 4 e 5.

Acho que não entendo por que o OpenBCI não possui ou precisa de um driver de dispositivo, enquanto a webcam (ou qualquer outro dispositivo USB padrão como impressora, mouse, teclado etc.) possui. Desde já, obrigado!

Respostas:


5

Existem vários motivos pelos quais você pode querer / precisar escrever um driver de dispositivo.

  1. você está criando um dispositivo que se encaixa em uma categoria genérica. Uma impressora, um scanner, uma webcam, um controlador de armazenamento etc. Você deseja gravar um driver de dispositivo para que aplicativos genéricos possam conversar com seu dispositivo sem precisar modificá-los.

  2. você deseja que um dispositivo seja utilizável por vários aplicativos em execução ao mesmo tempo. O driver do dispositivo precisa arbitrar o uso do dispositivo entre os aplicativos. Isso normalmente significa ter um nível mais alto de entendimento do dispositivo do que "fluxo de bytes".

  3. O design do hardware e / ou sistema operacional pode simplesmente forçá-lo a fazê-lo. O Windows precisa de algum tipo de driver vinculado a um dispositivo USB para que ele funcione; você pode abusar do driver oculto, mas apenas se o hardware estiver configurado para reivindicar ser um dispositivo HID. É possível usar um driver de dispositivo USB para serial existente, mas apenas se o dispositivo apresentar e apresentar uma interface semelhante a uma porta serial. Se o seu dispositivo estiver em um barramento de memória mapeada com DMA direta, você precisará que seu driver esteja no kernel para configurar corretamente as transações do DMA.

Da mesma forma, existem razões para evitar escrever um driver de dispositivo, especialmente um driver de dispositivo no modo kernel.

  1. Escrever código no modo kernel é complicado / especialista e, se você estragar tudo, derruba todo o sistema, não apenas o seu programa. Mesmo que o sistema operacional ofereça a capacidade de gravar seu driver no modo de usuário, isso pode significar a programação em um ambiente e linguagem desconhecidos.

  2. A implantação é muito mais difícil. No lado do Windows, a MS aumentou recentemente os requisitos de assinatura do driver. No lado do Linux, as interfaces do usuário são muito mais estáveis ​​do que as do lado do kernel e os módulos do kernel praticamente precisam ser reconstruídos para cada nova versão do kernel.

  3. Se o seu código estiver dividido em um aplicativo e um driver, você deverá se preocupar com a situação de versões mistas de aplicativos / drivers.

Em seguida, tudo se resume a um ato de equilíbrio cujas razões são mais convincentes para um dispositivo em particular.


Obrigado @ Peter Green (+1) - tudo o que você disse faz todo o sentido, exceto uma coisa. No seu primeiro marcador, você diz " Você deseja gravar um driver de dispositivo para que aplicativos genéricos possam falar com o seu dispositivo " . Mas esses aplicativos genéricos não podiam simplesmente ler / gravar diretamente na porta USB / serial (por meio de uma biblioteca de comunicação serial como JSerialComm)? Foi isso que fiz com sucesso com o OpenBCI e Java. Obrigado novamente!
smeeb

Imagine que você tem cem aplicativos diferentes que desejam imprimir e cem impressoras diferentes. Antes que os sistemas operacionais tivessem drivers de impressora, alguém teria que escrever o código de impressão para cada combinação de aplicativo e impressora. São dez mil pedaços de código.
Peter Green

Por outro lado, com um sistema operacional com uma estrutura de driver de impressora, cada aplicativo precisa apenas de um pedaço de código de impressão e cada impressora precisa apenas de um driver.
Peter Green

7

Drivers de dispositivo são uma camada de abstração. Eles permitem que você converse com o dispositivo sem conhecer a mecânica do sistema operacional de baixo nível ou as idiossincrasias específicas do dispositivo. Eles também fornecem uma interface de alto nível conhecida para o sistema operacional, uma interface exatamente igual para dispositivos semelhantes.

Sem um driver de dispositivo, você precisaria essencialmente escrever um, e esse driver seria completamente diferente para cada modelo de dispositivo. Em vez disso, o fabricante normalmente fornece um driver de dispositivo para você, que traduz da interface específica de hardware desse dispositivo específico para a interface de alto nível conhecida do sistema operacional.

Esse arranjo fornece vários benefícios:

  1. Todos os softwares criados para esses dispositivos funcionarão com qualquer dispositivo da classe de dispositivos (por exemplo, webcams), se forem criados na mesma interface comum de alto nível.

  2. Características específicas do dispositivo, como tempo, manipulação de sinal e protocolos de dados, são abstraídas do usuário.

  3. Os drivers de dispositivo fornecem uma camada de segurança. Enquanto o driver do dispositivo normalmente opera no kernel (onde os problemas podem travar o sistema operacional), o aplicativo do usuário normalmente se comunica com o driver do dispositivo no espaço do usuário, onde um problema simplesmente trava o aplicativo.

  4. Os drivers de dispositivo têm acesso a ferramentas de gerenciamento como o Painel de Controle.

Às vezes, você pode alinhar seu dispositivo com uma API como a especificação HID (Human Interface Device), e nem precisa instalar outro driver de dispositivo.

Não examinei o software OpenBCI em detalhes, mas suspeito que ele seja ou possua um driver de dispositivo. A maioria dos sistemas operacionais modernos nem permite que você fale diretamente com as portas; você deve passar pelo sistema operacional.


Obrigado @Rober Harvey (+1) - tudo o que você diz faz sentido. No entanto, li com êxito os dados do OpenBCI na minha porta COM (eu tenho um Macbook Pro) usando JSerialComm diretamente. Eu não estou dizendo que os drivers de dispositivo não foram magicamente instalado em algum lugar, mas eu nunca tive que fazer outra coisa senão integrar meu aplicativo Java com JSerialComm e, em seguida, ligar o meu stick USB do OpenBCI no.
smeeb

1
De certa forma, o JSerialComm está agindo como um driver para o seu próprio código.
Andres F.

Obrigado @AndresF. (+1) isso é uma espécie do que eu estava dirigindo no com todo o meu followup Qs :-)
smeeb

3

O motivo pelo qual você precisa instalar o driver da sua webcam é porque ela é possivelmente mais nova que o seu sistema operacional ou seus drivers não estão incluídos no seu sistema operacional. Muitas webcams não exigem a instalação de drivers, pois muitas usam plataformas existentes há muito tempo, e os drivers vêm com o sistema operacional. Encontre uma webcam da Logitech de 15 anos e conecte-a, e você tem uma boa chance de descobrir que pode usá-la sem instalar nada *

As portas seriais quase sempre têm drivers incluídos no seu sistema operacional, porque o hardware das portas seriais é basicamente o mesmo há 20 anos.

Os dois tipos de drivers, no entanto, fornecem acesso programático a diferentes abstrações de hardware diferente. É por isso que você não pode, no espaço do usuário, conversar com uma webcam através de fluxos de bytes entrando e saindo. Em vez disso, a webcam "fala" DirectShow ou Video4Linux ou qualquer abstração de vídeo que seu sistema operacional esteja usando *

O inverso é verdadeiro novamente, a porta serial apenas 'fala' fluxos de bytes, portanto você não pode solicitar quadros de vídeo e obtê-los do driver.

* Alguns drivers exigem que você instale drivers especiais, independentemente da idade, para usar totalmente o dispositivo, pois às vezes os dispositivos têm recursos que não são suportados no DirectShow / etc, como webcams que podem movimentar, inclinar e aplicar zoom ou fazer reconhecimento facial, ou outras coisas. Mas não pense muito sobre isso, pois esses são casos especiais.


3

Várias das outras respostas têm pontos muito bons sobre os benefícios de separar seu aplicativo da interface do dispositivo e da abstração, mas há dois pontos que não foram mencionados - privilégios de desempenho e acesso .

atuação

Os drivers de dispositivo geralmente aguardam uma entrada ou uma interrupção para solicitar que eles leiam uma entrada. Portanto, quando você estiver escrevendo seu próprio código, precisará fazer um dos seguintes procedimentos:

  • Ao pesquisar no dispositivo, o restante do seu código deve garantir que isso aconteça com bastante frequência
  • O manuseio interrompe essa é uma habilidade especializada e se você precisar conversar com mais de um dispositivo
  • Habilidades especializadas de multiencadeamento ou multiprocessamento novamente, nem todos os idiomas têm um bom suporte e, se você deseja dividir o manipulador de dispositivos em um encadeamento separado, está no caminho certo para um driver de dispositivo

Privilégios de acesso

Em muitos sistemas operacionais, e até mesmo em algumas metas bare metal montagem nível do acesso ao hardware e locais de memória absoluto exige privilégios elevados de super usuário, raiz, direitos de administrador - Não é uma boa prática para o seu aplicativo , e seu usuário, para exigir tais direitos, mas se implementar suas próprias interfaces de dispositivo, precisará delas.


1

Quando seu software se destina apenas a funcionar com uma peça específica de hardware, você não precisa de um driver de dispositivo adicional. No entanto, se houvesse outro hardware de leitor de ondas cerebrais com interfaces diferentes que você desejasse oferecer suporte, um driver de dispositivo adicional seria útil. Tudo depende do escopo do seu projeto. Para uso amador, não há necessidade de criar um driver de dispositivo extra.


0

Basicamente, a resposta é: quando você não está falando com um driver de dispositivo, seu programa é o driver de dispositivo.

Os drivers de dispositivo facilitam a conversa com o hardware, mas também são restritivos: você só pode fazer o que o driver de dispositivo oferece.

Mas, em geral: se você precisar de total liberdade, fale diretamente com uma porta. Isso geralmente faz com que o software fique entrelaçado com o hardware como em: ele funcionará apenas para o dispositivo específico para o qual você foi criado.

Se não houver um driver de dispositivo disponível, obviamente você precisará falar diretamente com o seu hardware.

Se os drivers de dispositivo disponíveis não forem bons o suficiente, você conversará diretamente com seu hardware.

Basicamente, em todos os outros casos, você usa um driver de dispositivo. (mas lembre-se, mesmo que você não use um driver de dispositivo, você ainda o usa, apenas o criou)


0

Na verdade, você está perdendo alguns blocos importantes no diagrama. O "receptor de RF (pen drive)" não envia os dados para a "porta serial / USB". Primeiro, não há "porta USB". O dongle RF envia dados USB para o "tubo USB" em resposta a solicitações de host. O host gera solicitação via driver USB do controlador de host, ehci.sys ou algo assim. O driver host forma pacotes USB e obedece ao protocolo USB.

O conteúdo do pacote para o controlador host, no entanto, é iniciado por um driver genérico da classe COM, outra camada de software (também padrão do sistema operacional). Este é o "driver de dispositivo", que emula uma porta COM padrão e mapeia / converte as leituras / gravações da porta em solicitações USB, de acordo com as definições / formatos de classe. A parte da biblioteca Java, JSerialComm, é apenas uma interface semelhante a um fluxo (em buffer) para essa porta COM virtual emulada.

Como se pode ver, não há nada como "falar diretamente com o seu hardware" ou "gravação direta na porta COM"; existem várias camadas de portas virtuais. É impossível gerar uma única alternância no barramento USB sem definir estruturas de dados enormes, muito específicas e complicadas (contexto do dispositivo / slot, buffers de anel de transferência, anel de comando, anel de eventos etc.) na memória principal e configurar o controlador host USB para lista de processamento e, em seguida, tocando em um registro de campainha para iniciar uma transação USB. Tudo isso é realizado com duas camadas de drivers, controlador host e dispositivo, com milhares de linhas de código e meia dúzia de anos de desenvolvimento e depuração. Para entender e apreciar melhor essa camada oculta de serviços, consulte a Microsoft .


0

A interface para exportar dados do espaço do kernel para o espaço do usuário não é muito expressiva. Em particular, não é digitado. Você obtém uma sequência de bytes e seu programa de espaço do usuário precisa convertê-los em algo com significado semântico. Portanto, os drivers de dispositivo geralmente são combinados com as bibliotecas de espaço do usuário.

Se você incluísse um driver de dispositivo OpenBCI com espaço no kernel sobre o driver serial genérico, isso basicamente lhe daria a capacidade de converter uma maneira de sequenciar os bytes em uma maneira diferente de sequenciar os bytes. Se você pudesse fazer isso, qual sequência diferente você escolheria? Se uma sequência diferente seria melhor, por que você não incorporou essa sequência melhor no firmware OpenBCI?

Você pode ter motivos de desempenho para escrever um driver de modo de kernel específico do dispositivo ou pode precisar traduzir para se adaptar a uma interface existente, mas, caso contrário, obterá muito mais valor ao criar uma biblioteca de espaço de usuário expressiva como o OpenBCI_Python do que fazer o que equivaleria a um driver de modo kernel muito anêmico.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.