Maison  >  Article  >  Tutoriel système  >  Une discussion approfondie sur la technologie des pilotes Linux (4)_Les principes de mise en œuvre et les technologies associées de la technologie de notification asynchrone

Une discussion approfondie sur la technologie des pilotes Linux (4)_Les principes de mise en œuvre et les technologies associées de la technologie de notification asynchrone

PHPz
PHPzavant
2024-02-09 20:24:141004parcourir

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

  1. Le programme de couche application s'enregistre en tant que processus qui reçoit le signal SIGIO du fichier de l'appareil
  2. Le pilote implémente l'interface correspondante afin d'avoir la possibilité d'envoyer des signaux SIGIO à toutes les applications enregistrées pour recevoir des signaux SIGIO de ce pilote de périphérique.
  3. Le pilote appelle la fonction d'envoi à l'emplacement approprié et l'application peut recevoir le signal SIGIO.

La charpente de l'ensemble du mécanisme :

«

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

La couche application reçoit SIGIO

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.

Le chauffeur envoie 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.

  1. Prend en charge la commande F_SETOWN Vous pouvez définir filp->f_owner comme ID du processus correspondant dans cette commande. Cette partie du noyau a déjà été réalisée
  2. .
  3. Prise en charge de F_SETFL, chaque fois que le drapeau FASYNC change, **fasync() dans le pilote sera exécuté, donc fasync()** doit être implémenté dans le pilote.
  4. Lorsque les ressources de l'appareil sont disponibles, envoyez SIGIO via kill_fasync()

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;
};
La fonction de

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);

Modèle de pilote

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer