Heim > System-Tutorial > LINUX > Hauptteil

Eine ausführliche Diskussion der Linux-Treibertechnologie (4)_Die Implementierungsprinzipien und verwandten Technologien der asynchronen Benachrichtigungstechnologie

PHPz
Freigeben: 2024-02-09 20:24:14
nach vorne
1029 Leute haben es durchsucht

Beim Schreiben von Linux-Treibern ist die asynchrone Benachrichtigungstechnologie eine sehr wichtige Technologie. Es kann eine effiziente Ereignisverarbeitung und Datenübertragung erreichen und so die Systemleistung und Reaktionsgeschwindigkeit verbessern. In diesem Artikel werden wir uns eingehend mit den Implementierungsprinzipien und verwandten Technologien der Linux-Treibertechnologie (4) und der asynchronen Benachrichtigungstechnologie befassen.

Der vollständige Name der asynchronen Benachrichtigung lautet „signalgesteuertes asynchrones E/A“. Wenn die erwarteten Ressourcen verfügbar sind, benachrichtigt der Treiber die angegebene Anwendung entsprechend dem „Signal“. Anwendungsschicht, hier verwendet Es ist das Signal „SIGIO“. Die Schritte sind

  1. Das Programm der Anwendungsschicht registriert sich als Prozess, der das SIGIO-Signal aus der Gerätedatei empfängt
  2. Der Treiber implementiert die entsprechende Schnittstelle, um SIGIO-Signale an alle Anwendungen senden zu können, die für den Empfang von SIGIO-Signalen von diesem Gerätetreiber registriert sind.
  3. Der Treiber ruft die Sendefunktion an der entsprechenden Stelle auf und die Anwendung kann das SIGIO-Signal empfangen.

Der Rahmen des gesamten Mechanismus:

深入探讨Linux驱动技术(四) _异步通知技术的实现原理和相关技术

Die Anwendungsschicht empfängt SIGIO

Wie andere Signale muss die Anwendungsschicht eine Signalverarbeitungsfunktion registrieren,
Die Registrierung erfolgt weiterhin über signal() oder sigaction()

Darüber hinaus muss sich die Anwendungsschicht auch zur Benachrichtigungskettenliste des Treibers hinzufügen. Der hinzugefügte Code lautet wie folgt

fcntl(dev_fd,F_SETOWN,getpid());
int oflags = fcntl(dev_fd,F_GETFL);
fcntl(dev_fd,F_SETFL,oflags|FASYNC);
...
while(1);
Nach dem Login kopieren

Nach Abschluss der oben genannten Arbeiten kann das Programm der Anwendungsschicht auf die Ankunft von SIGIO warten.

Fahrer sendet SIGIO

Nachdem die Anwendungsschicht registriert ist, hängt das endgültige Senden von der Verarbeitungsmethode des Gerätetreibers ab. Damit das Gerät den asynchronen Benachrichtigungsmechanismus unter Bezugnahme auf die Schnittstelle der Anwendungsschicht unterstützt, umfasst der Treiber drei Aufgaben.

  1. Unterstützt den Befehl F_SETOWN Sie können in diesem Befehl filp->f_owner als ID des entsprechenden Prozesses festlegen Unterstützt
  2. F_SETFL
  3. , wann immer sich das FASYNC-Flag ändert, wird **fasync() im Treiber ausgeführt, daher muss fasync()** im Treiber implementiert werden. Wenn Geräteressourcen verfügbar sind,
  4. senden Sie SIGIO über kill_fasync()
  5. Um die oben genannten drei Funktionen im Kernel zu implementieren, muss der Treiber
1 Struktur + 2 APIs

verwenden, die Struktur ist struct fasync_struct und die Funktionen sind fasync_helper() und kill_fasync()

struct fasync_struct {                                    
        spinlock_t              fa_lock;
        int                     magic;
        int                     fa_fd;
        struct fasync_struct    *fa_next; /* singly linked list */
        struct file             *fa_file;
        struct rcu_head         fa_rcu;
};
Nach dem Login kopieren
Die Funktion von

fasync_helper()

besteht darin, ein Objekt von fasync_struct im Kernel zu registrieren. Wenn die Anwendungsschicht **fcntl(dev_fd, F_SETFL, oflags|FASYNC) ausführt, ruft sie die fops des Treibers zurück. fasync(), also fügen Sie normalerweise fasync_helper() in die Implementierung von fasync()** ein.

/**
 *fasync_helper - 将一个fasync_struct对象注册进内核
 *@fd:文件描述符,由fasync传入
 *@filp:file指针,由fasync传入
 *@sig:信号类型,通常使用的就是SIGIO
 *@dev_fasync:事前准备的fasync_struct对象指针的指针
 */
int fasync_helper(int fd, struct file * filp, int sig, struct fasync_struct ** dev_fasync);   
Nach dem Login kopieren
Die folgende API dient dazu, SIGIO freizugeben und je nach Bedarf an verschiedenen Orten zu platzieren.

/**
 *kill_fasync - 释放一个信号
 *@dev_fasync:事前使用fasync_helper注册进内核的fasync_struct对象指针的指针
 *@filp:file指针,由fasync传入
 *@sig:信号类型,通常使用的就是SIGIO
 *@flag:标志,通常,如果资源可读用POLLIN,如果资源可写用POLLOUT
 */
void kill_fasync(struct fasync_struct **dev_fasync, int sig, int flag);
Nach dem Login kopieren

Treibervorlage

Die Treibervorlage unten soll ein Signal an die Anwendungsschicht senden, wenn ein Hardware-Interrupt eintrifft (Ressourcen sind verfügbar). Im tatsächlichen Betrieb gibt es viele Situationen, in denen Ressourcen verfügbar sind
static struct fasync_struct *fasync = NULL;

static irqreturn_t handler(int irq, void *dev)
{
    kill_fasync(&fasync, SIGIO, POLLIN);
    return IRQ_HANDLED;
}
static int demo_fasync(int fd, struct file *filp, int mode)
{
    return fasync_helper(fd, filp, mode, &fasync);
}
struct file_operations fops = {
    ...
    .fasync = demo_fasync,
    ...
}
static int __init demo_init(void)
{
    ...
    request_irq(irq, handler, IRQF_TRIGGER_RISING, "demo", NULL);
    ...
}
Nach dem Login kopieren

总之,异步通知技术是Linux驱动程序编写过程中不可或缺的一部分。它可以实现高效的事件处理和数据传输,提高系统的性能和响应速度。希望本文能够帮助读者更好地理解Linux驱动技术(四) _异步通知技术的实现原理和相关技术。

Das obige ist der detaillierte Inhalt vonEine ausführliche Diskussion der Linux-Treibertechnologie (4)_Die Implementierungsprinzipien und verwandten Technologien der asynchronen Benachrichtigungstechnologie. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:lxlinux.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage