Marc Silanus

En C

Les ports séries asynchrones

Pour mener à bien les tests de lecture et d'écriture sur les ports séries asynchrones de la FOX Board G20, nous allons relier entre eux 2 des ports. Connectez les lignes RX du port COM4 (tty5) et TX du port  et COM3 (tty4) entre elles et inversement.

Test de lecture et écriture sur port série

Connexion de tty4 sur tty5 pour tester la communication série

Sous Linux, chaque port série est représenté par un fichier de périphérique situé dans le dossier /dev.

Dans un programme en C, on ouvre ces fichiers comme n'importe quel autre fichier grâce à la fonction open() :

int fd;
if ((fd = open("/dev/ttyS1",O_RDWR))<0)
{
         fprintf (stderr,"Erreur d’ouverture %s\n", strerror(errno));
         exit(-1);
}

Une fois que le port est ouvert, on peut y lire et y écrire des caractères au moyen des fonctions read() et write().

Mais au paravent, il faut configurer les paramètres de la liaison. Ils répondent à la norme POSIX et sont regroupés dans une structure nommée termios définie dans le fichier termios.h qu'il faut  inclure. Ce fichier est situé dans /usr/include et /usr/include/bits.

Cette structure comporte les champs suivants

struct termios {
        tcflag_t c_iflag;      /* modes d'entrée */
        tcflag_t c_oflag;      /* modes de sortie */
        tcflag_t c_cflag;      /* modes de contrôle */
        tcflag_t c_lflag;      /* modes locaux */
        cc_t c_cc[NCCS];       /* caractères de controle */
};

Consultez la documentation de termios pour plus d’informations (en français, sous licence GPL, traduite par Christophe Blaess (ccb@club-internet.fr) :

http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man3/termios.3.html

Ecrire des données :

#include   <stdio.h>
#include   <string.h>
#include   <unistd.h>
#include   <fcntl.h>
#include   <errno.h>
#include   <sys/types.h>
#include   <sys/stat.h>
#include   <stdlib.h>
#include   <stdarg.h>
#include   <termios.h>
int main(void)
{
int    fd;
struct termios      termios_p;
/* Ouverture de la liaison serie */
if (   (fd=open("/dev/ttyS4",O_WRONLY))<0)
{
fprintf   (stderr,"Erreur d’ouverture %s\n", strerror(errno));
exit(-1);
}
/*   Lecture des parametres courants */
tcgetattr(fd,&termios_p);
/*   On ignore les BREAK et les erreur de parité*/
termios_p.c_iflag   = IGNBRK | IGNPAR;
/*   Pas de mode de sortie particulier */
termios_p.c_oflag   = 0;
/*   Liaison a 9600 bps avec 8 bits de donnees */
termios_p.c_cflag   = B9600 | CS8;
/*   Mode non-canonique sans echo */
termios_p.c_lflag   &= ~(ECHO);
termios_p.c_lflag   &= ~(ICANON);
/*   Caracteres immediatement disponibles */
termios_p.c_cc[VMIN]   = 1;
termios_p.c_cc[VTIME]   = 0;
/*   Sauvegarde des nouveaux parametres */
tcsetattr(fd,TCSANOW,&termios_p);
int i=0;
while(i<10)
{
char   a_transmettre[100];
sprintf(a_transmettre,"%d   - test de transmission",i);
write(fd,a_transmettre,strlen(a_transmettre));
i++;
sleep(1);
printf(a_transmettre);
printf("\nnombre   de caractères transmis : %d\n\n",strlen(a_transmettre));
}
write(fd,"fin.",4);
/* Fermeture */
close(fd);
/* Bye... */
exit(0);
}

Lire des données :

#include   <stdio.h>
#include   <string.h>
#include   <unistd.h>
#include   <fcntl.h>
#include   <errno.h>
#include   <sys/types.h>
#include   <sys/stat.h>
#include   <stdlib.h>
#include   <stdarg.h>
#include   <termios.h>
int main(void)
{
int    fd;
struct   termios      termios_p;
/*   Ouverture de la liaison serie */
if (   (fd=open("/dev/ttyS5",O_RDONLY))<0)
{
fprintf   (stderr,"Erreur d’ouverture %s\n", strerror(errno));
exit(-1);
}
/*   Lecture des parametres courants */
tcgetattr(fd,&termios_p);
/*   On ignore les BREAK */
termios_p.c_iflag   = IGNBRK | IGNPAR;
/*   Pas de mode de sortie particulier */
termios_p.c_oflag   = 0;
/*   Liaison a 9600 bps avec 8 bits de donnees et une parite paire */
termios_p.c_cflag   = CREAD | B9600 | CS8; //CREAD
/* Mode non-canonique sans echo */
termios_p.c_lflag   &= ~(ECHO);
termios_p.c_lflag   &= ~(ICANON);
/*   Caracteres immediatement disponibles */
termios_p.c_cc[VMIN]   = 1;
termios_p.c_cc[VTIME]   = 0;
/*   purge donnees non lues ou non envoyees */
tcflush(fd,   TCIFLUSH);
/*   Sauvegarde des nouveaux parametres */
tcsetattr(fd,TCSANOW,&termios_p);
int   fin=0;
while(!fin)
{
//lecture   de 100 caractères max
char   c[100]="";
read(fd,&c,100);
if(c[strlen(c)-1]=='.') fin=1;
printf("%s",c);
printf("\nnombre   de caractères reçus : %d\n\n",strlen(c));
/*   La transmission se termine par un . */
}
/* Fermeture */
close(fd);
/* Bye... */
exit(0);
}

Pour testez l’envoi et la réception de caractères, ouvrez deux terminaux simultanément :

Premier terminal :
debarm:~# gcc ecriretty4.c -o ecrirettyS4

debarm:~# ./ecriretty4
0 - test de transmission
nombre   de caractères transmis : 24
1 - test de transmission
nombre   de caractères transmis : 24
2- test de transmission
nombre   de caractères transmis : 24
3 - test de transmission
nombre   de caractères transmis : 24
4 - test de transmission
nombre   de caractères transmis : 24
5 - test de transmission
nombre   de caractères transmis : 24
6 - test de transmission
nombre   de caractères transmis : 24
7 - test de transmission
nombre   de caractères transmis : 24
8 - test de transmission
nombre   de caractères transmis : 24
9 - test de transmission
nombre   de caractères transmis : 24
fin.
debarm:~#
Deuxième terminal :
debarm:~# gcc lirettyS5.c -o lirettyS5
debarm:~# ./lirettyS5
2- test de transmission
nombre de caractères reçu: 24
3 - test de transmission
nombre de caractères reçu : 24
4 - test de transmission
nombre de caractères reçu : 24
5 - test de transmission
nombre de caractères reçu : 24
6 - test de transmission
nombre de caractères reçu : 24
7 - test de transmission
nombre de caractères reçu : 24
8 - test de transmission
nombre de caractères reçu : 24
9 - test de transmission
nombre de caractères reçu : 24
fin.
nombre de caractères reçu : 4
debarm:~#