Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
743 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Probléme de récupération des données à travers ttyS (LINUX)

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Probléme de récupération des données à travers ttyS (LINUX)

n°1882262
anounito
Posté le 08-05-2009 à 23:26:54  profilanswer
 

Bonjour, j'ai un gros problème que je n'arrive tjrs pas à résoudre !
Je dois récupérer des données provenant d'un montage électronique sur une carte équipée d'un noyau LINUX (FOX Board).
 
Donc pour ce faire j'ai un code en C que j'exécute sur la carte et qui permet d'ouvrir une connexion série (virtuelle) à travers une connexion Bluetooth (rfcomm0) pour envoyer les donnée de mon montage à la carte FOX Board.
 
Ce code en effet marche très bien, mes données arrivent, mais seulement, elles n'arrivent pas comme il faut:
j'envoie des trames de 19 bytes dans un certain ordre bien déterminé, le problème c'est que pratiquement une trame sur 10 n'arrive pas dans l'ordre et certaines trames arrivent avec un byte ou deux qui manquent !!!!
J'ai testé l'envoi de ces données sur un PC avec Hyperterminal et Docklight, mes trames arrivent correctement !
 
Donc le problème vient de mon code C que j'exécute sur la carte (FOX Board), je met le code plus bas si quelqu'un à une solution à mon problème ça m'aidera bcp, d'autant plus je doit finaliser ce projet ds quelque jours !
 
MERCI POUR VOTRE AIDE
 
Exemple de Données correcte:
----------------------------
Chaque trame commence par 02 EA et se termine par 03 comme ci dessous (les xx représentent des valeurs qui peuvent changer)
02 EA xx xx xx xx 00 00 00 00 00 00 00 00 00 00 00 00 03
 
02 EA 3E 00 49 E1 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 EA 3C E1 39 E1 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 EA 3D 00 40 E1 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 EA 40 02 56 E2 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 EA 40 82 5A E2 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 EA 40 00 5B E2 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 EA 41 AC 62 E1 00 00 00 00 00 00 00 00 00 00 00 00 03  
...
 
Exemple de Données incorrecte:
-----------------------------
02 EA 58 00 84 E1 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 00 00 00 00 00 00 00 00 03 EA 55 00 66 E1 00 00 00 00  
02 EA 53 00 4C E1 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 EA 4E 01 CA E1 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 EA 50 02 1D E1 00 00 00 00 00 00 00 00 00 00 00 00 03  
02 00 00 00 00 00 00 00 03 EA 5E 01 E1 00 00 00 00 00 02  
EA 60 01 64 E1 00 00 00 00 00 00 00 00 00 00 00 00 03 02
EA 00 01 1D E1 00 00 00 00 00 00 00 00 00 00 00 00 03 02  
EA 00 01 2B E1 00 03 02 EA 00 01 94 E1 00 00 00 00 00 00  
00 00 00 00 00 00 03 02 EA 00 01 CA 00 00 00 00 00 00 00  
00 00 00 00 03 02 EA 00 01 62 E1 00 00 00 00 00 00 00 00  
00 00 00 00 E1 00 00 00 00 00 00 00 00 00 00 00 00 03 02  
EA 00 02 1D E1 00 00 00 00 00 00 00 00 00 00 00 00 03 02  
EA 00 41 E1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 03 02 EA 00 03 02 EA 00 41 64 E1 00  
...
 
 
CODE C pour l'ouverture de la communication serie sur la carte LINUX:
 

