Wann wird ein Gerätetreiber benötigt und wann kann direkt auf den Port gelesen / geschrieben werden?

8

Es fällt mir schwer zu verstehen, wann Gerätetreiber benötigt werden und wann es in Ordnung ist, direkt mit einem Port-Controller über das vom Betriebssystem bereitgestellte serielle / parallele / USB / etc. Zu sprechen. Treiber.

Zum Beispiel Beispiel 1 : nehmen wir OpenBCI , eine Open - Source - Hardware BCI , die Sie EEG + EKG ( "Gehirnwellen") Lesungen lesen können. Das OpenBCI-Headset sendet HF-Signale an ein an Ihr Gerät angeschlossenes USB-Laufwerk. Anschließend können Sie Ihre eigene Software schreiben, um die an diesen Anschluss eingehenden Daten zu lesen. Auf diese Weise können Sie Ihre eigenen Gehirnwellen lesen und Gehirnwellendaten auf der App-Ebene interpretieren. Ziemlich cool. Um Ihre „Streaming“ brainwave Daten zu lesen, müssen Sie nicht nur von Ihrem seriell Port lesen (die seriellen Treiber vom Betriebssystem zur Verfügung gestellt), aber Sie müssen interpretieren die Daten in entsprechend mit den OpenBCI Spezifikationen . Der Stapel sieht also so aus:

Geben Sie hier die Bildbeschreibung ein

Aber nirgendwo hier haben wir einen "Gerätetreiber", der speziell für das OpenBCI-Headset ist. Nur der serielle Treiber, der zum Lesen von Datenbytes erforderlich ist, und dann müssen Sie interpretieren, was diese Bytes in Ihrer App bedeuten. Wenn ich beispielsweise möchte, dass eine Java-App Gehirnwellendaten interpretiert, kann ich JSerialComm verwenden , um die Daten von meinem lokalen COM-Port (oder von USB auf dem lokalen System) zu lesen. Es wäre dann zu meiner App bis Interpet , dass Daten gemäß den Spezifikationen des oben aufgeführt ist .

Nun Beispiel 2 : Eine Logitech USB-Webcam wie diese . Hier müssen Sie die Gerätetreiber der Webcam auf Ihrem Computer installieren, damit Sie sie verwenden können. Ich frage mich warum. Stellen wir uns vor (drücken Sie einfach einen Moment auf die Schaltfläche " Ich glaube! "), Dass die Pinbelegung für diese Webcam einfach dumm war:

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

Dies ist ein USB-Gerät, genau wie das OpenBCI. Warum konnte ich keine App (in einer beliebigen Sprache) schreiben, die auch nur direkt auf den USB- / seriellen Anschluss liest / schreibt (wieder möglicherweise mit JSerialComm oder ähnlichem)? Wenn die App mit der Erfassung von Webcam-Videodaten beginnen soll, sende ich Bytes an die serielle Schnittstelle ( erneut über JSerialComm usw.), die Pin 3 hoch / einschalten und anschließend die Videodaten von Pins 4 und 5 lesen.

Ich glaube, ich verstehe nicht, warum OpenBCI keinen Gerätetreiber hat oder benötigt, wohingegen die Webcam (oder ein anderes Standard-USB-Gerät wie ein Drucker, eine Maus, eine Tastatur usw.) dies tut. Danke im Voraus!

smeeb
quelle

Antworten:

5

