2016-06-21 29 views
2

Ich möchte Daten von UART lesen, gefolgt i this tutorial, die Schreibfunktion funktioniert wie erwartet, aber iam immer Probleme mit der Lesefunktion:Linux Lesen von Daten von UART

Dies ist die uart_init Funktion:

void uart_init() 
{ 
printf("\n +----------------------------------+"); 
printf("\n |  Serial Port Write   |"); 
printf("\n +----------------------------------+"); 

/*------------------------------- Opening the Serial Port -------------------------------*/ 

    fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY| O_SYNC);  /* !!blocks the read */ 
                  /* O_RDWR Read/Write access to serial port   */ 
                  /* O_NOCTTY - No terminal will control the process */ 
                  /* O_NDELAY -Non Blocking Mode,Does not care about- */ 
                  /* -the status of DCD line,Open() returns immediatly */           

if(fd == -1)            /* Error Checking */ 
    printf("\n Error! in Opening ttyUSB0 "); 
else 
    printf("\n ttyUSB0 Opened Successfully "); 


/*---------- Setting the Attributes of the serial port using termios structure --------- */ 

struct termios SerialPortSettings;   /* Create the structure       */ 

tcgetattr(fd, &SerialPortSettings);   /* Get the current attributes of the Serial port */ 

cfsetispeed(&SerialPortSettings,B19200);  /* Set Read Speed as 19200      */ 
cfsetospeed(&SerialPortSettings,B19200);  /* Set Write Speed as 19200      */ 

SerialPortSettings.c_cflag &= ~PARENB;   /* Disables the Parity Enable bit(PARENB),So No Parity */ 
SerialPortSettings.c_cflag &= ~CSTOPB;   /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */ 
SerialPortSettings.c_cflag &= ~CSIZE;   /* Clears the mask for setting the data size    */ 
SerialPortSettings.c_cflag |= CS8;    /* Set the data bits = 8         */ 

SerialPortSettings.c_cflag &= ~CRTSCTS;   /* No Hardware flow Control       */ 
SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines  */ 


SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);   /* Disable XON/XOFF flow control both i/p and o/p */ 
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* Non Cannonical mode       */ 

SerialPortSettings.c_oflag &= ~OPOST;/*No Output Processing*/ 

/* Setting Time outs */ 
SerialPortSettings.c_cc[VMIN] = 10; /* Read at least 10 characters */ 
SerialPortSettings.c_cc[VTIME] = 0; /* Wait indefinetly */ 

if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) /* Set the attributes to the termios structure*/ 
printf("\n ERROR ! in Setting attributes"); 
else 
printf("\n BaudRate = 19200 \n StopBits = 1 \n Parity = none"); 

} 

erhalten die Funktion:

void uart_receive() 
{ 
char read_buffer[32]; /* Buffer to store the data received    */ 
int bytes_read = 0; /* Number of bytes read by the read() system call */ 
int i = 0; 

bytes_read = read(fd,&read_buffer,10); /* Read the data     */ 

printf("\n\n Bytes Rxed %d", bytes_read); /* Print the number of bytes read */ 
printf("\n\n "); 

for(i=0;i<bytes_read;i++) /*printing only the received characters*/ 
printf("%c",read_buffer[i]); 

printf("\n +----------------------------------+\n\n\n"); 
} 

die Hauptfunktion:

EDIT

ich das Programm ausführen und für Daten-Bytes warten in UART empfangen werden, ich sende Daten UART verwenden, aber die Lesefunktion gesperrt hält.

Ich benutze eine virtuelle Maschine mit Ubunutu 14.04, und ich bin mir nicht sicher, ob die Verwendung eines emulierten UART Probleme beim Empfang verursachen kann. kann blockiert werden, aus welchem ​​Grund

+0

Ich kann Ihnen eine gute Bibliothek vorschlagen, ist es Open Source, so dass Sie auch Inspiration aus dem Code für Ihre Zwecke nehmen: [Bibliothek Link] (http://www.teuniz.net/RS-232/) – Niles

+0

Was ist das ** spezifische ** Problem? – Olaf

+0

@Olaf das Programm ist in der Lesefunktion fest, ich sende Daten über UART, aber das Programm nicht die Lesefunktion – fedi

Antwort

2

Ihr Programm hängt in lesen() syscall, weil es auf ein Zeichen für die Beendigung der Leitung blockiert ist.
Sie haben versucht, den Port für nicht-kanonischen Modus mit der Aussage

SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* Non Cannonical mode 

aber, dass der Betrieb ist auf dem falschen termios Element zu konfigurieren.
Die ICANON-Bit Attribut ist ein Teil des lflag Element (und nicht die iflag). (Dieser Fehler stammt aus dem Tutorial, auf das Sie verwiesen haben!)
Daher führt Ihr Programm blockierende kanonische Lesevorgänge aus.

Es gibt eine bequeme termios Funktion für die Konfiguration von nicht-kanonischen Modus:

cfmakeraw() sets the terminal to something like the "raw" mode of the old 
    Version 7 terminal driver: input is available character by 
    character, echoing is disabled, and all special processing of 
    terminal input and output characters is disabled. The terminal 
    attributes are set as follows: 

     termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP 
         | INLCR | IGNCR | ICRNL | IXON); 
     termios_p->c_oflag &= ~OPOST; 
     termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 
     termios_p->c_cflag &= ~(CSIZE | PARENB); 
     termios_p->c_cflag |= CS8; 
+0

Sie haben völlig Recht, es scheint, dass dies die Ursache des Problems ist, werde ich mit dieser Konfiguration versuchen, und aktualisieren Sie den Status – fedi

+1

Problem gelöst, danke – fedi

2

Es gibt einen Fehler in der Lesefunktion

bytes_read = read(fd,&read_buffer,10); /* Read the data 

sollte

bytes_read = read(fd,read_buffer,10); /* Read the data 
+0

@lllishar, ich änderte es, aber das Problem besteht immer noch – fedi

+0

@fedi - sei speziell über das Problem. Welche Fehlermeldung oder welches Verhalten siehst du? – ryyker

+0

@ryyker, ich habe die Frage bearbeitet – fedi

0

Ihre read() Funktion. Here is a discussion beim Lesen von einer seriellen Schnittstelle, einschließlich Code für blockierte/nicht blockierte Einstellungen.

Es kann auch sein, dass keine Daten übertragen werden und nichts gelesen wird. Ohne Zugriff auf das Hardware-Setup ist es schwierig, ohne spezielle Informationen über das, was Sie sehen, weiter zu gehen.

Auch zusätzlich richtig read_buffer zu vorbei (eine andere Antwort), gibt es mindestens zwei weitere Dinge, die verbessern können:

1) überprüfen die Rückkehr von read, bevor es mit:

bytes_read = read(fd,&read_buffer,10); /* Read the data*/ 
if(bytes_read > 0) 
{ 
    ... 
} 

2) Wechsel:

for(i=0;i<bytes_read;i++) /*printing only the received characters*/ 
printf("%c",read_buffer[i]); 

An:

//after successful read: 
read_buffer[bytes_read]=0;//place null termination after last character read. 
printf("%s",read_buffer);//note format specifier 

Dies wird die Anzahl der gelesenen Zeichen ohne die Schleife drucken.