Code :
  1. #include <stdio.h>   
  2. #include <string.h>   
  3. #include <unistd.h>   
  4. #include <fcntl.h>   
  5. #include <errno.h>   
  6. #include <termios.h> 
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <stdlib.h>
  10. #include <stdarg.h>
  11. #include <signal.h>
  12. #define TAILLE_MAX 1000  // Tableau de taille 1000 pour la lecture du nom de fichier
  13. /****************************************************/
  14. /*  CONFIGURATION POUR ÉTABLIR LA CONNEXION SÉRIE   */
  15. /****************************************************/
  16. struct termios stdin_saved_attributes;
  17. struct termios tty_saved_attributes;
  18. int tty_fd;
  19. int tty_open(char* tty_dev) {
  20. struct termios new_attributes;
  21.   tty_fd = open(tty_dev,O_RDWR| O_NOCTTY | O_NONBLOCK);
  22.   if (tty_fd<0) {
  23.    return -1;
  24.   } else {
  25.  tcgetattr(tty_fd,&tty_saved_attributes);
  26.  tcgetattr(tty_fd,&new_attributes);
  27. new_attributes.c_cflag |= CREAD;    // Enable receiver
  28.    new_attributes.c_cflag |= B9600;    // Set baud rate
  29.    new_attributes.c_cflag |= CS8;     // 8 data bit
  30.    new_attributes.c_iflag |= IGNPAR;    // Ignore framing errors and parity errors.  
  31.    new_attributes.c_lflag &= ~(ICANON);   // DISABLE canonical mode.  
  32.               // Disables the special characters EOF, EOL, EOL2,  
  33.               // ERASE, KILL, LNEXT, REPRINT, STATUS, and WERASE, and buffers by lines.
  34.    new_attributes.c_lflag &= ~(ECHO);   // DISABLE this: Echo input characters.
  35.    new_attributes.c_lflag &= ~(ECHOE);   // DISABLE this: If ICANON is also set, the ERASE character erases the preceding input  
  36.               // character, and WERASE erases the preceding word.
  37.    new_attributes.c_lflag &= ~(ISIG);   // DISABLE this: When any of the characters INTR, QUIT, SUSP,  
  38.               // or DSUSP are received, generate the corresponding signal.
  39.  new_attributes.c_cc[VMIN]=1;    // Minimum number of characters for non-canonical read.
  40. new_attributes.c_cc[VTIME]=0;    // Timeout in deciseconds for non-canonical read.
  41.     tcsetattr(tty_fd, TCSANOW, &new_attributes);
  42. }
  43.   return tty_fd;
  44. }
  45. // Serial version of printf
  46. void tty_printf(char *format, ...) {
  47.   va_list argptr;
  48.   char buffer[200];
  49.   va_start(argptr,format);
  50.   vsprintf(buffer,format,argptr);
  51.   va_end(argptr);
  52.   write(tty_fd,buffer,strlen(buffer));
  53. }
  54. void termination_handler (int signum) {
  55. tcsetattr(STDIN_FILENO,TCSANOW,&stdin_saved_attributes);
  56. if (tty_fd>0) tcsetattr (tty_fd,TCSANOW,&tty_saved_attributes);
  57. close(tty_fd);
  58. printf("Exit\n" );
  59. exit(0);
  60. }
  61. int stdin_init(void) {
  62.   struct termios tattr;
  63.   // Make sure stdin is a terminal
  64. if (!isatty (STDIN_FILENO)) {
  65.  fprintf (stderr,"stdin is not a terminal\n" );
  66.   return -1;
  67. }
  68. // Save the terminal attributes so we can restore them later.
  69. tcgetattr (STDIN_FILENO, &stdin_saved_attributes);
  70.   // Set the funny terminal modes.  
  71.   tcgetattr (STDIN_FILENO, &tattr);
  72.   tattr.c_lflag &= ~(ICANON | ECHO); /* Clear ICANON and ECHO. */
  73.   tattr.c_cc[VMIN] = 0;
  74.   tattr.c_cc[VTIME] = 0;
  75.   tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
  76.   return 0;
  77. }
  78. /*********************************************************/
  79. /*  ROUTINE POUR RÉCUPÉRER LES DONNÉES ET LES AFFICHER   */
  80. /*********************************************************/
  81. int main(int argc, char *argv[]) {
  82.   int rxChar;
  83.   char i;
  84.   i=0;
  85.   FILE* fichiersave = NULL;
  86.   FILE* fichiernom = NULL;
  87.   char chaine[TAILLE_MAX] = "";  // Chaîne vide de taille TAILLE_MAX
  88.   printf("Acme Serial Test (press ctrl-c to exit)\n" );
  89.   if (tty_open(argv[1])<0) {
  90.    fprintf (stderr,"tty open error %s\n", strerror(errno));
  91.   exit(EXIT_FAILURE);
  92.   }
  93.   if (stdin_init()<0) {
  94.    printf("stdin init error %s\n", strerror(errno));
  95. //  exit(EXIT_FAILURE);
  96.   }
  97.   if (signal (SIGINT, termination_handler) == SIG_IGN) signal (SIGINT, SIG_IGN);
  98.   if (signal (SIGHUP, termination_handler) == SIG_IGN) signal (SIGHUP, SIG_IGN);
  99.   if (signal (SIGTERM, termination_handler) == SIG_IGN) signal (SIGTERM, SIG_IGN);
  100.  
  101.   fichiernom = fopen("/mnt/flash/noms/nom.save", "r" );
  102.   if (fichiernom != NULL)
  103. {
  104.  fgets(chaine, TAILLE_MAX, fichiernom);  // On lit maximum TAILLE_MAX caractères du fichiernom, on stocke le tout dans "chaine"
  105.  printf("%s", chaine);      // On affiche la chaîne
  106.   fclose(fichiernom);
  107. }
  108. fichiersave = fopen(("%s",chaine), "a" );
  109.   while (1)
  110. {
  111.  if (read(tty_fd,&rxChar,1)>0)
  112.  {
  113.   printf("%02X ",rxChar);
  114.   if (fichiersave != NULL)
  115.   {
  116.    // On écrit dans le fichier
  117.    fprintf(fichiersave, "%02X ",rxChar);
  118.    i++;
  119.   }
  120.   if (i==19)
  121.   {
  122.    printf("\n" );
  123.    i=0;
  124.   }
  125.  }
  126. }
  127.  fclose(fichiersave);
  128.  return EXIT_SUCCESS;
  129. }

