Forum Programmation.c Port série

Posté par  .
Étiquettes : aucune
0
26
juin
2006
Bonjour,

un petit branchement me permet de recevoir signal sur une des broches d'un port série, et le but du jeu est de déterminer quand il y a changement d'état sur cette broche.
J'ai donc réalisé un petit programme qui lit l'état de cette broche (sur code est inspiré de celui de statserial), et tout fonctionne bien lorsque le signal est lent, mais pas lorsqu'il est rapide.

J'ai fait différents essais (code release, réglage du port sur 115000 bauds, nice) mais rien n'y fait je ne vois pas tous les signaux.

Quelqu'un a-t-il une idée ?

PS :
- je suis sûr des signaux car ceux-ci sont générés par un générateur de signal
- pour mes tests de lecture, cela échoue à la valeur de 1280 tests par seconde, alors que j'aurai besoin au final de plus de test !
  • # mon humble avis

    Posté par  . Évalué à 4.

    tu ne peut pas fonctionner comme ca.
    Tu utilise un programme tournant dans le user-space, donc soumis a la volonté du kernel-scheduler pour avoir du temps machine, autrement dit ton programme est souvent interrompu et ne peut donc pas servir a scruter l'etat d'un port en continu.
    La seule solution est de reprendre/modifier le driver de ton port serie et d'utiliser l'interruption qui est généré sur le changement d'état de CTS ou DSR soit pour faire ton traitement soit pour t'interfacer avec ton appli.

    en général sur un pc c'est un uart compatible 16c550 qui est monté voici un lien vers le datasheet
    http://focus.ti.com/docs/prod/folders/print/tl16c550c.html#t(...)
    • [^] # Re: mon humble avis

      Posté par  . Évalué à 1.

      je m'en doutais un peu ...

      Mais j'ai pas très envie de travailler côté noyau si je n'y suis pas strictement obligé ...

      Penses-tu que je pourrais faire quelque chose côté utilisateur avec un autre port (j'ai un électronicien sous la main :-)) ?
      • [^] # Re: mon humble avis

        Posté par  . Évalué à 1.

        Sans électronique à coté ça me semble impossible de detecter autant de fronts .... déjà 1280hz ça parait énorme...

        Une autre solution simple serait de lire un compteur par le port parallèle par exemple.

        Mais ça dépend de ce que tu veux faire.
        -Compter le nombre de front ?
        -Réaliser une opération à chaque front ? (>1280Hz sans intérruption ça parait impossible)
        • [^] # Re: mon humble avis

          Posté par  . Évalué à 2.

          j'ai besoin de savoir quand arrivent ces fronts (je log leur date d'occurence) et ensuite avec cette information, je peux "rejouer" en tenant compte des moments d'arrivé de ceux-ci.

          De toute façon, cela vous semble trop rapide ... Donc même en jouant avec les paramètres de latence du noyau (et la préemptivité), rien n'y ferait.

          Côté noyau, cela sera fiable et assez rapide ?
          • [^] # Re: mon humble avis

            Posté par  . Évalué à 1.

            vous me direz qu'il y a pas d'autres choix ......


            Merci pour les conseils :-)
          • [^] # Re: mon humble avis

            Posté par  . Évalué à 2.

            Arg ! Surtout pas ! On ne passe pas en mode noyau simplement parce que le reste a échoué, on essaie plutôt de résoudre le problème en amont ...

            Si tu fais une scrutation active (polling) dans un pilote du noyau, c'est le système entier qui va être bloqué le temps que ton pilote se lasse (cela arrive avec certains pilotes propriétaires), et sans possibilité d'interrompre celui-ci avec un Ctrl-C ou un Kill. Je ne parle pas non plus de ce qu'il risque de se passer si ton programme contient des bugs, segfaults, ou autre. je passe également sur le fait que ton pilote va entrer en conflit avec les vrais gestionnaires des ports série et parallèle, et que c'est également lui qui sera chargé de déclarer les ressources comme utilisées ou non auprès du reste du noyau. Enfin, à ce niveau, tu travailles en dessous de toutes les bibliothèques de fonctions. Même un bête printf() te sera interdit. Il te faudra utiliser les fonctions dédiés du noyau ...

            un petit branchement me permet de recevoir signal sur une des broches d'un port série, et le but du jeu est de déterminer quand il y a changement d'état sur cette broche. J'ai donc réalisé un petit programme qui lit l'état de cette broche (sur code est inspiré de celui de statserial), et tout fonctionne bien lorsque le signal est lent, mais pas lorsqu'il est rapide.


            On va commencer par le début : c'est quelle broche ?

            Autrement, plutôt que de faire une scrutation des ports, il faut essayer d'attaquer une ligne suceptible de déclencher une interruption (IRQ), et la lire à ce moment.

            D'autre part, je sais que l'interruption 14h du BIOS propose exactement ce genre de choses : les bits 3 à 0 sont nommés bits "delta" pour cela.

            * bit 7 : liaison avec le modem récepteur établie
            * bit 6 : le téléphone sonne
            * bit 5 : modem activé
            * bit 4 : modem prêt à émettre
            * bit 3 : le bit 7 a changé
            * bit 2 : le bit 6 a changé
            * bit 1 : le bit 5 a changé
            * bit 0 : le bit 4 a changé

            Par contre, je ne me souviens plus si c'est l'interruption elle-même qui gère le delta ou bien si c'est le contrôleur série qui les maintient dans son propre registre. De toutes façons, à partir du moment où c'est l'électronique qui nous prévient lorsqu'il est temps de le faire, il est aisé de les remettre en oeuvre ...
            • [^] # Re: mon humble avis

              Posté par  . Évalué à 1.

              Je suis d'accord avec toi sur l'utilisation d'une interruption, mais côté utilisateur peut-on être à l'écoute d'une interruption (je pensais que l'on ne pouvais pas sous linux :-P) ?

              Côté cable je peux brancher sur la broche de mon choix.
              • [^] # Re: mon humble avis

                Posté par  . Évalué à 2.

                pour la gestion proprement dite il te faut etre dans le noyeau.
                il y as un exemple simple dans le rubiny qui peut te servir pour base de depart pour ta separation en deux partie de ton projet, il utilise le port paralelle et une pin en particulier qui est suceptible de genere une IT (pour info l'irq latency sur un kernel 2.6 est quand meme au alentour de quelque milli sur un linux quelque peut charger).
                1) driver qui date les changements d'etat de la pin
                2)prog en espace utilisateur fait la lecture des donnée

                Il ne me semble pas possible sans faire de point de blocage dans le kernel de rejoué tes mesures. A quel frequence max espere tu foncionner ?
                • [^] # Re: mon humble avis

                  Posté par  . Évalué à 1.

                  Rubini, c'est l'auteur de Linux Device Driver ?
                  Que veux-tu dire avec "l'Irq latency [...]" ?

                  "rejouer les mesures"
                  en fait, j'ai besoin de savoir comment se succèdent les signaux, pour ensuite générer des évènements à l'occurence de certains d'entre eux (par exemple, je fais quelque chose dès que les 40 premiers sont passés). Mon idée était donc de loguer les temps des impulsions, et lorsqu'il faudra y aller "pour de vrai", je n'écouterai plus les impulsions, mais m'appuyerai sur les temps relevés.

                  Pour l'heure, je n'ai pas d'idée réelle des fréquences (je vais bientôt pouvoir aller avec un oscillo sur la bête pour voir les signaux qu'elle émet), mais les signaux devraient être émis dans les alentours de 1280 fois par seconde (là encore c'est des hypothèses).
                  • [^] # Re: mon humble avis

                    Posté par  . Évalué à 2.

                    Rubini, c'est l'auteur de Linux Device Driver ?
                    oui
                    Que veux-tu dire avec "l'Irq latency [...]" ?
                    c'est le temps entre la generation du signal irq sur la carte mere et le temps ou le systeme donne la main a ta routine d'interruption.

                    en fait, j'ai besoin de savoir comment se succèdent les signaux, pour ensuite générer des évènements à l'occurence de certains d'entre eux (par exemple, je fais quelque chose dès que les 40 premiers sont passés). Mon idée était donc de loguer les temps des impulsions, et lorsqu'il faudra y aller "pour de vrai", je n'écouterai plus les impulsions, mais m'appuyerai sur les temps relevés.
                    ou commence le comptage des 40 ? je ne comprend pas vraiment le truc a faire. Sinon un driver est tout a fait capable de signaler (par un signal) a une application user que quelque chose c'est passé (ca evite les methodes de pooling ou les i/o bloquante)

                    Pour l'heure, je n'ai pas d'idée réelle des fréquences (je vais bientôt pouvoir aller avec un oscillo sur la bête pour voir les signaux qu'elle émet), mais les signaux devraient être émis dans les alentours de 1280 fois par seconde (là encore c'est des hypothèses).
                    cela fais environ 1 kilo-hertz, c'est limite pour traiter ca en soft pur a mon avis...
                    • [^] # Re: mon humble avis

                      Posté par  . Évalué à 1.

                      cela fais environ 1 kilo-hertz, c'est limite pour traiter ca en soft pur a mon avis...

                      C'est ce dont j'ai peur également.

                      Encore merci pour les conseils :-)
  • # Linux temps reel

    Posté par  . Évalué à 2.

    Je me demande si linux est bien indiqué pour ce genre de traitement. A mon avis, un OS temps réel se comportera mieux (au hasard, QNX).
    Au siecle dernier, j'echantillonais à plus de 20000KHZ un convertisseur analogique/numerique sur une carte dédié ISA d'un P200, et pas sous interruption (uniquement en poll), mais sous QNX.

    A priori, 1300Hz c'est une fréquence tellement basse que rien ne devrait pouvoir t'empecher d'echantilloner une ligne du port série. A moins que l'UART ait un débit limité, c'est a dire qu'elle ne renvois pas le signal qu'elle recoit en entrée.

    Tu peux aussi jouer sur les valeurs de quatum de temps du noyau, pour faire en sorte que les taches utilisateurs aient moins de temps a consacrer, mais plus rapidement.
    • [^] # Re: Linux temps reel

      Posté par  . Évalué à 2.

      Et sur le port parallele, cela ne serait pas plus simple ? (les 8 bits de données sont directements accessibles sur un port, d'apres mes vagues souvenirs de ma Bible Du PC)
    • [^] # Re: Linux temps reel

      Posté par  . Évalué à 1.

      cette carte était une carte d'acquisition ? Auquel cas, tu aurais déjà là un périphérique dédié à ce genre de chose ce qui changerait la donne, non ?

      Le temps "réel" est une solution qui est envisageable, mais n'est-ce pas un peu lourd juste pour avoir des "bips" ? (c'est vrai quoi :-) quand on pense que l'on a des PC qui va vont à des Mhz ou Ghz, ne pas pouvoir suivre des signaux à quelques kilos Hz c'est triste ...)
      • [^] # Re: Linux temps reel

        Posté par  . Évalué à 1.

        Il me semble qu'en utilisant un autre port tu pourrais aisément grimper en fréquence.
        Par exemple, GNURadio (http://www.gnu.org/software/gnuradio/index.html) permet de capter des signaux comme la HDTV (plusieurs Ghz) mais moyennant l'utilisation du PCI / usb2 ...
        Peut être l'utilisation de l'usb serait-elle avisée dans ton cas ?
        • [^] # Re: Linux temps reel

          Posté par  . Évalué à 1.

          Peut être l'utilisation de l'usb serait-elle avisée dans ton cas ?

          je ne sais pas si c'est plus adéquat (surtout qu'il faut se débrouiller pour que cela arrive sur le port USB), mais c'est toujours une piste :-), merci.

Suivre le flux des commentaires

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