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

C Discussion :

Lecture port série aléatoire linux


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Novembre 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte matériel
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Novembre 2012
    Messages : 21
    Points : 17
    Points
    17
    Par défaut Lecture port série aléatoire linux
    Bonjour à tou(te)s,

    Je sèche sur une erreur qui se produit dans certaines conditions dans un read d'un port série.

    Le problème est présent quand je démarre l'ordinateur et lance le programme
    Ensuite, comme je cherche à comprendre ce qui se passe, je teste le port série avec un autre programme, screen ou moserial par exemple
    Je constate que tout fonctionne avec ceux-cis.
    Suite à cela, je réessaye mon programme et il fonctionne correctement

    Voici comment j'initialise le port et je fais le read dont le perror me répond
    'ressource temporarily unavailable'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    serial = open("/dev/ttyUSB0", O_RDWR|O_NONBLOCK|O_NOCTTY);
        if(serial == -1)
            {
             printf("Unable to open ttyUSB0\n");
             exit(0);
            }
     
        // intitialise de port serie ouvert
        tcgetattr(serial, &options);
        cfsetispeed(&options, B19200);
        cfsetospeed(&options, B19200);
        options.c_cflag |= (CLOCAL|CREAD);
        options.c_cflag &= ~PARENB;
        options.c_cflag &= ~CSTOPB;
        options.c_cflag &= ~CSIZE;
        options.c_cflag |= CS8;
        options.c_cc[VMIN] = 1;
        options.c_cc[VTIME] = 0;
        tcsetattr(serial, TCSANOW, &options);
        fcntl(serial, F_SETFL, FNDELAY);
    le read
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char cmd[10] = {2, 78, 5, 0, 32, 32, 32, 32, 229, 83};
        i = write(serial, cmd, 10);
        usleep(200000);
        if(read(serial, buffer, 8) < 0)
          {
           perror("rien a lire");
           exit(0);
           }
    Bon je sais usleep n'est pas très élégant mais je verrai cela quand j'aurai levé mon problème

    Une idée ?

    merci

    Alfybe

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations forums :
    Inscription : Février 2010
    Messages : 87
    Points : 62
    Points
    62
    Par défaut
    salut

    j'ai déja utilisé le portCom pour windows donc je ne sais les variables et les fonctions équivalente pour ton système mais pour windows on utilisent trois "structure"

    DCB: est utiliser pour la configuration de portCom exemple B19200/8bits/parity
    COMSTAT: est utiliser pour voir si le control a récu les donnée avant d'appeler la foction "read()"
    COMMTIMEOUTS: est utiliser pour configurer le "timeout" pour les fonctions "read() et write()" par exemple
    COMMTIMEOUTS.ReadTotalTimeoutConstant = 200000; au lieu d'utiliser la fonction "usleep()"

  3. #3
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Je m'etais fait une classe pour gerer les ports COM sur Windows et linux. Jettes-y un coup d'oeil :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    #include "dialogueCOM.h"
     
    using namespace std;
     
    //Ensemble des fonctions gérant le port COM : initialisation, ouverture, lecture, écriture et fermeture
     
    // Délais d'attente sur le port COM
    #if defined (WIN32)
    COMMTIMEOUTS g_cto =
    {
        //MAX_WAIT_READ,  /* ReadIntervalTimeOut          */ Attente infinie
        0,              /* ReadTotalTimeOutMultiplier   */
        //MAX_WAIT_READ,  /* ReadTotalTimeOutConstant     */
        0,              /* WriteTotalTimeOutMultiplier  */
        0               /* WriteTotalTimeOutConstant    */
    };
     
    // Configuration du port COM
    DCB g_dcb =
    {
        sizeof(DCB),        /* DCBlength            */
        19200,               /* BaudRate             */
        TRUE,               /* fBinary              */
        FALSE,              /* fParity              */
        FALSE,              /* fOutxCtsFlow         */
        FALSE,              /* fOutxDsrFlow         */
        DTR_CONTROL_ENABLE, /* fDtrControl          */
        FALSE,              /* fDsrSensitivity      */
        FALSE,              /* fTXContinueOnXoff    */
        FALSE,              /* fOutX                */
        FALSE,              /* fInX                 */
        FALSE,              /* fErrorChar           */
        FALSE,              /* fNull                */
        RTS_CONTROL_ENABLE, /* fRtsControl          */
        FALSE,              /* fAbortOnError        */
        0,                  /* fDummy2              */
        0,                  /* wReserved            */
        0x100,              /* XonLim               */
        0x100,              /* XoffLim              */
        8,                  /* ByteSize             */
        NOPARITY,           /* Parity               */
        ONESTOPBIT,         /* StopBits             */
        0x11,               /* XonChar              */
        0x13,               /* XoffChar             */
        '?',                /* ErrorChar            */
        0x1A,               /* EofChar              */
        0x10                /* EvtChar              */
    };
     
    void dialogueCOM::InitCOM()
    {
      g_hCOM = NULL;
    }
     
    bool dialogueCOM::OpenCOM(int nId)
    {
        char szCOM[16];
     
        sprintf(szCOM, "\\\\.\\COM%d", nId);
        g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
                            OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
        if (g_hCOM == INVALID_HANDLE_VALUE)
            return FALSE;
     
        SetupComm(g_hCOM, RX_SIZE, TX_SIZE);
     
        if (!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb))
          {
    	CloseHandle(g_hCOM);
            return FALSE;
          }
     
        PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
        EscapeCommFunction(g_hCOM, SETDTR);
        return TRUE;
    }
     
    bool dialogueCOM::CloseCOM()
    {
        CloseHandle(g_hCOM);
        return TRUE;
    }
     
    bool dialogueCOM::ReadCOM(void* buffer, int nBytesToRead, int* readBytes)
    {
      int Res;
      char tmp[2] = "";
     
      *readBytes = 0;
      do
        {
          if (!ReadFile(g_hCOM, tmp, nBytesToRead, (DWORD*)&Res, NULL))
    	return false;
          if (Res > 0)
    	{
    	  if ((tmp[0] >= 'A' && tmp[0] <= 'F') || (tmp[0] >= '0' && tmp[0] <= '9'))
    	    pChaine[(*readBytes)++] = c;
    	  else if (tmp[0] == 13 && *readBytes > 0)
    	    {
    	      pChaine[*readBytes] = '\0';
    	      return true;
    	    }
    	}
        } while (*readBytes < nBytesToRead);
      pChaine[*readBytes] = '\0';
      return true;
    }
     
    bool dialogueCOM::WriteCOM(void* buffer, int nBytesToWrite, int* pBytesWritten)
    {
      return WriteFile(g_hCOM, buffer, nBytesToWrite, (DWORD*)pBytesWritten, NULL);
    }
    #else
    bool dialogueCOM::Configurer(const char* pPort,int Vitesse,int NbBits,int Parite,int NbStop)
    {
      int Res;
      //Ouverture de la com
      fd = open(pPort, O_RDWR/*| O_NONBLOCK*/);
     
      if (fd == -1)
        {
          cerr << "Erreur lors de l'ouverture du port !" << endl;
          return false;
        }
      else
        {
          cout << "Ouverture de " << pPort << " reussie." << endl;
          // Suppression de l'echo
          //Config.c_lflag &= ~(ECHO);
     
          Config.c_iflag = IGNBRK | IGNPAR;
          Config.c_oflag = 0;
     
          Config.c_cflag = CREAD | CLOCAL;
          Config.c_cflag = Config.c_cflag & ~CRTSCTS;
          // Vitesse
          switch (Vitesse)
    	{
    	case BPS9600:
    	  Config.c_cflag |= B9600;
    	  break;
    	case BPS4800:
    	  Config.c_cflag |= B4800;
    	  break;
    	case BPS2400:
    	  Config.c_cflag |= B2400;
    	  break;
    	case BPS19200:
    	  Config.c_cflag |= B19200;
    	  break;
    	default:
    	  cerr << "Vitesse invalide" << endl;
              return false;
    	}
          // Taille data
          switch (NbBits)
    	{
    	case BIT8:
    	  Config.c_cflag |= CS8;
    	  break;
    	case BIT7:
    	  Config.c_cflag |= CS7;
    	  break;
    	case BIT6:
    	  Config.c_cflag |= CS6;
    	  break;
    	case BIT5:
    	  Config.c_cflag |= CS5;
    	  break;
    	default:
    	  cerr << "Taille de donnee non conforme" << endl;
    	  return false;
    	}
          // Parite    
          switch (Parite)
    	{
    	case PARITE_PAIRE:
    	  Config.c_cflag |=  PARENB;
    	  break;
    	case PARITE_IMPAIRE:
    	  Config.c_cflag |= (PARODD | PARENB);
    	  break;
    	default:
    	  break;
    	}
     
          // Nombre de bits de stop
          switch (NbStop)
    	{
    	case STOP2:
    	  Config.c_cflag |= CSTOPB;
    	  break;
    	}
     
          // Application de la configuration
          Res = tcsetattr(fd, TCSANOW, &Config);
          if (Res == -1)
    	{
    	  cerr << "Erreur lors de l'application de la configuration" << endl;
    	  return false;
    	}
          tcflush(fd, TCIFLUSH);
          tcflush(fd, TCOFLUSH);
        }
      return true;
    }
     
    bool dialogueCOM::OpenCOM(std::string s)
    {
      return Configurer(s.c_str(), BPS19200, BIT8, PAS_DE_PARITE, STOP1);
    }
     
    dialogueCOM::dialogueCOM()
    {
    }
     
    dialogueCOM::~dialogueCOM()
    {
      if (fd >= 0)
        close(fd);
    }
     
    bool dialogueCOM::ReadCOM(char* pChaine, int Nb, int *readBytes)
    {
      char c = 0;
      int i;
     
      *readBytes = 0;
      do
        {
          if (read(fd, &c, 1) > 0)
    	{
    	  if ((c >= 'A' && c <= 'F') || (c >= '0' && c <= '9'))
    	    pChaine[(*readBytes)++] = c;
    	  else if (c == 13 && *readBytes > 0)
    	    {
    	      pChaine[*readBytes] = '\0';
    	      return true;
    	    }
    	}
          else
    	usleep(500);
        } while (*readBytes < Nb);
      pChaine[*readBytes] = '\0';
      return true;
    }
     
    bool dialogueCOM::WriteCOM(void* pChaine, int toWrite, int *written)
    {
      if (fd < 0 || (*written = write(fd, pChaine, toWrite)) < 0)
        return false;
      return true;
    }
    #endif

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par alfybe Voir le message
    Bonjour à tou(te)s,

    Je sèche sur une erreur qui se produit dans certaines conditions dans un read d'un port série.

    Le problème est présent quand je démarre l'ordinateur et lance le programme
    Ensuite, comme je cherche à comprendre ce qui se passe, je teste le port série avec un autre programme, screen ou moserial par exemple
    Je constate que tout fonctionne avec ceux-cis.
    Suite à cela, je réessaye mon programme et il fonctionne correctement

    […]

    Bon je sais usleep n'est pas très élégant mais je verrai cela quand j'aurai levé mon problème
    Effectivement, « resource temporarily unavailable » correspond à l'erreur EAGAIN et est renvoyée par read() lorsqu'il n'y a rien à lire.

    Pourquoi ouvres-tu systématiquement ton port en mode non-bloquant, d'une part, et en désactivant les lignes de contrôle, d'autre part ?

    Ensuite, sleep(200000), ça fait une temporisation de 0,2 seconde. Un port série, c'est lent et l'application de l'autre côté a probablement de l'overhead avant sa première transmission. Essaie de rajouter un zéro à ce délai pour voir si elle a le temps de te répondre.

    Vois également select() et poll() si te ne les connais pas encore…

  5. #5
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Novembre 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte matériel
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Novembre 2012
    Messages : 21
    Points : 17
    Points
    17
    Par défaut
    D'abord, merci à tous pour votre aide

    A PIC16F877A
    Sous windows, cest différent, sous linux j'utilise termios merci quand même

    A imperio, merci du code, je vais jetter un oeil

    A Obsidian
    J'ai bien identifié le problème, rien à lire... le problème c'est que l'interface USB/RS485 qui a des loupiottes a recu qq chose et le read me dit qu'il n'y a rien a lire sauf....
    que si je me connecte avec screen (par exemple screen /dev/ttyUSB0 19200), que je me déconnecte, je relance mon programme... et là, magie, cela fonctionne (même avec usleep(200000)!). Si je débranche le port USB, je le rebranche, là ça fonctionne plus.

    Donc je reçois bien les données, mais elles sont bloquées par le système car j'omets un paramètre que screen active correctement... mais lequel??? that is the question????

    merci

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par alfybe Voir le message
    Donc je reçois bien les données, mais elles sont bloquées par le système car j'omets un paramètre que screen active correctement...
    Effectivement…

    mais lequel??? that is the question????
    Que donne stty -a -F /dev/ttyUSB0 depuis le shell, effectué avant et après les appels à screen et/ou moserial ?

  7. #7
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Novembre 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte matériel
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Novembre 2012
    Messages : 21
    Points : 17
    Points
    17
    Par défaut
    Bonjour,

    Voici ce que donne stty -a -F /dev/ttyUSB0

    au démarrage de l'ordinateur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    speed 9600 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
    eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
    werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
    -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
    -iuclc -ixany -imaxbel -iutf8
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
    echoctl echoke
    Après avoir lancé mon programme (avec le message d'erreur)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    speed 19200 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
    eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
    werase = ^W; lnext = ^V; flush = ^O; min = 100; time = 2;
    -parenb -parodd cs8 hupcl -cstopb cread clocal crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
    -iuclc -ixany -imaxbel -iutf8
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
    echoctl echoke
    Après avoir utilsé screen /dev/ttyUSB0

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    speed 9600 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^H; eof = ^D; eol = <undef>;
    eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
    werase = ^W; lnext = ^V; flush = ^O; min = 100; time = 2;
    -parenb -parodd cs8 -hupcl -cstopb cread clocal -crtscts
    -ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff
    -iuclc -ixany -imaxbel -iutf8
    -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    -isig -icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
    Puis après avoir lancé mon programme (pas d'erreur)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    speed 19200 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^H; eof = ^D; eol = <undef>;
    eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
    werase = ^W; lnext = ^V; flush = ^O; min = 100; time = 2;
    -parenb -parodd cs8 -hupcl -cstopb cread clocal crtscts
    -ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff
    -iuclc -ixany -imaxbel -iutf8
    -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    -isig -icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

    Je n'ai pas encore étudié les différences...

    A bientôt

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Il y a beaucoup de paramètres qui changent d'un bloc à l'autre, à commencer par la vitesse, accélérée par ton programme puis redescendue à 9600 par screen. Mais cela ne semble pas être la cause puisque ton programme la ré-accélère à nouveau dans le quatrième bloc avec succès. En revanche :

    Citation Envoyé par alfybe Voir le message
    Bonjour,

    Voici ce que donne stty -a -F /dev/ttyUSB0

    au démarrage de l'ordinateur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    speed 9600 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
    eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
    werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
    -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
    -iuclc -ixany -imaxbel -iutf8
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
    echoctl echoke
    Après avoir lancé mon programme (avec le message d'erreur)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    speed 19200 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
    eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
    werase = ^W; lnext = ^V; flush = ^O; min = 100; time = 2;
    -parenb -parodd cs8 hupcl -cstopb cread clocal crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
    -iuclc -ixany -imaxbel -iutf8
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
    echoctl echoke
    Après avoir utilsé screen /dev/ttyUSB0

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    speed 9600 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^H; eof = ^D; eol = <undef>;
    eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
    werase = ^W; lnext = ^V; flush = ^O; min = 100; time = 2;
    -parenb -parodd cs8 -hupcl -cstopb cread clocal -crtscts
    -ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff
    -iuclc -ixany -imaxbel -iutf8
    -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    -isig -icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
    On remarque que les paramètres en gras ont bien été modifiés par screen et restent tels quels lors de l'appel à ton programme.

    Historiquement, UNIX considère que les lignes séries servent à y relier des terminaux et, d'une manière plus large, des « équipements terminaux de transmission de données ». C'est pour cela que Linux classe le fichier spécial du port série dans les TTY (anciennement, il s'appelait cua0). Et de fait :

    • echo sert à activer l'écho local automatique des caractères saisis par l'expéditeur. Pas souhaitable dans le cas qui nous intéresse ;
    • icanon sert à activer le mode canonique, c'est-à-dire la façon la plus courante pour l'utilisateur d'exploiter un terminal : dans ce mode, les données sont gérées en lignes : elles ne sont transmises au processus qu'à partir du moment où l'on a appuyé sur Entrée/Return et avant cela, toute la ligne peut être corrigée ou effacée à loisir avec les touches Erase (Backspace sur PC), Kill (Ctrl-U par défaut), WErase (Word Erase : Ctrl-W par défaut) et Rprnt (Reprint : Ctrl -R). Pas souhaitable non plus : on souhaite que tout caractère généré par l'équipement distant soit immédiatement reçu ;
    • opost sert à activer le post-traitement des caractères émis, c'est-à-dire à ignorer toutes les options en « o---- » quand cette option-là n'est pas active. Il s'agit principalement de correction de retours à la ligne selon le contexte, par exemple « \n » traduit en « \r\n », ce qui est souvent nécessaire. Dans le cas présent, on n'en veut pas non plus.


    Et enfin :

    Citation Envoyé par man stty
    Paramètres spéciaux :

    min N Lorsque -icanon est configuré, indique le nombre minimal de caractères à lire pendant la durée `time' avant que la lecture n'échoue.

    time N Lorsque -icanon est configuré, indique la durée (en dixièmes de secondes) pour lire `min' caractères avant que la lecture n'échoue.
    Tu as les valeurs min=100 et time=2. Lorsque icanon est désactivé (ici à partir de screen), tu as deux dixièmes de secondes pour recevoir cent caractères, faute de quoi la lecture sera considérée comme ayant échouée. Même si ton programme marche, vérifie que tu reçois bien toutes tes données, surtout sur la fin.

    La man page Linux de stty n'est pas très loquace car son traducteur a eu des difficultés à la finir car il butait sur certains termes et elle est restée en l'état depuis. Celle de AIX d'IBM est beaucoup plus complète : http://publib.boulder.ibm.com/infoce...cmds5/stty.htm

  9. #9
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Novembre 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte matériel
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Novembre 2012
    Messages : 21
    Points : 17
    Points
    17
    Par défaut
    Obsidian,
    Merci beaucoup pour ton aide intelligente qui m'a permise de trouver la solution
    C'était simplement le mode canonique qui n'était pas bien paramétré.
    J'ai ajouté 'options.c_lflag = -ICANON;' et ça roule...

    J'ai découvert la commande stty qui est bien pratique.

    Mille mercis encore

    Alfybe

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    À ton service. Merci d'avoir marqué la discussion comme résolue également. Sache cependant que pour ce faire, il suffit de cliquer sur le bouton en bas de page.

    À bientôt.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture port série sur LINUX
    Par ABouras dans le forum Linux
    Réponses: 4
    Dernier message: 23/11/2012, 14h36
  2. Lecture sur port série sous Linux
    Par DangerousBowlOfJelly dans le forum C
    Réponses: 6
    Dernier message: 28/03/2008, 17h00
  3. [Série] Accès au port série sous linux
    Par ghost dans le forum Entrée/Sortie
    Réponses: 10
    Dernier message: 10/10/2007, 10h43
  4. Pb de lecture port série
    Par amalis dans le forum Bibliothèques tierces
    Réponses: 1
    Dernier message: 18/03/2006, 16h21
  5. Port série sous Linux
    Par naoned dans le forum Bibliothèques tierces
    Réponses: 2
    Dernier message: 21/11/2005, 16h45

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