Comment puis-je mettre en œuvre timeout pour read () lors de la lecture d'un port série (C / C ++)
Je suis la lecture d'octets à partir d'un port série en C++ à l'aide d'un descripteur de fichier et la posix/unix read() fonction. Dans cet exemple, je suis de lecture de 1 octet à partir du port série (vitesse de transmission des paramètres et des approches similaires sont omis pour plus de clarté):
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
char buf[1];
int bytesRead = read(fd, buf, 1);
close(fd);
return 0;
}
Si le périphérique est connecté à /dev/ttyS0 ne pas envoyer de l'information, le programme se bloque. Comment puis-je définir un délai d'attente?
J'ai essayé de fixer une heure comme ceci:
struct termios options;
tcgetattr(fd, &options);
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
tcsetattr(fd, TCSANOW, &options);
J'ai pensé qu'il était censé donner 1 seconde de délai d'expiration, mais il ne fait aucune différence. Je pense que j'ai mal compris VMIN et VTIME. Qu'est-ce que VMIN et VTIME?
Puis j'ai cherché sur le web et trouvé quelqu'un parler de la fonction select (). Est-ce la solution et si oui, comment pourrait-on l'appliquer pour le programme ci-dessus pour faire 1 seconde de délai d'attente?
Toute aide est appréciée. Merci d'avance 🙂
source d'informationauteur pvh1987
Vous devez vous connecter pour publier un commentaire.
Oui, l'utilisation
select(2)
. Passer dans un descripteur de fichier qui contient juste votre fd de la lecture de jeu et vide d'écriture/exception des ensembles, et de transmettre dans un délai d'expiration. Par exemple:Vous pouvez tenter de capturer le signal pour arrêter l'opération de lecture. utilisation de l'alarme(1) avant de le lire, et si la fonction de lecture n'a pas retourné, l'alarme enverra le signal SIGALRM, alors vous pouvez créer de traitement de signal en fonction de capter ce signal, comme ceci:
Mais l'utilisation de sélectionner ou de sondage ou epoll sera mieux si votre programme est grand.
Qu'est-ce que VMIN et VTIME?
Source : http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html
select() est la façon dont je voudrais résoudre ce problème.
Il y a plusieurs pages sur internet qui va donner d'informations sur la façon d'utiliser select(), comme http://www.unixguide.net/unix/programming/2.1.1.shtml
Il y a plusieurs approches possibles. Si le programme sera finalement calendrier plus d'une opération d'e/s,
select()
est le choix évident.Toutefois, si la seule entrée est à partir de ce i/o, puis en sélectionnant non-blocage i/o et le calendrier est une méthode simple. J'ai élargi à partir de caractère unique i/o pour le multi-personnage afin de le rendre plus généralement complète exemple: