Einführung in das Linux-Eingabesubsystem
Das Linux-Eingabesubsystem ist eine Reihe von Treibern, die alle Eingabegeräte im Linux-System unterstützen, einschließlich Tastaturen, Mäuse, Touchscreens, Tablets, Gamecontroller usw. Der Kern des Eingabesubsystems ist das Eingabemodul, das für die Weitergabe von Ereignissen zwischen den beiden Modultypen verantwortlich ist:
- Gerätetreibermodule: Diese Module kommunizieren mit der Hardware (z. B. über USB) und stellen Ereignisse (Tastendrücke, Mausbewegungen usw.) an das Eingabemodul bereit.
- Event-Handling-Module: Diese Module erhalten Ereignisse vom Eingabemodul und leiten sie über verschiedene Schnittstellen dorthin weiter, wo sie benötigt werden (z. B. Kernel, GPM, X usw.).
In diesem Artikel stellen wir die grundlegenden Konzepte und die Struktur des Linux-Eingabesubsystems sowie einige häufig verwendete Befehle und Tools vor. Als Beispielsystem verwenden wir Ubuntu 20.04, der Inhalt gilt jedoch auch für andere Linux-Distributionen.

Treiberschicht
Konvertieren Sie die zugrunde liegende Hardware-Eingabe in eine einheitliche Ereignisform und melden Sie sie dem Eingabekern.
Kernschicht des Eingabesubsystems
Es stellt der Treiberschicht Eingabegeräte-Registrierungs- und Betriebsschnittstellen zur Verfügung, wie zum Beispiel: input_register_device; benachrichtigt die Ereignisverarbeitungsschicht, um das Ereignis zu verarbeiten, und generiert entsprechende Geräteinformationen unter /Proc.
Ereignisverarbeitungsschicht
Interagiert hauptsächlich mit dem Benutzerbereich (unter Linux werden alle Geräte als Dateien im Benutzerbereich behandelt). Da die FOPs-Schnittstelle in allgemeinen Treibern bereitgestellt wird und das entsprechende Gerätedatei-Nod unter /dev generiert wird, werden diese Der Vorgang wird durch die Ereignisverarbeitung abgeschlossen Schicht im Eingabesubsystem).
Gerätebeschreibung
Die Struktur input_dev dient dazu, die Kernaufgabe des Gerätetreibers zu implementieren: Tastendrücke, Touchscreens und andere Eingabeereignisse (Ereignisse, beschrieben durch die Struktur input_event) an das System zu melden, ohne dass Sie sich mehr um die Dateioperationsschnittstelle kümmern müssen. Der Treiber meldet Ereignisse über inputCore und Eventhandler an den Benutzerbereich.
Eingabegerätefunktion registrieren:
int input_register_device(struct input_dev *dev)
Eingabegerätefunktion abmelden:
void input_unregister_device(struct input_dev *dev)
Treiberimplementierung – Initialisierung (Ereignisunterstützung) set_bit() teilt dem Eingabesubsystem mit, welche Ereignisse und Schlüssel unterstützt werden. Zum Beispiel:
set_bit(EV_KEY,button_dev.evbit) (其中button_dev是struct input_dev类型)
struct input_dev****:
**1)** evbit-Ereignistyp (einschließlich EV_RST, EV_REL, EV_MSC, EV_KEY, EV_ABS, EV_REP usw.).
**2)**Keybit-Schlüsseltyp (einschließlich BTN_LEFT, BTN_0, BTN_1, BTN_MIDDLE usw., wenn der Ereignistyp EV_KEY ist).
Treiberimplementierung – Meldeereignisse Die zum Melden von EV_KEY-, EV_REL- und EV_ABS-Ereignissen verwendeten Funktionen sind:
void input_report_key(struct input_dev *dev,unsigned int code,int value) void input_report_rel(struct input_dev *dev,unsigned int code,int value) void input_report_abs(struct input_dev *dev,unsigned int code,int value)
Treiberimplementierung – Berichtsende input_sync()-Synchronisierung wird verwendet, um dem Eingabekern-Subsystem mitzuteilen, dass der Bericht beendet wurde. Im Touchscreen-Gerätetreiber ist der gesamte Berichtsprozess mit einem Klick wie folgt:
input_reprot_abs(input_dev,ABS_X,x); //x坐标 input_reprot_abs(input_dev,ABS_Y,y); // y坐标 input_reprot_abs(input_dev,ABS_PRESSURE,1); input_sync(input_dev);//同步结束
Beispielanalyse (Schlüssel-Interrupt-Programm):
//按键初始化 static int __init button_init(void) {//申请中断 if(request_irq(BUTTON_IRQ,button_interrupt,0,”button”,NUll)) return –EBUSY; set_bit(EV_KEY,button_dev.evbit); //支持EV_KEY事件 set_bit(BTN_0,button_dev.keybit); //支持设备两个键 set_bit(BTN_1,button_dev.keybit); // input_register_device(&button_dev);//注册input设备 } /*在按键中断中报告事件*/ Static void button_interrupt(int irq,void *dummy,struct pt_regs *fp) { input_report_key(&button_dev,BTN_0,inb(BUTTON_PORT0));//读取寄存器BUTTON_PORT0的值 input_report_key(&button_dev,BTN_1,inb(BUTTON_PORT1)); input_sync(&button_dev); }
Zusammenfassung: Das input-Subsystem ist immer noch ein Zeichengerätetreiber, aber die Menge an Code ist stark reduziert. Das ****input-Subsystem muss nur zwei Aufgaben erledigen: Initialisierung und Ereignisberichterstellung (hier in linux*). *** Dies wird durch Interrupts erreicht.
Instanzen
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct input_dev *button_dev; struct button_irq_desc { int irq; int pin; int pin_setting; int number; char *name; }; /*定义一个结构体数组*/ static struct button_irq_desc button_irqs [] = { {IRQ_EINT8 , S3C2410_GPG0 , S3C2410_GPG0_EINT8 , 0, "KEY0"}, {IRQ_EINT11, S3C2410_GPG3 , S3C2410_GPG3_EINT11 , 1, "KEY1"}, {IRQ_EINT13, S3C2410_GPG5 , S3C2410_GPG5_EINT13 , 2, "KEY2"}, {IRQ_EINT14, S3C2410_GPG6 , S3C2410_GPG6_EINT14 , 3, "KEY3"}, {IRQ_EINT15, S3C2410_GPG7 , S3C2410_GPG7_EINT15 , 4, "KEY4"}, {IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG11_EINT19, 5, "KEY5"}, }; static int key_values = 0; static irqreturn_t buttons_interrupt(int irq, void *dev_id) { struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id; int down; udelay(0); /*获取按键值*/ down = !s3c2410_gpio_getpin(button_irqs->pin); //down: 1(按下),0(弹起) if (!down) { /*报告事件*/ key_values = button_irqs->number; //printk("====>rising key_values=%d\n",key_values); if(key_values==0) input_report_key(button_dev, KEY_1, 0); if(key_values==1) input_report_key(button_dev, KEY_2, 0); if(key_values==2) input_report_key(button_dev, KEY_3, 0); if(key_values==3) input_report_key(button_dev, KEY_4, 0); if(key_values==4) input_report_key(button_dev, KEY_5, 0); if(key_values==5) input_report_key(button_dev, KEY_6, 0); /*报告结束*/ input_sync(button_dev); } else { key_values = button_irqs->number; //printk("====>falling key_values=%d\n",key_values); if(key_values==0) input_report_key(button_dev, KEY_1, 1); if(key_values==1) input_report_key(button_dev, KEY_2, 1); if(key_values==2) input_report_key(button_dev, KEY_3, 1); if(key_values==3) input_report_key(button_dev, KEY_4, 1); if(key_values==4) input_report_key(button_dev, KEY_5, 1); if(key_values==5) input_report_key(button_dev, KEY_6, 1); input_sync(button_dev); } return IRQ_RETVAL(IRQ_HANDLED); } static int s3c24xx_request_irq(void) { int i; int err = 0; for (i = 0; i if (button_irqs[i].irq continue; } /* IRQ_TYPE_EDGE_FALLING,IRQ_TYPE_EDGE_RISING,IRQ_TYPE_EDGE_BOTH */ err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH, button_irqs[i].name, (void *)&button_irqs[i]); if (err) break; } /*错误处理*/ if (err) { i--; for (; i >= 0; i--) { if (button_irqs[i].irq continue; } disable_irq(button_irqs[i].irq); free_irq(button_irqs[i].irq, (void *)&button_irqs[i]); } return -EBUSY; } return 0; } static int __init dev_init(void) { /*request irq*/ s3c24xx_request_irq(); /* Initialise input stuff */ button_dev = input_allocate_device(); if (!button_dev) { printk(KERN_ERR "Unable to allocate the input device !!\n"); return -ENOMEM; } button_dev->name = "s3c2440_button"; button_dev->id.bustype = BUS_RS232; button_dev->id.vendor = 0xDEAD; button_dev->id.product = 0xBEEF; button_dev->id.version = 0x0100; button_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT(EV_SYN); //set_bit(EV_KEY, button_dev->evbit)//支持EV_KEY事件 /*设置支持哪些按键*/ set_bit(KEY_1, button_dev->keybit); set_bit(KEY_2, button_dev->keybit); set_bit(KEY_3, button_dev->keybit); set_bit(KEY_4, button_dev->keybit); set_bit(KEY_5, button_dev->keybit); set_bit(KEY_6, button_dev->keybit); //printk("KEY_RESERVED=%d ,KEY_1=%d",KEY_RESERVED,KEY_1); input_register_device(button_dev); //注册input设备 printk ("initialized\n"); return 0; } static void __exit dev_exit(void) { int i; for (i = 0; i if (button_irqs[i].irq continue; } free_irq(button_irqs[i].irq, (void *)&button_irqs[i]); } input_unregister_device(button_dev); } module_init(dev_init); module_exit(dev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Xie");
In diesem Artikel haben wir die grundlegenden Konzepte und die Struktur des Linux-Eingabesubsystems sowie einige häufig verwendete Befehle und Tools kennengelernt. Wir haben gelernt, wie man die Eigenschaften und den Status von Eingabegeräten anzeigt und steuert und wie man die Tools evtest und libinput zum Testen und Debuggen von Eingabegeräten verwendet. Wir haben auch gelernt, wie man udev-Regeln verwendet, um das Verhalten und die Konfiguration von Eingabegeräten anzupassen.
Das Linux-Eingabesubsystem ist ein leistungsstarkes und flexibles Framework, mit dem Sie Ihre Eingabegeräte besser verwalten und nutzen können. Durch die Verwendung des Linux-Eingabesubsystems können Sie Ihre Produktivität und Benutzererfahrung verbessern. Wir empfehlen Ihnen, häufig das Linux-Eingabesubsystem zu verwenden, um Ihre Eingabegeräte bei Verwendung eines Linux-Systems zu optimieren.
Das obige ist der detaillierte Inhalt vonEinführung in das Linux-Eingabesubsystem. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Schritte zum Starten von Nginx unter Linux: Überprüfen Sie, ob Nginx installiert ist. Verwenden Sie SystemCTL Start Nginx, um den Nginx -Dienst zu starten. Verwenden Sie SystemCTL aktivieren NGINX, um das automatische Start von NGINX beim Systemstart zu aktivieren. Verwenden Sie den SystemCTL -Status NGINX, um zu überprüfen, ob das Startup erfolgreich ist. Besuchen Sie http: // localhost in einem Webbrowser, um die Standard -Begrüßungsseite anzuzeigen.

So bestätigen Sie, ob Nginx gestartet wird: 1. Verwenden Sie die Befehlszeile: SystemCTL Status Nginx (Linux/Unix), Netstat -ano | FindStr 80 (Windows); 2. Überprüfen Sie, ob Port 80 geöffnet ist; 3. Überprüfen Sie die Nginx -Startmeldung im Systemprotokoll. 4. Verwenden Sie Tools von Drittanbietern wie Nagios, Zabbix und Icinga.

Das Starten eines Nginx-Servers erfordert unterschiedliche Schritte gemäß verschiedenen Betriebssystemen: Linux/UNIX-System: Installieren Sie das NGINX-Paket (z. B. mit APT-Get oder Yum). Verwenden Sie SystemCTL, um einen Nginx -Dienst zu starten (z. B. sudo systemctl start nginx). Windows -System: Laden Sie Windows -Binärdateien herunter und installieren Sie sie. Starten Sie Nginx mit der ausführbaren Datei nginx.exe (z. B. nginx.exe -c conf \ nginx.conf). Unabhängig davon, welches Betriebssystem Sie verwenden, können Sie auf die Server -IP zugreifen

Verwenden Sie unter Linux den folgenden Befehl, um zu überprüfen, ob Nginx gestartet wird: SystemCTL -Status Nginx Richter basierend auf der Befehlsausgabe: Wenn "aktiv: aktiv (lief) angezeigt wird, wird Nginx gestartet. Wenn "Active: Inactive (Dead)" angezeigt wird, wird Nginx gestoppt.

Der Server verfügt nicht über die Berechtigung, auf die angeforderte Ressource zuzugreifen, was zu einem NGINX 403 -Fehler führt. Zu den Lösungen gehören: Überprüfung der Dateiberechtigungen. Überprüfen Sie die Konfiguration .htaccess. Überprüfen Sie die Nginx -Konfiguration. Konfigurieren Sie Selinux -Berechtigungen. Überprüfen Sie die Firewall -Regeln. Fehlerbehebung bei anderen Ursachen wie Browserproblemen, Serverausfällen oder anderen möglichen Fehlern.

Antwort auf die Frage: 304 Nicht geänderter Fehler gibt an, dass der Browser die neueste Ressourcenversion der Client -Anfrage zwischengespeichert hat. Lösung: 1. Löschen Sie den Browser -Cache; 2. Deaktivieren Sie den Browser -Cache; 3. Konfigurieren Sie Nginx, um den Client -Cache zu ermöglichen. 4. Überprüfen Sie die Dateiberechtigungen; 5. Datei Hash prüfen; 6. Deaktivieren Sie CDN oder Reverse Proxy -Cache; 7. Starten Sie Nginx neu.

Das Fehlerprotokoll befindet sich in/var/log/nginx (Linux) oder/usr/local/var/log/nginx (macOS). Verwenden Sie die Befehlszeile, um die Schritte zu beseitigen: 1. Sicherung des ursprünglichen Protokolls; 2. Erstellen Sie eine leere Datei als neues Protokoll; 3. Starten Sie den Nginx -Dienst neu. Die automatische Reinigung kann auch mit Tools von Drittanbietern wie lehnte oder konfiguriertem verwendet werden.

Die wichtigsten Unterschiede zwischen CentOS und Ubuntu sind: Ursprung (CentOS stammt von Red Hat, für Unternehmen; Ubuntu stammt aus Debian, für Einzelpersonen), Packungsmanagement (CentOS verwendet yum, konzentriert sich auf Stabilität; Ubuntu verwendet apt, für hohe Aktualisierungsfrequenz), Support Cycle (Centos) (CENTOS bieten 10 Jahre. Tutorials und Dokumente), Verwendungen (CentOS ist auf Server voreingenommen, Ubuntu ist für Server und Desktops geeignet). Weitere Unterschiede sind die Einfachheit der Installation (CentOS ist dünn)