Es gibt mehrere Gründe, warum Sie möglicherweise einen Gerätetreiber schreiben möchten / müssen.

  1. Sie erstellen ein Gerät, das in eine generische Kategorie passt. Ein Drucker, ein Scanner, eine Webcam, ein Speichercontroller usw. Sie möchten einen Gerätetreiber schreiben, damit generische Anwendungen mit Ihrem Gerät kommunizieren können, ohne die Anwendungen ändern zu müssen.

  2. Sie möchten, dass ein Gerät von mehreren Anwendungen verwendet werden kann, die gleichzeitig ausgeführt werden. Der Gerätetreiber muss die Verwendung des Geräts auf die Anwendungen verteilen. Dies bedeutet normalerweise ein höheres Verständnis des Geräts als "Bytestrom".

  3. Das Hardware- und / oder Betriebssystemdesign kann Sie einfach dazu zwingen. Windows benötigt eine Art Treiber, der an ein USB-Gerät gebunden ist, damit es überhaupt funktioniert. Sie können den versteckten Treiber missbrauchen, aber nur, wenn die Hardware so eingerichtet ist, dass sie behauptet, ein verstecktes Gerät zu sein. Sie können möglicherweise einen vorhandenen USB-zu-Seriell-Gerätetreiber verwenden, jedoch nur, wenn Ihr Gerät eine Schnittstelle aufweist, die wie eine serielle Schnittstelle aussieht. Befindet sich Ihr Gerät auf einem Speicher-Bus mit direktem DMA, muss sich Ihr Treiber im Kernel befinden, um die DMA-Transaktionen korrekt einzurichten.

Ebenso gibt es Gründe, das Schreiben eines Gerätetreibers, insbesondere eines Gerätetreibers im Kernelmodus, zu vermeiden.

  1. Das Schreiben von Kernel-Modus-Code ist schwierig / spezialisiert, und wenn Sie es vermasseln, wird das gesamte System heruntergefahren, nicht nur Ihr Programm. Selbst wenn das Betriebssystem die Möglichkeit bietet, Ihren Treiber im Benutzermodus zu schreiben, kann dies bedeuten, dass Sie in einer unbekannten Sprache und Umgebung programmieren.

  2. Die Bereitstellung ist viel mehr ein Schmerz. Auf der Windows-Seite hat MS kürzlich die Anforderungen an die Treibersignatur erhöht. Auf der Linux-Seite sind die Userland-Schnittstellen weitaus stabiler als die kernelseitigen, und die Kernel-Module müssen für jede neue Kernel-Version neu erstellt werden.

  3. Wenn Ihr Code in eine Anwendung und einen Treiber aufgeteilt ist, müssen Sie sich über die Situation gemischter Anwendungs- / Treiberversionen Gedanken machen.

Es kommt dann auf einen Spagat an, dessen Gründe für ein bestimmtes Gerät zwingender sind.

Peter Green
quelle
Danke @Peter Green (+1) - alles, was Sie gesagt haben, macht vollkommen Sinn, bis auf eine Sache. In Ihrem ersten Aufzählungszeichen sagen Sie: " Sie möchten einen Gerätetreiber schreiben, damit generische Anwendungen mit Ihrem Gerät kommunizieren können. " Diese generischen Anwendungen konnten jedoch nicht einfach direkt auf den USB- / seriellen Anschluss lesen / schreiben (über eine serielle Kommunikationsbibliothek wie) JSerialComm)? Das habe ich mit OpenBCI und Java erfolgreich gemacht. Danke noch einmal!
Smeeb
Stellen Sie sich vor, Sie haben hundert verschiedene Anwendungen, die gedruckt werden sollen, und hundert verschiedene Drucker. Bevor Betriebssysteme Druckertreiber hatten, hätte jemand Druckcode für jede Kombination aus Anwendung und Drucker schreiben müssen. Das sind zehntausend Codestücke.
Peter Green
Andererseits benötigt bei einem Betriebssystem mit einem Druckertreiber-Framework jede Anwendung nur einen Block Druckcode und jeder Drucker benötigt nur einen Treiber.
Peter Green
7

Gerätetreiber sind eine Abstraktionsschicht. Mit ihnen können Sie mit dem Gerät kommunizieren, ohne die Mechanik des Betriebssystems auf niedriger Ebene oder gerätespezifische Besonderheiten zu kennen. Sie bieten auch eine bekannte, übergeordnete Schnittstelle zum Betriebssystem, eine Schnittstelle, die für ähnliche Geräte genau gleich ist.

