2010-11-06 3 views
0

J'ai un programme de travail pour lire les données provenant du terminal. Le problème est que lorsque, par exemple, une donnée arrive et s'arrête, mon programme continue de lire depuis le tampon. Comment puis-je l'empêcher de lire des choses qui sont déjà passées par le port?Comment puis-je empêcher mon programme de lire le tampon du port série?

Voici mon code, qui peut aussi être found at pastebin

#include <ncurses.h> 
#include <stdio.h> 
#include <string.h> 
#include <time.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <termios.h> 
#include <signal.h> 
#include <unistd.h> 
#include <iostream> 
#include <signal.h> 


int open_port(void); 

int main() 
{ 
    char dato[1]; 
    int fd = 0; 
    fd = open_port(); 
    while(1) 
    { 
     read(fd,dato,1); 
     //~ if(dato == "B") 
     //~ return 0; 
     printf(dato); 
    } 
} 

int open_port(void) 
{ 
    int fd; /* File descriptor for the port */ 

    //~ fd = open("/home/tomas/ttySV1", O_RDWR | O_NOCTTY | O_NDELAY); 
    fd = open("/dev/ttyUSB0", O_RDWR | O_NDELAY); 
    //~ fd = open("/dev/ttyUSB0", O_RDWR); 

    if (fd == -1) 
    { 
     perror("open_port: No se pudo abrir el puerto: "); 
    } 
    else 
    { 
     struct termios options; 

     /* 
     * Get the current options for the port... 
     */ 

     tcgetattr(fd, &options); 

     /* 
     * Set the baud rates to B9600... 
     */ 

     cfsetispeed(&options, B9600); 
     cfsetispeed(&options, B9600); 

     /* 
     * Enable the receiver and set local mode... 
     */ 

     options.c_cflag |= (CLOCAL | CREAD); 

     /* 
     * Set the new options for the port... 
     */ 

     tcsetattr(fd, TCSANOW, &options); 

     options.c_cflag &= ~CSIZE; /* Mask the character size bits */ 
     options.c_cflag |= CS8; /* Select 8 data bits */ 

     options.c_cflag &= ~PARENB; 
     options.c_cflag &= ~CSTOPB; 
     options.c_cflag &= ~CSIZE; 
     options.c_cflag |= CS8; 

     //~ fcntl(fd, F_SETFL, 0); 
     return (fd); 
    } 
} 
+0

Comment savez-vous quand vous avez lu assez de données? (c'est-à-dire quelles sont vos conditions d'arrêt?) –

+0

Les conditions sont sans arrêt, je veux dire, je scanne toujours le port à la recherche de données à venir, mais je ne sais pas comment effacer le tampon pour arrêter de lire les données passées. – Tomas

+0

selon [cette référence] (http://www.opengroup.org/onlinepubs/009695399/functions/read.html), 'read' devrait se bloquer jusqu'à ce que le nouveau contenu soit disponible sur le canal ouvert. –

Répondre

2

O_NDELAY empêche la lecture de bloquer. Vous devriez toujours vérifier les codes de retour. Read renverra -1 et placera errno à EWOULDBLOCK.

jouer Donc, avec les codes de retour et errno pour savoir quoi faire - par exemple:

ssize_t retval=1; 
int doit=1; 
while(doit) 
{ 
while(retval==1) 
{ 
    retval=read(fd, &ch, 1); 
} 
if(retval == -1) 
{ 
    if (errno == EWOULDBLOCK) 
    { 
     sleep 1;  
    } 
    else 
    doit=0; 
} 
+1

Il serait plus judicieux d'utiliser le mode de blocage plutôt que de dormir pour un intervalle arbitraire, qui est soit trop long si les données arrivent, soit trop court si les données n'arrivent pas. – EJP

+0

Je ne lisais pas le retour de 'read()' tout va bien maintenant. Merci! – Tomas