/****************** * Erweiterter Zeichengerätetreiber *********************/ (1)ioctl Neben dem Lesen und Schreiben auf Geräten erfordern die meisten Treiber die Möglichkeit, verschiedene Arten der Hardwaresteuerung über Gerätetreiber durchzuführen. Beispielsweise Medium auswerfen, Baudrate ändern usw. Diese Operationen werden durch die ioctl-Methode unterstützt, die den gleichnamigen Systemaufruf implementiert. Im Benutzerbereich lautet der Prototyp des ioctl-Systemaufrufs:
Die Prototypen der ioctl-Methoden des Treibers unterscheiden sich geringfügig von den Userspace-Versionen:
Die meisten ioctl-Implementierungen enthalten eine Switch-Anweisung, um die entsprechende Operation basierend auf dem cmd-Parameter auszuwählen. Die Befehlsnummern im Benutzerbereich und im Kernelbereich müssen konsistent sein. (2) Wählen Sie die ioctl-Befehlsnummer Bevor Sie Ioctl-Code schreiben, müssen Sie Nummern auswählen, die den verschiedenen Befehlen entsprechen. Sie können die Nummer nicht einfach bei 0 oder 1 beginnend wählen, da Linux erfordert, dass diese Befehlsnummer systemweit eindeutig ist. Der Linux-Kernel verwendet eine Konvention zur Auswahl von Ioctl-Nummern für Treiber. Weitere Informationen finden Sie unter include/asm/ioctl.h und Documentation/ioctl-number.txt. Eine ioctl-Nummer ist 32 Bit lang. Linux unterteilt sie in vier Teile. Die zur Konstruktion einer ioctl-Nummer benötigten Makros sind in <linux/ioctl.h> definiert:
Sie können die Makros in <linux/ioctl.h> verwenden, um eine ioctl-Nummer zu konstruieren
Rückgabewert Bei Systemaufrufen werden positive Rückgabewerte zuerst geschützt, während negative Werte als Fehler betrachtet und zum Festlegen der Fehlervariable im Benutzerbereich verwendet werden. Wenn beim Aufruf der ioctl-Methode eine undefinierte ioctl-Nummer übergeben wird, lautet der vom System zurückgegebene Fehlerwert -ENVAL und -ENOTTY. (3) Blockierende und nicht blockierende Operationen Bei Vorgängen wie Lesen und Schreiben ist der Standardvorgang das Blockieren. Seine Merkmale sind: *Wenn ein Prozess „read“ aufruft, aber keine zu lesenden Daten vorhanden sind, muss der Prozess blockiert werden. Wenn Daten eintreffen, wird der Prozess aufgeweckt und die Daten an den Aufrufer zurückgegeben, auch wenn die Datenmenge geringer ist als die durch den Zählparameter angegebene Datenmenge. *Wenn ein Prozess „Write“ aufruft, aber kein Platz im Puffer vorhanden ist, muss dieser Prozess blockiert werden und in einer anderen Warteschlange schlafen als der Leseprozess. Wenn einige Daten auf das Hardwaregerät geschrieben werden und dadurch ein Teil des Ausgabepuffers freigegeben wird, wird der Prozess aktiviert und der Schreibaufruf ist erfolgreich. Manchmal möchten wir diese Funktion ändern und sie nicht blockierend machen, sodass die Lese-/Schreibmethode sofort zurückkehrt, unabhängig davon, ob das Gerät Daten zum Lesen oder Schreiben hat. Wenn Sie eine Datei so einstellen möchten, dass sie nicht blockiert, sollten Sie das Flag O_NONBLOCK von filp->f_flags setzen. Beim Umgang mit nicht blockierenden Dateien müssen Anwendungen beim Aufrufen von stdio-Funktionen sehr vorsichtig sein, da eine nicht blockierende Rückgabe leicht mit EOF verwechselt werden kann. Daher muss „errno“ immer überprüft werden. (4) Asynchrone Benachrichtigung a. Die Rolle der asynchronen Benachrichtigung Meistens kann eine Kombination aus blockierenden und nicht blockierenden Operationen und der Select-Methode das Gerät effektiv abfragen, es gibt jedoch Zeiten, in denen diese Technik nicht effizient ist. In bestimmten zufälligen oder selten auftretenden Situationen (z. B. beim Eintippen von STRG+C auf der Tastatur) ist eine asynchrone Benachrichtigung erforderlich. b. So starten Sie eine asynchrone Benachrichtigung im User Space-Programm Um den asynchronen Benachrichtigungsmechanismus für eine Datei zu starten, muss das Benutzerprogramm zwei Schritte ausführen:
(5) So implementieren Sie asynchrone Benachrichtigungen im Treiber a. Entsprechung von Userspace-Operationen im Kernel
b. Fügen Sie den fasync_struct-Zeiger zur Gerätestruktur hinzu Diese Struktur ist in <linux/fs.h> definiert: Struktur fasync_struct { int Magie; int fa_fd; Struktur fasync_Struktur *fa_next; Strukturdatei *fa_file; }; c. Zwei vom Treiber aufzurufende Funktionen Diese beiden Funktionen sind in <linux/fs.h> deklariert. Definiert in /fs/fcntl.c. Der Prototyp sieht wie folgt aus:
Wenn das FASYNC-Flag einer geöffneten Datei geändert wird, wird fasync_helper aufgerufen, um die Datei zur Liste der zugehörigen Prozesse hinzuzufügen oder daraus zu entfernen, und kill_fasync benachrichtigt alle zugehörigen Prozesse, wenn Daten eintreffen. Beispiel 01. Definieren Sie die dynamische Datenstruktur fasync_struct im Gerätetyp Struktur meine_pipe { struct fasync_struct *async_queue; /* Asynchrone Lesestruktur*/ ...... }; 02. Die fasync-Funktion im Treiber ruft fasync_helper auf int my_fasync(fasync_file fd, Strukturdatei *filp, int-Modus) { meine_pipe *dev = filp->private_data; gibt fasync_helper zurück (fd, filp, Modus, &dev->async_queue); } 03. Rufen Sie kill_fasync auf, wenn die Bedingungen für die asynchrone Benachrichtigung erfüllt sind Die asynchrone Benachrichtigung gilt für einen Lesevorgang, daher sollte kill_fasync per Write gesendet werden. Rufen Sie kill_fasync auf, um das Signal SIGIO an alle Prozesse zu senden, die in der asynchronen Warteschlange async_queue auf dem Gerät registriert sind. ssize_t my_write(Strukturdatei *filp, const char *buf, size_t Anzahl, loff_t *f_pos) { ...... wenn (dev->async_queue) kill_fasync(&dev->async_queue, SIGIO, POLL_IN); ...... } 04. Die fasync-Methode muss beim Schließen einer Datei aufgerufen werden Die Methode fasync muss beim Schließen einer Datei aufgerufen werden, um die Datei aus der Liste der aktiven asynchronen Reader zu entfernen. Aufruf in der Version: scull_p_fasync(-1, filp, 0); Zusammenfassen Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM. Wenn Sie mehr darüber erfahren möchten, schauen Sie sich bitte die folgenden Links an Das könnte Sie auch interessieren:
|
<<: Eine kurze Diskussion über allgemeine Operationen von MySQL in cmd und Python
>>: Detaillierte grafische Erläuterung der MySql5.7.18-Zeichensatzkonfiguration
In MySQL gibt es drei Datumstypen: Datum (Jahr-Mo...
<br />Ich freue mich sehr, an dieser Folge d...
1. Voraussetzungen: Die Datenbanksicherung ist be...
In diesem Artikelbeispiel wird der spezifische Co...
keine Ahnung nvm ist für die Verwaltung mehrerer ...
CentOS8 wurde vor ein paar Tagen veröffentlicht. ...
Vorwort Tatsächlich bin ich noch nie auf eine Sit...
Meine System- und Softwareversionen sind wie folg...
Inhaltsverzeichnis 1. Beispielcode 2. Sehen Sie d...
<iframe src=”URL Ihrer Seite” width=”100″ heigh...
Inhaltsverzeichnis 1. Warum brauchen wir vue3? 2....
Ich habe eine Navigationsleiste mit einem erweite...
Linux: Linux-Version 3.10.0-123.9.3.el7.x86_64 Ng...
In diesem Artikel erfahren Sie, wie Sie die Boots...
1. Was ist die HTML-Auszeichnungssprache? HTML is...