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
Der Rahmen des gesamten Mechanismus:
“
“
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 Abschluss der oben genannten Arbeiten kann das Programm der Anwendungsschicht auf die Ankunft von SIGIO warten.
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.
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;
};
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);
/** *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);
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); ... }
总之,异步通知技术是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!