Beschreibung
Beginnen wir die Diskussion mit dem Charakter -Treiber unter Linux. Kernel kategorisiert die Treiber in drei Kategorien:
Charakterfahrer - Dies sind die Treiber, die nicht zu viel Daten haben, um damit umzugehen. Nur wenige Beispiele für Charakter -Treiber sind Touchscreen -Treiber, UART -Treiber usw. Dies alle sind die Charakter -Treiber, da die Datenübertragung durch Zeichen durch Zeichen durchgeführt wird.
Blocktreiber - Dies sind die Treiber, die mit zu vielen Daten zu tun haben. Die Datenübertragung erfolgt blockiert blockiert, da zu viel Daten übertragen werden müssen. Beispiel für Blocktreiber sind SATA, NVME usw.
Netzwerktreiber - Dies sind die Treiber, die in der Netzwerkgruppe der Fahrer funktionieren. Hier erfolgt die Datenübertragung in Form von Datenpaketen. Funkfahrer wie Atheros fallen in diese Kategorie.
In dieser Diskussion werden wir uns nur auf den Charakter -Treiber konzentrieren.
Als Beispiel werden wir die einfachen Lese-/Schreibvorgänge nehmen, um den grundlegenden Charakter -Treiber zu verstehen. Im Allgemeinen hat jeder Gerätetreiber diese beiden Mindestvorgänge. Zusätzlicher Betrieb kann geöffnet sein, schließen, ioctl usw. In unserem Beispiel hat unser Fahrer den Speicher im Kernelraum. Dieser Speicher wird vom Gerätetreiber zugewiesen und kann als Gerätespeicher betrachtet werden. Der Treiber erstellt die Geräteschnittstelle im Verzeichnis /dev, das von den Benutzerraumprogrammen verwendet werden kann, um auf den Treiber zuzugreifen und die vom Treiber unterstützten Vorgänge auszuführen. Für das UserSpace -Programm sind diese Vorgänge genau wie bei allen anderen Dateivorgängen. Das Benutzerraumprogramm muss die Gerätedatei öffnen, um die Instanz des Geräts zu erhalten. Wenn der Benutzer den Lesevorgang ausführen möchte, kann der Read -System -Aufruf dazu verwendet werden. Wenn der Benutzer den Schreibvorgang ausführen möchte, kann der Schreibsystemaufruf verwendet werden, um den Schreibvorgang zu erreichen.
Charakterfahrer
Betrachten wir, um den Charakter -Treiber mit den Lesen/Schreibdatenvorgängen zu implementieren.
Wir beginnen mit der Instanz der Gerätedaten. In unserem Fall handelt es sich um "struct cdrv_device_data".
Wenn wir die Felder dieser Struktur sehen, haben wir CDEV, Gerätepuffer, Puffergröße, Klasseninstanz und Geräteobjekt. Dies sind die Mindestfelder, auf denen wir den Charakter -Treiber implementieren sollten. Es hängt von dem Implementierer ab, auf dem zusätzliche Felder hinzufügen möchten, um die Funktion des Treibers zu verbessern. Hier versuchen wir, die Mindestfunktion zu erreichen.
Als nächstes sollten wir das Objekt der Gerätedatenstruktur erstellen. Wir verwenden den Anweisungen, um den Speicher auf statische Weise zuzuweisen.
struktur cdrv_device_data char_device [cdrv_max_minors];
Dieser Speicher kann auch dynamisch mit „Kmalloc“ zugewiesen werden. Lassen Sie uns die Implementierung so einfach wie möglich halten.
Wir sollten die Implementierung von Lese- und Schreibfunktionen nehmen. Der Prototyp dieser beiden Funktionen wird durch das Gerätetreiber -Framework von Linux definiert. Die Implementierung dieser Funktionen muss Benutzer definiert werden. In unserem Fall haben wir Folgendes berücksichtigt:
Lesen Sie: Die Operation, um die Daten aus dem Treiberspeicher in den UserSpace zu erhalten.
static ssize_t cdrv_read (strukturdatei *Datei, char __user *user_buffer, size_t size, loff_t *offset);
Schreiben Sie: Die Operation zum Speichern der Daten im Treiberspeicher vom UserSpace im Treiberspeicher.
static ssize_t cdrv_write (strukturdatei *Datei, const char __user *user_buffer, size_t size, loff_t *offset);
Beide Operationen, lesen und schreiben, müssen als Teil von struct File_operations cdrv_fops registriert werden. Diese sind im Rahmen der Linux -Geräte -Treiber im Init_cdrv () des Treibers registriert. In der Funktion init_cdrv () werden alle Setup -Aufgaben ausgeführt. Nur wenige Aufgaben sind wie folgt:
Der vollständige Beispielcode für den Treiber für den grundlegenden Zeichen für Zeichen ist wie folgt:
#enthaltenWir erstellen ein Beispiel -Makefile, um den grundlegenden Charakter -Treiber und die Test -App zu kompilieren. Unser Treibercode ist in CRDV vorhanden.c und der Test -App -Code ist in cdrv_app vorhanden.C.
OBJ-M+= CDRV.ÖNachdem die Ausstellung an das Makefile erfolgt, sollten wir die folgenden Protokolle erhalten. Wir bekommen auch den CDRV.KO und ausführbare Datei (cdrv_app) für unsere Test -App:
root@haxv-shrathore-2:/home/cienauser/kernel_articles#Hier ist der Beispielcode für die Test -App. Dieser Code implementiert die Test -App, die die vom CDRV -Treiber erstellte Gerätedatei öffnet und die „Testdaten“ darauf schreibt. Anschließend liest es die Daten des Treibers und druckt sie nach dem Lesen der Daten als „Testdaten“ aus.
#enthaltenSobald wir alle Dinge vorhanden haben, können wir den folgenden Befehl verwenden, um den grundlegenden Charakter -Treiber in den Linux -Kernel einzulegen:
root@haxv-shrathore-2:/home/cienauser/kernel_articles# Insmod CDRV.koNach dem Einfügen des Moduls erhalten wir die folgenden Nachrichten mit DMESG und erhalten die in /dev as /dev /cdrv_dev erstellte Gerätedatei:
root@haxv-shrathore-2:/home/cienauser/kernel_articles# dmesgFühren Sie nun die Test -App mit dem folgenden Befehl in der Linux -Shell aus. Die endgültige Nachricht druckt die Lesedaten aus dem Treiber, die genau das entsprechen wie das, was wir in der Schreibvorlage geschrieben haben:
root@haxv-shrathore-2:/home/cienauser/kernel_articles# ./cdrv_appWir haben nur wenige zusätzliche Drucke im Schreib- und Lesweg, die mit Hilfe des DMESG -Befehls gesehen werden können. Wenn wir den DMESG -Befehl ausgeben, erhalten wir die folgende Ausgabe:
root@haxv-shrathore-2:/home/cienauser/kernel_articles# dmesgAbschluss
Wir haben den grundlegenden Charakter -Treiber durchlaufen, der die grundlegenden Schreib- und Lesevorgänge implementiert. Wir haben auch das Beispiel -Makefile besprochen, um das Modul zusammen mit der Test -App zu kompilieren. Die Test -App wurde geschrieben und besprochen, um die Schreibvorgänge aus dem Benutzerbereich auszuführen und zu lesen. Wir haben auch die Zusammenstellung und Ausführung des Modul- und Test -App mit Protokollen demonstriert. Die Test -App schreibt nur wenige Bytes von Testdaten und liest sie dann zurück. Der Benutzer kann beide Daten vergleichen, um die korrekte Funktion des Treibers und der Test -App zu bestätigen.