Ohne einen Gerätetreiber müssten Sie im Wesentlichen selbst einen schreiben, und dieser Gerätetreiber wäre für jedes Gerätemodell völlig anders . Stattdessen stellt der Hersteller in der Regel einen Gerätetreiber für Sie bereit, der von der hardwarespezifischen Schnittstelle dieses bestimmten Geräts in die bekannte übergeordnete Schnittstelle für das Betriebssystem übersetzt wird.

Diese Anordnung bietet mehrere Vorteile:

  1. Für diese Geräte geschriebene Software funktioniert mit allen Geräten der Geräteklasse (z. B. Webcams), wenn sie über dieselbe gemeinsame Schnittstelle auf hoher Ebene geschrieben wurde.

  2. Gerätespezifische Merkmale wie Timing, Signalverarbeitung und Datenprotokolle werden vom Benutzer weg abstrahiert.

  3. Gerätetreiber bieten eine Sicherheitsstufe. Während der Gerätetreiber normalerweise im Kernel ausgeführt wird (wo Probleme das Betriebssystem zum Absturz bringen können), kommuniziert die Benutzeranwendung normalerweise mit dem Gerätetreiber im Benutzerbereich, wo ein Problem lediglich die Anwendung zum Absturz bringt.

  4. Gerätetreiber haben Zugriff auf Verwaltungstools wie die Systemsteuerung.

Manchmal können Sie Ihr Gerät an einer API wie der HID-Spezifikation (Human Interface Device) ausrichten, und Sie müssen nicht einmal einen anderen Gerätetreiber installieren.

Ich habe mir die OpenBCI-Software nicht im Detail angesehen, aber ich vermute, dass es sich tatsächlich um einen Gerätetreiber handelt oder handelt. Bei den meisten modernen Betriebssystemen können Sie nicht einmal direkt mit Ports kommunizieren. Sie müssen das Betriebssystem durchlaufen.

Robert Harvey
quelle
Danke @Rober Harvey (+1) - alles was du sagst macht Sinn. Ich habe jedoch erfolgreich OpenBCI-Daten von meinem COM-Port (ich habe ein Macbook Pro) mit JSerialComm direkt gelesen. Ich sage nicht, dass Gerätetreiber nicht irgendwie magisch irgendwo installiert wurden, aber ich musste nie etwas anderes tun, als meine Java-App in JSerialComm zu integrieren und dann den USB-Stick meines OpenBCI anzuschließen.
smeeb
1
@smeeb In gewisser Weise verhält sich JSerialComm wie ein Treiber für Ihren eigenen Code.
Andres F.
Danke @AndresF. (+1) das ist eine Art, was ich mit all meinen Follow-up-
Fragen
3

Der Grund, warum Sie den Treiber für Ihre Webcam installieren müssen, liegt darin, dass Ihre Webcam möglicherweise neuer als Ihr Betriebssystem ist oder die Treiber nicht in Ihrem Betriebssystem enthalten sind. Bei vielen Webcams müssen Sie keine Treiber installieren, da viele Webcams Plattformen verwenden, die es schon lange gibt, und Treiber für sie mit Ihrem Betriebssystem geliefert werden. Suchen Sie eine 15 Jahre alte Logitech-Webcam und schließen Sie sie an. Sie haben gute Chancen festzustellen, dass Sie sie verwenden können, ohne etwas zu installieren. *

Bei seriellen Ports sind fast immer Treiber in Ihrem Betriebssystem enthalten, da die Hardware für serielle Ports seit 20 Jahren im Wesentlichen dieselbe ist.

Die beiden Treiberarten bieten jedoch programmgesteuerten Zugriff auf unterschiedliche Abstraktionen unterschiedlicher Hardware. Aus diesem Grund können Sie im Benutzerbereich nicht über ein- und ausgehende Byteströme mit einer Webcam kommunizieren. Stattdessen "spricht" die Webcam DirectShow oder Video4Linux oder die von Ihrem Betriebssystem verwendete Videoabstraktion *

Das Gegenteil ist wieder der Fall: Die serielle Schnittstelle "spricht" nur Byteströme, sodass Sie keine Videobilder anfordern und vom Treiber abrufen können.

* Bei einigen Treibern müssen Sie unabhängig vom Alter spezielle Treiber installieren, um das Gerät vollständig nutzen zu können, da Geräte manchmal über Funktionen verfügen, die in DirectShow / etc nicht unterstützt werden, z. B. Webcams, die schwenken, neigen und zoomen oder Gesichtserkennung durchführen können. oder andere Sachen. Aber denken Sie nicht zu viel darüber nach, da dies Sonderfälle sind.

Whatsisname
quelle
3

Einige der anderen Antworten haben sehr gute Punkte zu den Vorteilen der Trennung Ihrer Anwendung von der Geräteschnittstelle und der Abstraktion, aber es gibt zwei Punkte, die nicht erwähnt wurden - Leistung und Zugriffsrechte .

Performance

Gerätetreiber warten häufig auf eine Eingabe oder einen Interrupt, um sie aufzufordern, eine Eingabe zu lesen. Wenn Sie also Ihren eigenen Code schreiben, müssen Sie einen der folgenden Schritte ausführen:

  • Wenn Sie das Gerät abfragen, muss der Rest Ihres Codes sicherstellen, dass dies häufig genug geschieht
  • Die Handhabung von Interrupts ist eine Spezialfähigkeit und was ist, wenn Sie mit mehr als einem Gerät sprechen müssen
  • Multi-Threading oder Multi-Processing wieder Fachkenntnisse, nicht alle Sprachen haben eine gute Unterstützung und wenn Sie Ihren Geräte-Handler in einen separaten Thread aufteilen wollen, sind Sie meistens auf dem Weg zu einem Gerätetreiber

Zugriffsrechte

Auf vielen Betriebssystemen und sogar in einigen Montageebene blanken Metallziele der Zugriff auf Hardware und absolute Speicherplätze erfordert Zugriffsrechte unter Superuser root, Admin - Rechte - Es ist nicht eine gute Praxis für Ihre ist Anwendung , und seine Benutzer zu verlangen , so Rechte, aber wenn es seine eigenen Geräteschnittstellen implementiert, muss es diese haben .

Steve Barnes
quelle
1

Wenn Ihre Software nur für eine bestimmte Hardware vorgesehen ist, benötigen Sie keinen zusätzlichen Gerätetreiber. Wenn es jedoch andere Brainwave-Reader-Hardware mit unterschiedlichen Schnittstellen gibt, die Sie unterstützen möchten, ist ein zusätzlicher Gerätetreiber hilfreich. Es hängt alles vom Umfang Ihres Projekts ab. Für Hobbyisten ist es nicht erforderlich, einen zusätzlichen Gerätetreiber zu erstellen.

user230118
quelle
0

Grundsätzlich lautet die Antwort: Wenn Sie nicht mit einem Gerätetreiber sprechen, ist Ihr Programm der Gerätetreiber.

Gerätetreiber erleichtern das Sprechen mit Hardware, sind aber auch einschränkend: Sie können nur die Aufgaben ausführen, die der Gerätetreiber bietet.

Aber im Allgemeinen: Wenn Sie völlige Freiheit brauchen, sprechen Sie direkt mit einem Port. Dadurch ist Ihre Software häufig wie in: Mit der Hardware verflochten: Sie funktioniert nur für das Gerät, für das Sie sie erstellt haben.

Wenn kein Gerätetreiber verfügbar ist, müssen Sie natürlich direkt mit Ihrer Hardware sprechen.

Wenn die verfügbaren Gerätetreiber nicht gut genug sind, sprechen Sie direkt mit Ihrer Hardware.

