C write() ne pas envoyer de données jusqu'à la fermeture(fd) est appelée
J'ai donc ce code de test pour envoyer un "BONJOUR" sur un port série USB:
int fd;
struct termios tty;
if((fd = open("/dev/ttyUSB0", O_WRONLY|O_NONBLOCK|O_NOCTTY)) == -1){
err(1, "Cannot open write on /dev/ttyUSB0");
}
tcgetattr(fd, &tty);
tty.c_iflag = 0;
tty.c_oflag = 0;
tty.c_lflag = 0;
tty.c_cflag = 0;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 0;
cfsetospeed(&tty, B19200);
cfsetispeed(&tty, B19200);
tty.c_cflag |= CREAD|CRTSCTS|HUPCL|CS8;
tcsetattr(fd, TCSANOW, &tty);
printf("Write: %i\n", write(fd, "HELLO", 5));
sleep(5);
if(close(fd) != 0){
warn("Could not close write fd");
}
Le programme s'exécute beaux et "BONJOUR" est envoyé, mais il y a un problème. "BONJOUR" ne semble pas être envoyé lorsque la fonction write() la fonction est appelée, mais plutôt quand le descripteur de fichier est fermé. J'ai ajouté le sommeil(5) de la ligne ci-dessus pour tester cette théorie, et bien sûr, "BONJOUR", est envoyé ~5 secondes après que le programme est exécuté. Comment puis-je obtenir "BONJOUR" à être envoyé immédiatement après la write() de la commande au lieu de la fermer()?
Avez-vous vérifié le
tcsetattr retourne 0
Vous dites "BONJOUR" n' semble à envoyer lors de l'écriture() la fonction est appelée. Comment êtes-vous établir ce exactement? Êtes-vous sûr qu'il n'est pas envoyé immédiatement et que l'appareil n'est tout simplement pas de traitement?
Je suis en train de lire le port série de l'autre côté et je ne vois pas le "BONJOUR" à venir à travers jusqu'à ce que le programme ci-dessus se ferme.
avez-vous trouvé une solution à cela?
tcsetattr
valeur de retour?tcsetattr retourne 0
Vous dites "BONJOUR" n' semble à envoyer lors de l'écriture() la fonction est appelée. Comment êtes-vous établir ce exactement? Êtes-vous sûr qu'il n'est pas envoyé immédiatement et que l'appareil n'est tout simplement pas de traitement?
Je suis en train de lire le port série de l'autre côté et je ne vois pas le "BONJOUR" à venir à travers jusqu'à ce que le programme ci-dessus se ferme.
avez-vous trouvé une solution à cela?
OriginalL'auteur Ryan | 2010-07-12
Vous devez vous connecter pour publier un commentaire.
À partir de la page de man de
write()
:Vous devez appeler
fsync()
sur votre descripteur de fichier à assurer que les données sont effectivement commis.Ce n'
errno
dire?Aucun lien de parenté. Le problème est que le terminal est en ligne-mode mémoire tampon.
Oh, c'est probablement
EROFS
ouEINVAL
...errno EINVAL
OriginalL'auteur Louis Marascio
L'appareil est un appareil tty, donc fsync ne va pas aider, peut-être pas fflush soit.
Par défaut, le périphérique fonctionne en mode canonique qui signifie que les données sont emballés dans des unités de lignes. Vous trouverez probablement que l'ajout d'un cr/lf paire de vos données va l'amener à être envoyé.
Vous devez vous assurer que le mode canonique est éteint. En outre, la R de la réponse sera de l'utiliser.
http://en.wikibooks.org/wiki/Serial_Programming/termios
OriginalL'auteur JeremyP
tout d'abord, aucune idée de pourquoi vous réglez d'abord toutes les termios champs à 0, puis, plus tard, sans aucune modification à 0 précèdent, décide de fixer l'habitude rs232 drapeaux sur la cflag. (plutôt que de le faire sans OU directement, d'où vous est maintenant réglée à 0, ci-dessus).
ce que vous aimeriez -au lieu - de l'établissement de tous ces drapeaux est juste cfmakeraw() la structure des champs.
aussi, sync(); en l'absence de paramètres (PAS fsync! 😉 semble envoyer tous en attendant la sortie de TOUS les filedescriptors, et pas seulement les périphériques de bloc. aussi les sockets tcp et rs232..
et aussi open() dispose d'une option O_SYNC (O_SYNC et O_ASYNC ont la confusion des noms, mais n'ont rien à voir avec la ligne série protocole cadencé ou pas, l'un immédiatement s'engage write()'s et de l'autre génère un signal pour le piégeage lors de l'entrée devient disponible (un peu comme irq en fonction rs232 sur le dos 😉
réglage O_SYNC dans le open() peut déjà résoudre votre problème.
aussi "par la lecture de données sur l'autre fin" ... il y a de ces choses que l'on appelle les "voyants" et "résistances" que vous pouvez simplement vous connecter à TXD et VOIR les données 😉 il y a des choses que l'on appelle 'rs232 breakout box" ou un champ d'application qui peuvent rendre directement visible 😉 beaucoup plus facile de cette façon de 'deviner' de quel côté est de ne pas se comporter correctement.
AVERTISSEMENT: N'A PAS DE CODE DE TEST. il compile. mais j'ai tous mes ttyUSB0 câbles dans un autre bâtiment. mais je pense que votre problème principal est O_SYNC de toute façon. le réglage de tous les termios merde à 0 est à peu près le même que cfmakeraw()... aussi pourquoi mettre CREAD si tu vas l'ouvrir en écriture seule? (pourquoi l'ouvrir en écriture seule plutôt que de readwrite de toute façon? - et aussi à écrire que vous n'aurez pas à avoir peur de devenir un contrôle ats (O_NOCTTY 😉 donc dans le cas de l'écriture seule, c'est vraiment pas nécessaire...
viens de remarquer %i (même pour %d btw) formateur déclenche également une incompatibilité de type avertissement de la ssize_t valeur de retour de la fonction write() donc joué qu'à (int)
OriginalL'auteur HRH Sven Olaf von CyberBunker
Les ports de sortie sont souvent mise en mémoire tampon, de sorte qu'il n'y a plus ou moins d'écart entre vous de l'écriture dans un flux de sortie, et le contenu fait d'être envoyés sur le disque, en ligne, ou quoi que ce soit. C'est en général pour plus d'efficacité.
Voir fflush(3) à la force de la mémoire tampon pour être engagé à la sortie.
Vous pourriez également être en mesure d'ouvrir la sortie du descripteur d'une manière qui le rend non mis en mémoire tampon, mais en utilisant
fflush
- à-dire "ça y est, je suis foutu", est probablement mieux.FILE*
, et comme d'autres l'ont souligné, fsync(2) est probablement ce que vous voulez si vous avez besoin d'utiliser des FDs.En fait, regardez fcntl(2) sur votre plate-forme. Sur certaines plates-formes, qui vous permettra de désactiver la mise en mémoire tampon de sortie, mais ce n'est pas portable. Si vous souhaitez renoncer à la portabilité de la complètement, puis les ioctls pour votre appareil sera probablement aider avec cela, mais qui devient désespérée.
fd -> fonction -> fh; fh -> fileno -> fd... le problème est de ne pas avoir de FICHIER "*" ou fd (si la conformité est de POSIX, et non pas strictement C89/C99)
OriginalL'auteur Norman Gray
Modifier cette ligne:
:
OriginalL'auteur R..
la mémoire tampon n'est pas vidé. fflush.
fdopen
peut être utilisé; si cela résout le OP problème et il n'a aucune raison de ne pas utiliser de gestionnaire de fichier au lieu de descripteur de fichier.OriginalL'auteur BobTurbo
Veuillez voir cette question. Fondamentalement, vous avez besoin de vider le fichier dans l'ordre de IO à prendre place quand vous le souhaitez.
OriginalL'auteur Alexandre C.
Essayer de faire un
après la
write()
. Peut-être il ya une certaine mémoire tampon interne qui n'est pas rincé.OriginalL'auteur Frerich Raabe