Forum Programmation.c IRQ en C

Posté par .
Tags : aucun
0
26
avr.
2005
Bonjour,
Je dois rédiger un programme en C qui doit lire 4 ports series. Sur chaque ports série se trouve une balance. L'information est obtenue lorsqu'il y a une variation du poids sur la balance.
Exemple: Sur la balance A se trouve 100g de nourriture. Une sourie mange 10g. Sur A nous avons maintenant 90g. L'info est envoyé lorque le poid est stabilisé sur la balance.
Pour ne pas monopolisé le CPU en lecture sur les 4 ports, il faut mettre en place un gestionnaire d'interruption. Ansi, chaque fois qu'une infos ce présente sur un des 4 ports series, le CPU est interrompu par une IRQ en provenance de l'un des 4 ports série.
Le développement sous IRQ en C, je sais pas. Si quelqu'un à des idées, elles sont les bien venues.

Merci d'avance
  • # sur quelle patteforme/OS?

    Posté par . Évalué à 1.

    sur quelle patteforme/OS?
    bah, oui, car c'est different sur chaque couple Machine/OS...
    Je suppose quand même qu'il s'agit de x86 sinon, t'aurait peut être pas employé le terme IRQ...
    mais, bon, sous linux il faut lire les les fichiers /dev/ttyS0 à /dev/ttyS3.... et avoir les droit dessus si tu veux écrire (un simple chmod en root devrait faire l'affaire)... ensuite tu peux affecter un thread qui vérifie s'il y a quelque chose à lire avec un simple ioctl...

    si tu veux vraiment être prévenu par une interruption du système il va falloir utiliser la fonction poll() qui doit pouvoir bloquer en attendant que quelquechose arrive sur l'un de tes descripteur de fichier... mais je te conseille de mettre un timeout et de boucler dessus quand même car sinon ton appli bloquera indéfiniement si jamais rien n'arrive...

    voilà, je peux entrer un peu plus dans les détails si tu veux...mais j'aimerai pas te gacher le plaisir de bidouiller avec les ports séries...
    • [^] # Re: sur quelle patteforme/OS?

      Posté par . Évalué à 1.

      Vu qu'il a 4 ports à gerer en meme temps, select() me semble plus approprié.

      Daniel
      --
      • [^] # Re: sur quelle patteforme/OS?

        Posté par . Évalué à 1.

        Bonjour,

        Ca se passe sur Linux, Suse noyau 2.4.21
        Au vu des informations, ca ne serais pas obligatoire de travailler sous interruptions ?
        • [^] # Re: sur quelle patteforme/OS?

          Posté par . Évalué à 1.

          D'une part je ne sais pas si c'est possible en userland, et d'une autre select() me semble tout a fais approprié, vu que tu saura si quelque chose est dispo ou si c'est le timeout qui a fais "retourné" select().

          Daniel.
          --
          • [^] # Re: sur quelle patteforme/OS?

            Posté par . Évalué à 1.

            J'ai oublié de preciser que poll() et select() ne "bouffe" pas de CPU quand ils attendent quelque chose, ce qui est nettement plus mieux bien qu'une boucle temporisé de la mort qui tenterais de savoir si l'IRQ a ete declenchée.

            Daniel
            --
            • [^] # Re: sur quelle patteforme/OS?

              Posté par . Évalué à 1.

              Auriez vous des exemples ou URL à me proposer pour l'utilisation de poll() et select().
              Me lancer les interruptions ne me semble pas simple.
              Pour le noyau 2.4 ou 2.6 fera l'affaire.
        • [^] # Re: sur quelle patteforme/OS?

          Posté par . Évalué à 2.

          les interruptions sont gereés par l'OS (kernel) au travers des drivers de peripherique.
          quand tu ouvre un port serie par ttsy le kernel gere toute la partie reception des infos sous interruption du port serie et les bufferisent.
          Donc tu n'as qu'as lire regulierement les données recu sur le ttsy (par plein de methode comme pool() ou select() ou avec un thread et un blocking-read)
          voir le serial programming how-to aidera beaucoup

          http://www.faqs.org/docs/Linux-HOWTO/Serial-Programming-HOWTO.html(...)
      • [^] # Re: sur quelle patteforme/OS?

        Posté par . Évalué à 1.

        poll() est plus efficasse qu'un simple select...c'est la version upgradé....
  • # Module noyau ?

    Posté par . Évalué à 2.

    Je suppose que tu es sous Linux, un *BSD, ...

    Sur plateforme x86, pouvoir détourner une IRQ et l'exécuter nécessite
    des droits particuliers en mode protégé (ring 0).

    Tu ne pourras pas avoir un gestionnaire d'IRQ en user-land sachant que
    ce gestionnaire d'IRQ doit toujours être accessible (il doit donc toujours
    être dans un espace "fixe", à savoir l'espace noyau). La réalisation d'un
    module noyau me parait nécessaire.

    Un ouvrage intéressant et qui pourrait t'aider est "Linux Device Drivers":

    http://lwn.net/Kernel/LDD3/(...)

    Si je ne me trompe pas, la gestion des IRQ devrait être abordée dedans.
    • [^] # Re: Module noyau ?

      Posté par . Évalué à 1.

      Bonjour,

      Plateforme x86, SuSE Linux 2.4.21
      Rédiger un module...oula !!!
      Je pensait pas qu'il faille aller si loin.
      Je ne sais pas trop par ou commencer...
      • [^] # Re: Module noyau ?

        Posté par . Évalué à 2.

        Déjà, fais un petit test en user-land avec select(), comme conseillé
        au-dessus.

        Un squelette écrit à la va-vite (désolé pas testé):

        fd_set rfds;
        int fd[4], max_fd = -1;

        fd[0] = open("/dev/ttyS0",O_RDWR,0600);
        fd[1] = open("/dev/ttyS1",O_RDWR,0600);
        fd[2] = open("/dev/ttyS2",O_RDWR,0600);
        fd[3] = open("/dev/ttyS3",O_RDWR,0600);

        for(i=0;i<4;i++)
        if (fd[i] > max_fd)
        max_fd = fd[i];

        while(1) {
        FD_ZERO(&rfds);
        for(i=0;i<4;i++) FD_SET(fd[i],&rfds);
        select(max_fd+1,&rfds,NULL,NULL,NULL);

        for(i=0;i<4;i++)
        {
        if (FD_ISSET(fd[i],&rfds)) {
        printf("qqch recu sur ttyS%d\n",i);
        }
        }
        }

        Un "man select()" t'expliquera comment marchent FD_SET, FD_CLR,
        etc.
        • [^] # Re: Module noyau ?

          Posté par . Évalué à 1.

          OK, je vais déjà essayer tous ca
          Merci pour les infos
        • [^] # Re: Module noyau ?

          Posté par . Évalué à 2.

          et pour la version a timeout, test la valeur de retour de select (chose qui doit etre faite de toute facon :-) ).

          Daniel
          --
          • [^] # Re: Module noyau ?

            Posté par . Évalué à 3.

            C'est une excellente remarque, le retour de tout appel système doit
            être testé :)

            Dans mon petit exemple, il faut donc tester le retour des fonctions
            "open" et "select".

            Même sans timeout, select() peut être interrompu par un signal
            (dans ce cas valeur de retour == -1 et errno == EINTR), c'est
            important d'en tenir compte.
        • [^] # Re: Module noyau ?

          Posté par . Évalué à 1.

          OK, je vais déjà essayer tous ca
          Merci pour les infos

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.