Voici à quoi ressemble ma fonction pour ouvrir le port série (en utilisant Ubuntu 12.04):
int open_port(void)
{
int fd; /* File descriptor for the port */
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
// Could not open the port.
perror("open_port: Unable to open /dev/ttyUSB0 - ");
}
else
fcntl(fd, F_SETFL, 0);
struct termios options;
tcgetattr(fd, &options);
//setting baud rates and stuff
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);
options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(fd, TCSANOW, &options);
tcsetattr(fd, TCSAFLUSH, &options);
options.c_cflag &= ~PARENB;//next 4 lines setting 8N1
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//options.c_cflag &= ~CNEW_RTSCTS;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //raw input
options.c_iflag &= ~(IXON | IXOFF | IXANY); //disable software flow control
return (fd);
}
Le problème est que lorsque j'exécute ce programme et si mon périphérique série est déjà branché, le tampon contient du contenu. J'ai besoin d'un moyen d'effacer le tampon avant de commencer à lire. Je pensais que l'utilisation de tcsetattr(fd, TCSAFLUSH, &options);
résoudrait ce problème, en vidant les tampons IO avant d'initialiser le port, mais pas de chance. Une idée?
Je pense que je l'ai compris. Pour une raison quelconque, je dois ajouter un délai avant de rincer. Ces deux lignes ajoutées avant de renvoyer fd
semblent pour avoir fait l'affaire:
sleep(2); //required to make flush work, for some reason
tcflush(fd,TCIOFLUSH);
La cause de ce problème réside dans l'utilisation d'un port série USB. Si vous utilisez un port série standard, vous n'aurez pas ce problème.
La plupart des pilotes de port série USB ne prennent pas correctement en charge le rinçage, probablement parce qu'il n'y a aucun moyen de savoir s'il y a encore des données dans le registre à décalage interne, FIFO ou dans le sous-système USB.
Voir aussi la réponse de Greg à un problème similaire signalé précédemment ici .
Votre sleep
peut résoudre le problème, mais ce n'est qu'une solution de rechange. Malheureusement, il n'y a pas d'autre solution que d'utiliser un port série standard.
J'ai rencontré des symptômes similaires avec une carte Arduino Uno qui se réinitialise sur open (). Je recevais des données après l'appel open () qui a été généré avant la réinitialisation de la carte Arduino et donc avant l'appel open ().
En recherchant le problème avec les appels ioctl (), j'ai appris que les données n'étaient tout simplement pas encore arrivées dans le tampon d'entrée au moment de l'appel de tcflush (). Donc, le tcflush () a fonctionné mais il n'y avait aucune donnée à vider. Un sommeil de 1000 nous après l'appel open () semblait résoudre le problème. C'est parce que le délai a permis aux données d'arriver avant que tcflush () soit appelé et donc tcflush () a effectivement vidé le tampon d'entrée.
Vous rencontrez peut-être le même problème.