Programmation du port série sous Linux, ttyS0
Je suis en train d'apprendre à programmer le ttyS0 port série sous Linux à l'aide de C. j'ai une autre machine connectée à mon port série de l'envoi de l'alternance de valeurs hexadécimales de 5f, 6f environ toutes les deux secondes. J'ai vérifié avec d'autres la surveillance de port apps que ces valeurs apparaissent dans le port. Dans mon code j'utilise un blocage read() en 10 char longueur de la mémoire tampon. Même si mon autre machine est encore l'envoi de données, read() blocs pour toujours. Si je comprend la ligne fcntl(fd, F_SETFL, FNDELAY); qui définit read() de non-blocage read() retourne toujours avec une valeur de -1, ce qui signifie pas de données dans la mémoire tampon UART, et mon pour la boucle de code se contente d'afficher des valeurs aléatoires qui sont dans la mémoire tampon. Donc en bref mon hypothèse, c'est que mon code n'est pas de la lecture ttyS0 et je n'ai aucune idée pourquoi. Ci-dessous mon code, j'espère que quelqu'un va voir quelle est la cause de mon problème et me droite. En passant, je suis en utilisant Scientific Linux, je crois ttyS0 est le port com 1, car il est dans RedHat et Fedora. Aslo ci-dessous est la sortie lorsque j'exécute le code. Il semble être écrit pour le port COM avec pas de problèmes, mais pour les lire il dit de son indisponibilité. Aussi, il est clair que la mémoire tampon, je suis d'impression est juste des valeurs aléatoires, pas de données qui a été lu. Grâce
sortie de la console
hello world
hi again
write error: : Success
wrote 4 bytes
number of bytes read is -1
read error:: Resource temporarily unavailable
4 8 120 -99 -73 -65 41 -120 4 8
should of put something out
Code
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
int main()
{
printf("hello world\n");
int n;
int fd;
char c;
int bytes;
char buffer[10];
char *bufptr;
int nbytes;
int tries;
int x;
struct termios options;
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if(fd == -1)
{
perror("open_port: Unable to open:");
}
else
{
fcntl(fd, F_SETFL, 0);
printf("hi again\n");
}
tcgetattr(fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~( ICANON | ECHO | ECHOE |ISIG );
options.c_iflag &= ~(IXON | IXOFF | IXANY );
options.c_oflag &= ~OPOST;
tcsetattr(fd, TCSANOW, &options);
write(fd, "ATZ\r",4);
printf(" wrote\n");
bufptr = buffer;
fcntl(fd, F_SETFL, FNDELAY);
bytes = read(fd, bufptr, sizeof(buffer));
printf("number of bytes read is %d\n", bytes);
perror ("read error:");
for (x = 0; x < 10 ; x++)
{
c = buffer[x];
printf("%d ",c);
}
close(fd);
//puts(buffer[0]);
printf("\nshould of put something out \n");
return (0);
}
read
retour -1
pourrait dire bien d'autres choses encore. Vous devez vérifier errno
pour voir ce que cela signifie vraiment.OK. J'ai ajouté perrer() des lignes après la ligne read() et write(). Ressemble à son écriture fine, mais impossible d'accéder au port de la lecture.
Dans le
options.c_cflag &= ~( ICANON | ECHO | ECHOE |ISIG );
ligne, vouliez-vous dire pour définir options.c_lflag
plutôt que options.c_cflag
?Les trois principaux problèmes avec votre code sont: (1) Votre programme utilise non-mode de blocage d'entrée. Vous serait beaucoup mieux d'utiliser un mode de blocage. (2) Votre programme utilise non-canonique. Depuis l'entrée et de sortie sont des lignes de texte, vous pouvez configurer le terminal pour le mode canonique. Voir stackoverflow.com/questions/25996171/... (3) La structure de configuration est bâclé, comme mentionné par @VilhelmGray
OriginalL'auteur Frank Dejay | 2012-04-20
Vous devez vous connecter pour publier un commentaire.
La ligne suivante va causer des problèmes:
Il va réinitialiser tous les autres bits de la c_cflag.
Si vous souhaitez utiliser 1 bit d'arrêt, puis utilisez:
Si vous souhaitez utiliser 2 bits d'arrêt, puis utilisez:
EDIT:
Également la ligne suivante causer des problèmes:
Il sera réinitialisé plusieurs drapeaux.
Dejay Il y a aussi une étrange dans le paramètre d'indicateur. J'ai mis à jour ma réponse.
"Également la ligne suivante causer des problèmes:
fcntl(fd, F_SETFL, 0);
Il sera réinitialisé plusieurs drapeaux." -- en Fait, qui ne sera pas causer des problèmes; le syscall ne peut modifier une documenté & ensemble restreint de fichier descripteur d'options. Dans ce cas, il ne claire de la O_NDELAY drapeau (mais c'est plus tard, re-activé et provoque des problèmes pour l'OP).OriginalL'auteur SKi