mood
Publicité
Posté le 08-05-2009 à 23:26:54  profilanswer
 

n°1882265
Taz
bisounours-codeur
Posté le 08-05-2009 à 23:31:00  profilanswer
 

regarde bien que ton write réussisse

n°1882266
Taz
bisounours-codeur
Posté le 08-05-2009 à 23:32:12  profilanswer
 

et read peut renvoyer -1 sans que ça soit EOF. Regarde errno

n°1882272
anounito
Posté le 08-05-2009 à 23:45:53  profilanswer
 

Juste une petite précision, c'est que je suis un débutant :(  et donc ça peu arriver que je ne comprend pas trop ce que vous me dite.
Si j'ai bien compris, mon write réussi bien puisque j'ai qd mm quelque chose en sortie.

 
Citation :

et read peut renvoyer -1 sans que ça soit EOF. Regarde errno

 
errno n'est renvoyé que qd l'ouverture na pas réussi !!?!

Code :
  1. if (tty_open(argv[1])<0)
  2. {
  3.     fprintf (stderr,"tty open error %s\n", strerror(errno));
  4.     exit(EXIT_FAILURE)
  5. };


ou bien le faite que read peut renvoyer -1, ça générera un errno qd mm ???
Merci


Message édité par anounito le 08-05-2009 à 23:46:15
n°1882357
Taz
bisounours-codeur
Posté le 09-05-2009 à 12:34:01  profilanswer
 

man 2 read
man 2 write

 

dans tous les cas, il faut bien que tu contrôles le retour de ces fonctions et errno pour t'assurer que tu as reçu/envoyé le bon nombre de char, sinon savoir pourquoi (EINTR par exemple).

 

1) regarder le code de retour
2) si < 0, l'interpréter en fonction de la valeur d'errno.


Message édité par Taz le 09-05-2009 à 12:35:25
n°1884955
anounito
Posté le 15-05-2009 à 14:01:10  profilanswer
 

Salut,
Dit moi, comment faire pour tester le retour sur read et write
 
Désolé, je suis un débutant donc veille à m'excuser pour ces questions qui peuvent sembler pas à la hauteur !
Merci


Message édité par anounito le 15-05-2009 à 14:02:41
n°1884987
Taz
bisounours-codeur
Posté le 15-05-2009 à 14:59:31  profilanswer
 

ssize_t ret = read(...);
 
if (ret < 0) { analyzer errno et prendre une décision }
if (ret == 0) { EOF }
if (ret > 0) { comparer ret avec la quantité de données que tu avais demandé; }
 
idem pour write

n°1885066
anounito
Posté le 15-05-2009 à 19:04:53  profilanswer
 

Ok Merci, je vais tester ça.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Probléme de récupération des données à travers ttyS (LINUX)

 

Sujets relatifs
Problème de bannière flash sous IEProblème fusion cellule tableau html
[résolu] problème de débutantEviter un reload des données POST
Problème d'allocation mémoire sur gros vecteurPassage de données de flash à php via un LoadVars : erreur en local
[Menu déroulant / Javascript/ C# ][VBA] : problème d'affichage (Image.Visible = False ou true)
[ActionScript 3 ] Probleme affichage d'un rectangle (débutant)Problème conception objet pour modeleur UML en GWT
Plus de sujets relatifs à : [C] Probléme de récupération des données à travers ttyS (LINUX)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR