Bonjour à tous, je suis nouveau sur le forum et satisfait de rejoindre cette grosse communauté de développeurs.
Je travaille en ce moment sur une carte linux embarqué qui tourne sous Debian, la FOX board G20 : http://www.acmesystems.it/FOXG20, peut-être que certains d'entre vous connaissent...
Voici mon soucis, j'essaye de faire tourner un programme en C qui, entre-autres, communique via les liaisons série avec d'autres microcontrôlleur.
A un moment donné je code une fonction qui prend en paramètre le port série concerné (j'ai besoin de /dev/ttyS1 jusqu'à ttyS4) et la trame à envoyer. Je teste si l'ouverture du port se passe correctement...
Il s'avère à l'exécution que la fonction s'exécute, passe dedans et ressort correctement pendant un temps (j'ai envie de dire aléatoire mais je n'en sais rien) et que d'un coup, le port série reste bloqué, j'ai bien tenté de le fermer mais même la fermeture du port se passe mal...
J'ai testé la valeur du renvoie du file descriptor et de la fonction close(fd); avec gdb, elles sont toutes deux égales à -1 avant et après les tests.
Voici la partie de mon code que je soupçonne mal faite (je mets pas tout, ya aps mal de lignes) Je vais en commentaires les breakpoints posés sur gdb.
Code cpp : 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 // fonction générique utilisé pour écrire une trame sur un des ports COM depuis une valeur lue dans un des registres de la shm void sendFrame(int serialNum, char *frameToSend){ int fd; char serialDir[11] = "/dev/ttyS"; sprintf(serialDir,"%s%1d", serialDir, serialNum); if((fd = open(serialDir,O_RDWR|O_NOCTTY|O_NONBLOCK))<0){ //TODO résoudre problème ouverture // gdb indique fd = -1 int errorRes; if((errorRes = close(fd))!=0){ printf("Erreur de fermeture du port série"); } // gdb indique fd = -1 et close(fd) = -1 FILE *logFileErr; printf("[Ecriture]Erreur d'ouverture port série %s.\n", serialDir); fflush(stdout); logFileErr = fopen(logFile, "a"); if(logFileErr == NULL){ printf ("Erreur d'ouverture du fichier de log.\n"); }else{ char *errMsg = NULL; sprintf(errMsg, "[Err][Date][Eng:can't open %s][Fr:impossible d'ouvrir %s]\n", serialDir, serialDir); fputs(errMsg, logFileErr); fclose(logFileErr); } }else{ //----Initialisation des ports séries---- // voir détail de l'initialisation dans readSerialThread() tcgetattr(fd, &tty_attributes); tty_attributes.c_cflag |= CREAD; tty_attributes.c_cflag |= CS8; tty_attributes.c_iflag |= IGNPAR; tty_attributes.c_lflag &= ~(ICANON); tty_attributes.c_lflag &= ~(ECHO); tty_attributes.c_lflag &= ~(ECHOE); tty_attributes.c_lflag &= ~(ISIG); tty_attributes.c_cc[VMIN]=1; tty_attributes.c_cc[VTIME]=0; cfsetospeed(&tty_attributes,B57600); cfsetispeed(&tty_attributes,B57600); tcsetattr(fd, TCSANOW, &tty_attributes); if(write(fd, frameToSend, strlen(frameToSend))!=strlen(frameToSend)){ MSGDEBUG("erreur d'envoi\n"); }else{ MSGDEBUG("trame envoyée\n"); } } }
Et une fois l'erreur apparue, le port série devient définitivement inaccessible et il faut relancer le programme pour qu'il devienne accessible de nouveau. Je soupçonne l'application de garder le contrôle du port (/var/lock) et de ne pas le libérer convenablement.
Comment faire pour libérer le port série correctement quand il y a une erreur d'ouverture???
Merci d'avance
Partager