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

Embarqué Discussion :

Gestion des erreurs (RX error, CRC error, Bad StartOfFrame)


Sujet :

Embarqué

  1. #1
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut Gestion des erreurs (RX error, CRC error, Bad StartOfFrame)
    Bonjour,

    J'ai un environnement avec un Raspi, un FTDI RS232 et je programme en C. J'utilise les fonctions standard write et read, avec un select pour gérer le timeout.
    A chaque envoie de trame, l'équipement en face réponds, un write est donc toujours suivi d'un read.
    L'écriture ne me pose aucun problème. La lecture par contre, il m'arrive :
    - de ne pas recevoir de trame en retour, le timeout du select déclenche (normalement ça signifie que celle qui a été envoyé a mal été reçue, ou que l'équipement mets trop de temps à répondre)
    - de ne pas recevoir le bon début de trame
    - d'avoir une erreur de CRC (alors que le reste de la trame parait ok au sniffer)

    Je suis à la recherche de conseils ou de littératures traitant les bonnes pratiques pour gérer les erreurs sur une communication série.

    Est ce qu'il faut renvoyer en boucle une trame tant qu'on a pas un retour correct par exemple ? ça me parait pas être une bonne idée.
    D'un autre coté si une trame (de config) est mal passée, ça peut mettre le bazar ensuite ...

    Si vous avez des idées, des infos à partager, je suis preneur et vous en remercie par avance.

    Bonne journée

  2. #2
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Salut,
    Quelle longueur entre le RPI et l'équipement d'en face ?
    Quelle type de câble ?
    Quelle environnement de travail, sur un site industriel ou sur table ?

    A+
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  3. #3
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Bonjour,

    J'ai ce type de câble : https://www.ftdichip.com/Support/Doc...232_CABLES.pdf
    Longueur 1m80, sur table.

    Mais c'est d'une manière plus générale que j'aimerais savoir comment bien gérer les erreurs de COM, parce que si je dois faire un while à chaque trame pour être sur que ça passe bien... je ne pense pas que ça soit la meilleur solution.

    Merci par avance.

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Je comprends mais tes erreurs

    Citation Envoyé par dark_vidor
    - de ne pas recevoir de trame en retour, le timeout du select déclenche (normalement ça signifie que celle qui a été envoyé a mal été reçue, ou que l'équipement mets trop de temps à répondre)
    - de ne pas recevoir le bon début de trame
    - d'avoir une erreur de CRC (alors que le reste de la trame parait ok au sniffer)
    Me font penser à des erreurs de communications hardware (genre un clone de câble) et pas à un problème software.
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  5. #5
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Peut être que c'est l'équipement en face qui réponds pas ou mal ... mais justement comment "bien" gérer ces erreurs ?
    De mon coté j'ai suivit les exemples :
    https://www.cmrr.umn.edu/~strupp/serial.html#3_1_5
    http://ftp.lip6.fr/pub/linux/french/..._series.html#6

  6. #6
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Tu utilises un protocole maison peut être ?
    Parce que dans les protocoles courants, pour les questions que tu te poses il y a des choses d'implémentées automatiquement (handshaking / contrôle de trame) ou alors la main est donnée à l'utilisateur.

    En I2C,
    Le handshaking se fait via des ACK (acknowledge = l'esclave répond "bien reçu") ou NACK (no acknowledge = l'esclave répond "problème ou pas compris") et à la question ; que faire au niveau du maître si NACK ? Tu peux faire ce que tu veux, réssayer ? arrêter ? renvoyer un code d'erreur à l'utilisateur ?

    En ModBus,
    L'esclave connait à l'avance des codes d'erreurs : 01 - Illegal Function, 02 - Illegal Data Address, 03 - Illegal Data Value, 04 - Slave Device Failure, 05 - Acknowledge, 06 - Slave Device Busy. Si le maître reçoit le code 02, adresse illégale, alors il est inutile de réessayer il vaut mieux renvoyer un code d'erreur à l'utilisateur.

    En ICMP,
    C'est toi qui dit à la commande "ping" combien de fois elle doit répéter la requête avant de constater un échec de réponse.


    Là où je veux en venir, c'est que dans mes 3 exemples ci dessus on a 3 manières de gérer une erreur (on répète et c'est toi qui estime combien de fois, on renvoie directement un message d'erreur sans réessayer, on répète le nombre de fois que l'utilisateur veut)


    Qu'elle est le protocole utilisé dans l'esclave ?
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  7. #7
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Bonjour,
    Effectivement c'est un protocole "propriétaire", je connais le début de trame de réponse attendu, la longueur de la trame de réponse et re-calculer le CRC pour vérifier l'intégrité des données.

    Donc les retours d'erreurs possibles sont ceux exprimés plus haut
    - de ne pas recevoir de trame en retour, le timeout du select déclenche (normalement ça signifie que celle qui a été envoyé a mal été reçu, ou que l'équipement mets trop de temps à répondre)
    - de ne pas recevoir le bon début de trame
    - d'avoir une erreur de CRC (alors que le reste de la trame parait ok au sniffer)
    Estimer combien de fois rééssayer revient à faire un for pour chaque envoie de trame et sortir une erreur si ça passe pas

  8. #8
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Ça se précise

    - Dans beaucoup de protocole le Timeout et suivie d'une répétition car l'équipement qu'on interroge peut être entrain de sortir de veille ou de démarrer. Voir l'exemple du "ping" vers une adresse IP

    - Si tu reçois le mauvais début de trame, ce qui est équivalent au code 01 du ModBus, déjà c'est que le CRC était ok mais il n'est pas nécessaire de répéter l'opération car il n'y a aucune raison que tu reçoives la bonne trame. Tu recevras toujours le mauvais début trame, il faut chercher le problème autre part.

    - Si le CRC n'est pas ok c'est que la donnée est corrompu (pas de bol, c'est une perturbation du signal la plupart du temps) et il faut répéter l'opération. Dans le BUS CAN s'il y a une collision, donc un mauvais CRC, il y a répétition.
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  9. #9
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Bonjour,

    Merci pour ces éléments, en fait dans mon cas il s'agit d'un petit servo moteur que je fait tourner en continue.
    Donc le pas de réponse (timeout) c'est soit que le moteur ne réponds pas (la trame qu'il a reçu était fausse), soit que mon timeout est "trop court" (250ms pour un Bus en 57600), soit que Linux n'a pas eu le temps de bufferisé les paquets reçu (c'est possible ça ?) et le read du coup ne renvoie rien.

    Le début de trame est testé avant le CRC.

    Ma fonction envoie la trame de requete, tente de recevoir la réponse, vérifie le début de la réponse, vérifie le CRC, si un échoue on sort avec un code erreur:

    Code C : 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
    int servoSendRequestAndCheckResponse(unsigned char *tx, size_t len_tx,
                                                unsigned char *rx, size_t len_rx,
                                                unsigned char startOfFrame,
                                                unsigned char srcFrame) {
        int rc = 0;
        unsigned char crc = 0;
     
        // send request
        if (serial_write(tx, len_tx) < 0) {
            rc = SERVO_TX_ERROR;
            log_error("TX error: Frame %s", FRAME_LABEL[srcFrame]);
            goto __error;
        }
     
        // receive response
        if (serial_read(rx, len_rx) < 0) {
            rc = SERVO_RX_ERROR;
            log_error("RX error: Frame %s", FRAME_LABEL[srcFrame]);
            goto __error;
        }
     
        // check start of frame
        if (rx[0] != startOfFrame) {
            rc = SERVO_SYNC_FRAME_ERROR;
     
            printf("Receive: ");
            for (int i = 0; i < len_rx; i++) {
                printf("[%02X]", rx[i]);
            }
            printf("\n");
     
            log_error("Start of frame error: Frame %s, received: %02X", FRAME_LABEL[srcFrame], rx[0]);
            goto __error;
        }
     
        // check CRC
        if (rx[len_rx - 1] != (crc = crc8(rx, len_rx - 1))) {
            rc = SERVO_CRC_ERROR;
            log_error("CRC error: Frame %s, crc8: %02X, received: %02X", FRAME_LABEL[srcFrame], crc, rx[len_rx - 1]);
            goto __error;
        }
     
        __error:
        return rc;
    }

    Mais si j'ai bien compris :
    - je dois identifier les trames "critiques"
    - faire une fonction d’envoi pour X fois
    - sortir une erreur si ça n'a pas fonctionné

  10. #10
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 324
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 324
    Points : 4 134
    Points
    4 134
    Par défaut Trop vite ?
    Bonjour,

    La portion de code laisse entendre une réponse immédiate du périphérique (sauf s'il y a une hypothétique gestion du temps dans la bibliothèque de la liaison série mais je ne vois pas de timeout dans l'appel de la fonction de réception).

    A 56700 bps, il faut compter de l'ordre de 0.2 ms par caractère. Supposons que l'échange soit d'une dizaine de caractères pour la requête puis pour la réponse. Dans le meilleur des cas (hors temps de décodage du CRC et autres traitements par le périphérique) la réponse complète ne parviendrait que 4 ms après l'émission de la requête soit une éternité pour un PC qui ne fait qu'un test - quelques ns au pire dizaines de ns - avant de regarder si la réponse est là.

    Il faut donner le temps à la transmission de se faire et au périphérique de réagir (delay, sleep, pause etc) et ne pas hésiter, comme l'indique Vincent, à réitérer un certain nombre de fois avant de déclarer forfait.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  11. #11
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Bonjour,

    Merci pour ce retour, mais il y a bel et bien un timeout sur le read de 500ms

    Citation Envoyé par dark_vidor Voir le message
    J'utilise les fonctions standard write et read, avec un select pour gérer le timeout.

  12. #12
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 324
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 324
    Points : 4 134
    Points
    4 134
    Par défaut Vécu
    Bonjour,

    J'ai eu la surprise avec Modbus d'avoir un CRC envoyé poids faible puis poids fort alors que les registres (int_16) sont envoyés dans l'autre sens. Il est donc possible de bien calculer le CRC mais de l'envoyer dans le mauvais sens auquel cas la réception déclare le message en erreur.
    Peut être un problème similaire ?

    Salutations.
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  13. #13
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Bonjour,
    Mais dans ce cas je n'aurais aucune trame qui ne passerai ...
    J'ai un défaut avec le timeout qui se déclenche de façon aléatoire (et sur des trames vérifiées), l'erreur se produit 1 fois par heure maximum, et j'attends 100ms après chaque retour de read()

Discussions similaires

  1. [XL-2007] Ma gestion des erreurs "On Error GoTo- -" ne fonctionne plus sur mon PC
    Par Yuoli dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 03/04/2020, 09h18
  2. Gestion d'erreurs : On Error Resume Next
    Par jérémyp8 dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 04/06/2013, 14h26
  3. gestion des exceptions via <error-page>
    Par mrjeronimo dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 16/08/2010, 13h26
  4. Réponses: 3
    Dernier message: 19/09/2007, 17h11
  5. [Sybase ASE 12.5.3] Gestion d'erreur avec @@error
    Par lsone dans le forum Sybase
    Réponses: 5
    Dernier message: 24/07/2006, 22h25

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