Dans le processus d'écriture des pilotes Linux, la technologie de notification asynchrone est une technologie très importante. Il peut réaliser un traitement efficace des événements et une transmission de données, améliorant ainsi les performances du système et la vitesse de réponse. Dans cet article, nous approfondirons les principes de mise en œuvre et les technologies associées de la technologie du pilote Linux (4) _technologie de notification asynchrone.
Le nom complet de la notification asynchrone est « IO asynchrone piloté par signal ». Grâce à la méthode « signal », lorsque les ressources attendues sont disponibles, le pilote notifiera activement l'application spécifiée, correspondant au « signal » du couche d'application, utilisée ici C'est le signal « SIGIO ». Les étapes sont
La charpente de l'ensemble du mécanisme :
«
”
Comme les autres signaux, la couche application doit enregistrer une fonction de traitement du signal,
La façon de s'inscrire est toujours d'utiliser signal() ou sigaction()
De plus, la couche application doit également s'ajouter à la liste de la chaîne de notification du conducteur. Le code ajouté est le suivant
.fcntl(dev_fd,F_SETOWN,getpid()); int oflags = fcntl(dev_fd,F_GETFL); fcntl(dev_fd,F_SETFL,oflags|FASYNC); ... while(1);
Après avoir terminé le travail ci-dessus, le programme de couche application peut attendre l'arrivée de SIGIO.
Une fois la couche application enregistrée, l'envoi final dépend de la méthode de traitement du pilote de périphérique. Afin que le périphérique prenne en charge le mécanisme de notification asynchrone, faisant référence à l'interface de la couche application, le pilote implique trois tâches.
Afin d'implémenter les trois fonctions ci-dessus dans le noyau, le pilote doit utiliser 1 structure + 2 API, la structure est struct fasync_struct et les fonctions sont fasync_helper() et 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; };
fasync_helper() est d'enregistrer un objet de fasync_struct dans le noyau. Lorsque la couche application exécute **fcntl(dev_fd, F_SETFL, oflags|FASYNC), elle rappellera le fops du pilote. fasync(), donc mettez généralement fasync_helper() dans l'implémentation de fasync()**.
/** *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);
L'API suivante consiste à publier SIGIO et à le placer à différents endroits en fonction de différents besoins.
/** *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);
Le modèle de pilote ci-dessous est conçu pour envoyer un signal à la couche application lorsqu'une interruption matérielle arrive (des ressources sont disponibles). Dans les opérations réelles, il existe de nombreuses situations où des ressources sont disponibles
.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驱动技术(四) _异步通知技术的实现原理和相关技术。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!