Grundsätzlich verwenden Sie in allen anderen Fällen einen Gerätetreiber. (Aber denken Sie daran, auch wenn Sie keinen Gerätetreiber verwenden, den Sie immer noch verwenden, haben Sie ihn einfach selbst erstellt.)

Pieter B.
quelle
0

Tatsächlich fehlen Ihnen einige wichtige Blöcke im Diagramm. Der "RF-Empfänger (USB-Stick)" sendet die Daten nicht an den "seriellen / USB-Anschluss". Erstens gibt es keinen "USB-Anschluss". Der RF-Dongle sendet USB-Daten als Antwort auf Host-Anforderungen in eine "USB-Pipe". Der Host generiert eine Anfrage über den USB-Treiber des Host-Controllers, ehci.sys oder ähnliches. Der Host-Treiber bildet USB-Pakete und befolgt das USB-Protokoll.

Der Paketinhalt für den Host-Controller wird jedoch von einem generischen COM-Klassentreiber initiiert, einer weiteren Softwareschicht (ebenfalls ein Betriebssystemstandard). Dies ist der "Gerätetreiber", der einen Standard-COM-Port emuliert und die Port-Lese- / Schreibvorgänge gemäß Klassendefinitionen / -formaten in USB-Anforderungen abbildet / konvertiert. Das Java-Bibliotheksstück JSerialComm ist nur eine streamähnliche (gepufferte) Schnittstelle zu diesem emulierten virtuellen COM-Port.

Wie man sehen kann, gibt es nichts Schöneres als "direkt mit Ihrer Hardware sprechen" oder "direkt auf den COM-Port schreiben". Es gibt mehrere Ebenen virtueller Ports. Es ist unmöglich, einen einzelnen Umschalter auf dem USB-Bus zu generieren, ohne große, sehr spezifische und komplizierte Datenstrukturen (Geräte- / Steckplatzkontext, Übertragungsringpuffer, Befehlsring, Ereignisring usw.) im Hauptspeicher festzulegen und den USB-Host-Controller für die Verbindung zu konfigurieren Listenverarbeitung und dann Klingeln eines Klingelregisters, um eine USB-Transaktion zu starten. All dies wird mit zwei Treiberschichten, Host-Controller und Gerät, mit vielen tausend Codezeilen und einem halben Dutzend Jahren Entwicklungs- und Debug-Erfahrung erreicht. Wenden Sie sich an Microsoft , um diese verborgene Schicht von Diensten besser zu verstehen und zu verstehen .

Ale..chenski
quelle
0

Die Schnittstelle zum Exportieren von Daten aus dem Kernel-Space in den User-Space ist nicht sehr aussagekräftig. Insbesondere ist es untypisiert. Sie erhalten eine Folge von Bytes und Ihr User-Space-Programm muss diese Bytes dann in etwas mit semantischer Bedeutung konvertieren. Daher werden Gerätetreiber normalerweise mit Benutzerbereichsbibliotheken gekoppelt.

Wenn Sie einen OpenBCI-Gerätetreiber für den Kernelspeicherplatz zusätzlich zum generischen seriellen Treiber hinzufügen, können Sie im Grunde eine Möglichkeit zum Sequenzieren der Bytes in eine andere Methode zum Sequenzieren der Bytes konvertieren. Wenn Sie dies tun könnten, welche andere Reihenfolge würden Sie wählen? Wenn eine andere Sequenz besser wäre, warum haben Sie diese bessere Sequenz nicht überhaupt in die OpenBCI-Firmware eingebaut?

Möglicherweise haben Sie Leistungsgründe, um einen gerätespezifischen Kernelmodustreiber zu schreiben, oder Sie müssen möglicherweise übersetzen, um sich an eine vorhandene Schnittstelle anzupassen. Andernfalls wird die Erstellung einer ausdrucksstarken Benutzerbereichsbibliothek wie OpenBCI_Python wesentlich wertvoller als zu machen, was einem sehr anämischen Kernel-Modus-Treiber gleichkommen würde.

Karl Bielefeldt
quelle