IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

[KERNEL] [Signaux] Générer Appel système capturable par Qt


Sujet :

Qt

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Par défaut [KERNEL] [Signaux] Générer Appel système capturable par Qt
    Bonjour,
    j'ai réalisé un petit driver en mode caractère. Celui-ci, en interne, intercepte les interruptions générées par le matériel pour lequel il est programmé. Je souhaiterais pouvoir signaler (émission d'un signal) coté utilisateur que le matériel a généré une interruption. Quelqu'un sait-il comment faire pour intercepter avec Qt des signaux (système ?) non émis par Qt ? Je suis également preneur d'informations sur l'émission de signaux à partir de mon module KERNEL mais je ne suis pas dans la section appropriée pour cette dernière question.

    Merci de votre aide.

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Salut, tu est sur quel os?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Par défaut
    Oups, désolé, dans la précipitation j'ai oublié d'indiquer que je travaillais sous Linux/Fedora (11).

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    regarde ceci
    http://qt.developpez.com/doc/4.5/qap...x11eventfilter
    Normalement, c'est par cette fonction que qt récupère et gère les évènements provenant de x11.
    Sinon, c'est plus du Qt, y as peut être un système d'abonnement au évènement système sous linux comme sous windows.
    Demande peut être conseil dans ce forum
    http://www.developpez.net/forums/f32...mmation-linux/

  5. #5
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Oui, il faut distinguer 2 choses :
    - comment ton appli user peut recevoir une notification du kernel
    - comment "greffer" ce système au dessus des signaux/slots de Qt

    Normalement, on communique avec un driver avec des IOCTL et des read / write. Une fois que tu sais faire ça depuis une petite appli C à part, tu peux dans ton code Qt créer un thread qui effectue une lecture bloquante en attente de ton driver. Quand il reçoit quelque chose, il émet un signal et retourne en attente bloquante (depuis Qt 4 l'envoie de signaux entre différents thread est possible).

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Par défaut
    Merci pour vos réponse.

    Mon interface coté Qt est déjà un thread. Finalement, je vais me contenter d'aller vérifier régulièrement si mon driver a capté l'interruption. Je ne vais pas chipoter pour quelques millisecondes. Je marquerai l'évènement en interne par un timestamp.

  7. #7
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Ah bon. C'est un peu crade mais si ça convient à ton besoin.
    Pour info, fait attention à ne pas répartir ton code graphique dans divers threads, en particulier en dehors du thread GUI (principal).

    Je ne sais pas ce qu'il en est sous X11, mais en général les gestionnaires n'aiment pas trop. Et Qt non plus je pense. En tous cas pour Qt 3 c'est sûr que ça finit mal, et je ne vois pas trop comment ils auraient pu changer ça avec Qt 4.

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel Voir le message
    Et Qt non plus je pense. En tous cas pour Qt 3 c'est sûr que ça finit mal, et je ne vois pas trop comment ils auraient pu changer ça avec Qt 4.
    C'est bien cela.
    Avec Qt, t'as un beau assert en debug.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Par défaut
    Je l'ai fait hériter d'un thread parce que je dois régulièrement (toutes les qqms) vérifier l'état des registres internes du matériel. Je n'ai pas besoin de réagir à la milliseconde sur l'interruption mais je dois tout de même savoir quand elle a eu lieu. C'est pour cela que je récupère le timestamp en interne dans le driver. Je ne saisis pas bien ce qui est crade dans cette façon de procéder ?

    Pour info, fait attention à ne pas répartir ton code graphique dans divers threads, en particulier en dehors du thread GUI (principal).
    Qu'entends tu par là ? Je ne comprends pas.

    Merci pour vos remarques.

  10. #10
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Cédric-29 Voir le message
    Je l'ai fait hériter d'un thread parce que je dois régulièrement (toutes les qqms) vérifier l'état des registres internes du matériel. Je n'ai pas besoin de réagir à la milliseconde sur l'interruption mais je dois tout de même savoir quand elle a eu lieu. C'est pour cela que je récupère le timestamp en interne dans le driver. Je ne saisis pas bien ce qui est crade dans cette façon de procéder ?
    Ce qui est "crade", c'est une attente active, c.a.d - si j'ai bien compris - que tu as une boucle qui tourne en rond dans ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void MyThread::run()
    {
        for (;;;)
        {
            msleep(10);
            if ( testDriverRegister() )
            {
                emit driverEvent();
            }
        }
    }
    }
    C'est une attente active, ca veut dire que ton client interroge activement le driver (ou autre chose), ce qui provoque une consommation inutile de CPU.

    La méthode préconisée, c'est de passer par un objet kernel (mutex...) qui provoque une attente bloquante (passive), c.a.d que ton thread client est mis en pause le temps que l'objet soit signalé. C'est ce qui se passe par exemple quand tu demandes au driver du système de fichier de lire des données. Tu ne fais pas une boucle active pour savoir quand est-ce que tes données ont été lues, tu fais simplement read(), et ton thread reste bloqué sur cette fonction jusqu'à ce que les données soient lues / qu'il y ait une erreur. Normalement, tous les drivers supportent les opérations read / write. Je connais mal Linux, mais tu devrais pouvoir ouvrir ton driver sous forme de fichier virtuel et faire un read dessus. Ou quelque chose du genre. Comment fais-tu pour dialoguer avec ton driver actuellement ?

    Citation Envoyé par Cédric-29 Voir le message
    Qu'entends tu par là ? Je ne comprends pas.
    Tout appel à une fonction graphique (X11...) - c.a.d en gros tout ce qu'il y a dans QtGui et ce qui en dépend - doit être effectué par le même thread. Ainsi, tu ne peux pas faire des QMessageBox dans plusieurs threads en même temps, mais toujours dans le même thread : celui qui contient la boucle des messages (encapsulée par QApplication::exec()) et qu'on appelle le thread GUI.

    Tu peux en revanche utiliser sans problèmes les objets de type QFile, QXmlReader, etc... dans tous les threads, et aussi connecter les slots d'un thread aux signaux d'un autre. C'est d'ailleurs comme ça qu'il faudrait faire dans ton cas : quand ton thread d'interrogation du driver a détecté une interruption, il fait simplement un emit d'un signal donné.

    Dans ta fonction main (thread GUI), tu lances ce thread et te connecte au signal qu'il émet en cas d'interruption matérielle. Quand tu reçois ce signal Qt (dans ton thread GUI donc), tu peux alors afficher un messages à l'écran (ou autre).

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Par défaut
    Merci pour tes remarques.

    Actuellement je fais a peu près ce que tu décris. Il y a deux choses:
    + Un appel pour controler l'état d'un registre sur mon materiel (a chaque appel vers le driver, ce dernier va controler l'etat du registre sur une carte PCI)
    + Un autre appel pour vérifier si une interruption a eu lieu.

    Pour faire un truc correct il faudrait donc (?) deux threads, un pour controler l'interruption avec une lecture bloquante comme tu le proposes. Puis, un autre avec une lecture également bloquante (en interne le driver continuera necessairement à faire du polling sur le registre de la carte) sur la lecture du registre en attendant que la condition (test interne au driver) que je recherche sur le registre soit atteinte.

    Relativement à ton code, je vire le msleep() et je rend la fonction testDriverRegister() bloquante ?

    Actuellement, je n'utilise que les commandes ioctl. Je vais méditer ta proposition

    Comment réagit un thread qui revient sur une fonction (type read) bloquée ? Le quitte t-il immédiatement ou y reste t-il aussi longtemps que lorsqu'il y a effectivement du code à executer ?

    Mon code graphique n'est que dans le thread Principal. Je me suis déjà aperçu du problème en essayant de mettre un QMessageBox dans un autre thread...

  12. #12
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Cédric-29 Voir le message
    en interne le driver continuera necessairement à faire du polling sur le registre de la carte
    Si ce polling est effectivement nécessaire, alors à mon avis il vaut mieux le laisser côté user que de le basculer en kernel land.

    Je ne sais pas comment ça marche, mais je trouve cela très surprenant que ton driver doive faire du polling. C'est le principe même des IRQ : le driver est informé par le matos qu'il y a eu changement au lieu de devoir tester en boucle.

    Pour ce qui est d'informer les applis user land, là aussi je n'y connais rien. J'ai pensé au read bloquant parce que c'est le plus classique, mais ce n'est peut être pas adapté à ton cas vu que tu souhaites en fait détecter des évènements si j'ai bien compris. Et je n'ai aucune idée de comment il faut procéder. Mais si je devais chercher, je commencerai par me demander comment le desktop manager (Gnome...) fait pour savoir qu'une clé USB a été branchée + montée pour ensuite m'afficher automatiquement une nouvelle icone sur le bureau.

    Le thread est nécessaire si tu dois effectuer un appel bloquant ou du polling. Mais si c'est un système d'event (basé sur X11 ?), peut être qu'il te suffit de définir tes propres event filters comme suggéré au début par yan.

    Maintenant si tu ne sais pas / peux pas faire autrement que via une attente active dans ton appli Qt, ben tu as déjà coder ce qu'il y avait à coder il me semble. Mais ça vaudrait le coup de chercher un petit peu comment font les autres drivers.

    edit : ou simplement comment les drivers clavier / souris informent les applis user d'un nouvel input

    edit 2 : http://www.xml.com/ldd/chapter/book/ch05.html

Discussions similaires

  1. [VB6] Appeler une procedure par son nom.
    Par kenn dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 24/05/2006, 09h29
  2. [UBUNTU] Ajout nouvel appel système ?
    Par [Margot] dans le forum Ubuntu
    Réponses: 5
    Dernier message: 11/05/2006, 14h11
  3. appel système opendir dans thread
    Par madimane dans le forum POSIX
    Réponses: 2
    Dernier message: 14/04/2006, 05h39
  4. Interfacer un logiciel et un système hardware par port série
    Par jean-claude74 dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 13/08/2005, 16h52
  5. Appel de procédure par contenu de variable
    Par lil_jam63 dans le forum Langage
    Réponses: 9
    Dernier message: 13/09/2004, 08h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo