2017-04-15 5 views
0

Bonjour Chers participants stackoverflow,mise en œuvre du mécanisme dans le sondage Char Device Driver

Je suis nouveau au développement de l'espace noyau et encore au début de la route. J'ai développé un pilote de périphérique char de base qui peut lire ouvert fermer etc. Mais n'a pas pu trouver une source appropriée et comment tutoriel pour l'échantillon de mécanisme de sondage/sélection.

J'ai écrit l'exemple de code pour la fonction de sondage ci-dessous:

static unsigned int dev_poll(struct file * file, poll_table *wait) 

{

poll_wait(file,&dev_wait,wait); 
if (size_of_message > 0){ 
    printk(KERN_INFO "size_of_message > 0 returning POLLIN | POLLRDNORM\n"); 
    return POLLIN | POLLRDNORM; 
} 
else { 
    printk(KERN_INFO "dev_poll return 0\n"); 
    return 0; 
} 

}

Il fonctionne très bien, mais ne pouvait pas undestand quelques choses.

Lorsque j'appelle selection de programme de l'espace utilisateur comme

struct timeval time = {5,0 } ; 
select(fd + 1 , &readfs,NULL,NULL,&time); 

la fonction dev_poll dans conducteur appelé une fois et retour à zéro ou POLLIN afin de taille de mémoire tampon. Et puis plus jamais appelé. Dans l'espace utilisateur, après 5 secondes le programme continue si dev_poll a renvoyé 0. Ce que je ne pouvais pas comprendre est ici, comment le code de conducteur décidera et laissera l'espace d'utilisateur programme s'il y a quelque chose dans le tampon qui est lisible pendant ces 5 secondes, s'il est appelé une fois et retourné immédiatement.

Y at-il de toute façon dans le module du noyau de recueillir des informations sur le paramètre timeval qui vient de l'espace utilisateur?

Merci à partir de maintenant.

Cordialement,

Répondre

0

Appel poll_wait() PLACES fait quelque attendre objet dans un waitqueue, spécifié comme second paramètre. Lorsque l'objet wait est déclenché (via la fonction wake_up de waitqueue ou une fonction similaire), la fonction d'interrogation est à nouveau évaluée. Le pilote du noyau n'a pas à s'inquiéter des délais d'attente: lorsque le temps est écoulé, l'objet d'attente sera automatiquement retiré de la file d'attente.

+0

Merci pour votre réponse, Alors comment dois-je gérer les situations pour laisser le noyau quand j'ai des données disponibles avec le délai? À titre d'exemple, sélectionnez l'appel de l'espace utilisateur avec une temporisation de 5 s. Au début de la sélection, je n'ai aucune donnée dans l'appareil. Ensuite, j'ai les données avec 2 secondes. Donc, je veux réveiller le programme de l'espace utilisateur. Comment je peux mettre en œuvre ceci? – Ozan

+0

Comme indiqué dans la réponse, lorsque la file d'attente devient non vide, vous devez appeler 'wake_up' pour la file d'attente que vous utilisez pour' poll'. – Tsyvarev

0

Bonjour chers curieux comme moi à propos du sondage. Je suis venu avec une solution. D'un autre sujet sur stackowerflow un gars a dit que la fonction poll_function est appelée plusieurs fois si le noyau a besoin de la dernière situation. Donc, fondamentalement, j'implémente ce code.

lors d'un appel appelé appel wait_poll (wait_queue_head); lorsque le périphérique possède des données mises en mémoire tampon (généralement dans la fonction d'écriture du pilote). appelez la macro wake_up avec le paramètre wait_queue_head. Donc, après cette étape, la fonction de sondage du pilote est appelée à nouveau. Donc, ici, vous pouvez retourner ce que vous voulez retourner. Dans ce cas, POLLIN | POLLRDNORM ..

Voici mon exemple de code pour écrire et interroger dans le pilote.

static unsigned int dev_poll(struct file * file, poll_table *wait) 
{ 
    static int dev_poll_called_count = 0 ; 
    dev_poll_called_count ++; 
    poll_wait(file,&dev_wait,wait); 
    read_wait_queue_length++; 
    printk(KERN_INFO "Inside dev_poll called time is : %d read_wait_queue_length %d\n",dev_poll_called_count,read_wait_queue_length); 

    printk(KERN_INFO "After poll_wait wake_up called\n"); 
    if (size_of_message > 0){ 
     printk(KERN_INFO "size_of_message > 0 returning POLLIN | POLLRDNORM\n"); 
     return POLLIN | POLLRDNORM; 
    } 
    else { 
     printk(KERN_INFO "dev_poll return 0\n"); 
     return 0; 
    } 
} 

    static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){ 
    printk(KERN_INFO "Inside write \n");; 
    int ret;  
    ret = copy_from_user(message, buffer, len); 
    size_of_message = len ; 
    printk(KERN_INFO "EBBChar: Received %zu characters from the user\n", size_of_message); 
    if (ret) 
     return -EFAULT; 
    message[len] = '\0'; 
    printk(KERN_INFO "gelen string %s", message); 
    if (read_wait_queue_length) 
    { 
     wake_up(&dev_wait); 
     read_wait_queue_length = 0; 
    } 
    return len; 

}