2009-11-18 20 views
6

mam następujący program: COdczyt z portu szeregowego nie

#include <fcntl.h> 
#include <termios.h> 
#include <stdio.h> 

int main() 
{ 
    int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK); 
    if(fd < 0) 
    { 
     perror("Could not open device"); 
    } 
    printf("Device opened\n"); 

    struct termios options; 
    tcgetattr(fd, &options); 
    cfmakeraw(&options); 
    cfsetispeed(&options, B19200); 
    cfsetospeed(&options, B19200); 
    tcsetattr(fd, TCSANOW, &options); 

    char txpacket[] = {0x23, 0x06, 0x00, 0x00, 0xdd, 0xf9}; 
    ssize_t written = write(fd, txpacket, sizeof(txpacket)); 
    printf("Written %d bytes\n", written); 

    printf("Starting to wait for target to respond\n"); 
    while(1) 
    { 
     fd_set readset; 
     FD_ZERO(&readset); 
     FD_SET(fd, &readset); 
     int nCount = select(fd + 1, &readset, NULL, NULL, NULL); 
     if(nCount > 0) 
     { 
      if(FD_ISSET(fd, &readset)) 
      { 
       int i; 
       char buffer[128]; 
       ssize_t bytesread = read(fd, buffer, sizeof(buffer)); 
       printf("Received %d bytes\n", bytesread); 
       for(i = 0; i < bytesread; i++) 
       { 
        printf(" %02x", buffer[i]); 
       } 
      } 
     } 
    } 
} 

Ten program otwiera urządzenie szeregowe/dev/ttyS0, pisze sekwencję danych do niego i zaczyna słuchać na odpowiedź. Otrzymuję następujące dane wyjściowe:

Device opened 
Written 6 bytes 
Starting to wait for target to respond 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
Received 0 bytes 
... 

Aplikacja zużywa 100% procesora. Nie mogę odbierać żadnych danych, mimo że docelowy sprzęt faktycznie je transmituje.

Co jest nie tak?

Odpowiedz

7

return 0 oznacza warunek końca pliku. Powinieneś to sprawdzić i wyjść z pętli, jeśli wystąpi.

Co powoduje to - koniec pliku na porcie szeregowym wskazuje, że wykrył przerwanie, co oznacza, że ​​linia DCD została usunięta.

Możesz ustawić flagę CLOCAL w options.c_cflag, aby zignorować linie kontrolne modemu, jeśli twoje urządzenie nie ustawiło ich poprawnie.

+0

Dzięki! To właśnie było przyczyną problemu. – anorm

+0

Cholera, nie widziałem rzeczy CLOCAL! – shodanex

+0

Miał ten sam problem, dzięki za napiwek. Nie zdawałem sobie sprawy, że cfmakeraw nie widzi tych dwóch oczywistych flag. – RishiD

1

Powinieneś wypróbować bez flagi O_NONBLOCK. w trybie RAW, czy ustawienia c_cc[VMIN] i c_cc[VTIME] wynosi 0, port szeregowy zachowują się tak (według człowieka cfmakeraw):

Jeśli dane są dostępne, przeczytaj powraca natychmiast, a mniejsza od liczby dostępnych bajtów lub liczba żądanych bajtów . Jeśli żadne dane jest dostępny, przeczytaj zwraca 0

Więc co należy spróbować to:

options->c_cc[VMIN]=1; 
+0

Naprawdę dobra uwaga na dziwnym rogu. – Joe

Powiązane problemy