[LINUX] Probléme de récup de donnée sur ttyS
anbakkali
Messages postés
4
Statut
Membre
-
anbakkali Messages postés 4 Statut Membre -
anbakkali Messages postés 4 Statut Membre -
Bonjour,
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)
Exemple de Données incorrecte:
-----------------------------
CODE C pour l'ouverture de la communication serie sur la carte LINUX:
MERCI
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:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#define TAILLE_MAX 1000 // Tableau de taille 1000 pour la lecture du nom de fichier
/****************************************************/
/* CONFIGURATION POUR ÉTABLIR LA CONNEXION SÉRIE */
/****************************************************/
struct termios stdin_saved_attributes;
struct termios tty_saved_attributes;
int tty_fd;
int tty_open(char* tty_dev) {
struct termios new_attributes;
tty_fd = open(tty_dev,O_RDWR| O_NOCTTY | O_NONBLOCK);
if (tty_fd<0) {
return -1;
} else {
tcgetattr(tty_fd,&tty_saved_attributes);
tcgetattr(tty_fd,&new_attributes);
new_attributes.c_cflag |= CREAD; // Enable receiver
new_attributes.c_cflag |= B9600; // Set baud rate
new_attributes.c_cflag |= CS8; // 8 data bit
new_attributes.c_iflag |= IGNPAR; // Ignore framing errors and parity errors.
new_attributes.c_lflag &= ~(ICANON); // DISABLE canonical mode.
// Disables the special characters EOF, EOL, EOL2,
// ERASE, KILL, LNEXT, REPRINT, STATUS, and WERASE, and buffers by lines.
new_attributes.c_lflag &= ~(ECHO); // DISABLE this: Echo input characters.
new_attributes.c_lflag &= ~(ECHOE); // DISABLE this: If ICANON is also set, the ERASE character erases the preceding input
// character, and WERASE erases the preceding word.
new_attributes.c_lflag &= ~(ISIG); // DISABLE this: When any of the characters INTR, QUIT, SUSP,
// or DSUSP are received, generate the corresponding signal.
new_attributes.c_cc[VMIN]=1; // Minimum number of characters for non-canonical read.
new_attributes.c_cc[VTIME]=0; // Timeout in deciseconds for non-canonical read.
tcsetattr(tty_fd, TCSANOW, &new_attributes);
}
return tty_fd;
}
// Serial version of printf
void tty_printf(char *format, ...) {
va_list argptr;
char buffer[200];
va_start(argptr,format);
vsprintf(buffer,format,argptr);
va_end(argptr);
write(tty_fd,buffer,strlen(buffer));
}
void termination_handler (int signum) {
tcsetattr(STDIN_FILENO,TCSANOW,&stdin_saved_attributes);
if (tty_fd>0) tcsetattr (tty_fd,TCSANOW,&tty_saved_attributes);
close(tty_fd);
printf("Exit\n");
exit(0);
}
int stdin_init(void) {
struct termios tattr;
// Make sure stdin is a terminal
if (!isatty (STDIN_FILENO)) {
fprintf (stderr,"stdin is not a terminal\n");
return -1;
}
// Save the terminal attributes so we can restore them later.
tcgetattr (STDIN_FILENO, &stdin_saved_attributes);
// Set the funny terminal modes.
tcgetattr (STDIN_FILENO, &tattr);
tattr.c_lflag &= ~(ICANON | ECHO); /* Clear ICANON and ECHO. */
tattr.c_cc[VMIN] = 0;
tattr.c_cc[VTIME] = 0;
tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
return 0;
}
/*********************************************************/
/* ROUTINE POUR RÉCUPÉRER LES DONNÉES ET LES AFFICHER */
/*********************************************************/
int main(int argc, char *argv[]) {
int rxChar;
char i;
i=0;
FILE* fichiersave = NULL;
FILE* fichiernom = NULL;
char chaine[TAILLE_MAX] = ""; // Chaîne vide de taille TAILLE_MAX
printf("Acme Serial Test (press ctrl-c to exit)\n");
if (tty_open(argv[1])<0) {
fprintf (stderr,"tty open error %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (stdin_init()<0) {
printf("stdin init error %s\n", strerror(errno));
// exit(EXIT_FAILURE);
}
if (signal (SIGINT, termination_handler) == SIG_IGN) signal (SIGINT, SIG_IGN);
if (signal (SIGHUP, termination_handler) == SIG_IGN) signal (SIGHUP, SIG_IGN);
if (signal (SIGTERM, termination_handler) == SIG_IGN) signal (SIGTERM, SIG_IGN);
fichiernom = fopen("/mnt/flash/noms/nom.save", "r");
if (fichiernom != NULL)
{
fgets(chaine, TAILLE_MAX, fichiernom); // On lit maximum TAILLE_MAX caractères du fichiernom, on stocke le tout dans "chaine"
printf("%s", chaine); // On affiche la chaîne
fclose(fichiernom);
}
fichiersave = fopen(("%s",chaine), "a");
while (1)
{
if (read(tty_fd,&rxChar,1)>0)
{
printf("%02X ",rxChar);
if (fichiersave != NULL)
{
// On écrit dans le fichier
fprintf(fichiersave, "%02X ",rxChar);
i++;
}
if (i==19)
{
printf("\n");
i=0;
}
}
}
fclose(fichiersave);
return EXIT_SUCCESS;
}
MERCI
A voir également:
- [LINUX] Probléme de récup de donnée sur ttyS
- Linux reader - Télécharger - Stockage
- Effacer les données de navigation sur android - Guide
- R-linux - Télécharger - Sauvegarde
- Backtrack linux - Télécharger - Sécurité
- Toutou linux - Télécharger - Systèmes d'exploitation
Je ne sait pas c'est le faite de diminuer le baud-rate, influencerai mes exigences (100 mesures /s).
En tt cas, je vais tester la solution !
Mais sinon, j'ai lu un peu sur les forums et j'ai vu qu'il y a certaine personne qu'on le même genre de problème que moi, https://openclassrooms.com/forum/sujet/comment-eviter-des-problemes-avec-scanf-94623
Le problème peut venir du buffer de stdin, mais seulement, mes données n'arrivent à partir de stdin, mais d'une connexion série, donc je ne sait pas le tty_fd de if (read(tty_fd,&rxChar,1)>0) peut être considérer comme un stdin.
while (1) { if (read(tty_fd,&rxChar,1)>0) { printf("%02X ",rxChar); if (fichiersave != NULL) { // On écrit dans le fichier fprintf(fichiersave, "%02X ",rxChar); i++; } if (i==19) { printf("\n"); i=0; } } }Merci à toi