2015-12-09 22 views
16

Sto usando il termios api in Linux per comunicare con un dispositivo seriale. Sto cercando di rilevare se il dispositivo è disconnesso, quindi posso provare a riconnettersi dopo un certo timeout. Ho il seguente codice esempio:Rilevare se un dispositivo di carattere si è disconnesso in Linux con termios api (C++)

while(1) 
{ 
    FD_ZERO(&rfds); 
    FD_SET(tty_fd, &rfds); 

    // have tried checking fcntl(tty_fd, F_GETFL); too 

    // Blocking call to wait until we have data 
    select(tty_fd+1, &rfds, NULL, NULL, NULL); 

    // While we have data, collect it 
    while (read(tty_fd, &c, 1)>0 && bytesRead++<200) 
    { 
     serialBuffer.push_back(c); 
    } 

    bytesRead = 0; 

    // Try to parse it 
    BufferParse(); 
} 

non sto realmente vedere select() o valori di errore di ritorno fcntl (-1) dopo il dispositivo ttyUSB è fisicamente scollegato. Potrei, naturalmente, controllare se il file in/dev/esiste, ma speravo che esistesse una soluzione più elegante.

Gradirei qualche consiglio, grazie!

+3

Con un adattatore USB, potrebbero esserci due livelli di disconnessione. Con un dispositivo collegato alla porta seriale, quel dispositivo non poteva più comunicare. Potrebbe esserci una disconnessione del collegamento RS232 stesso. Il segnale DSR/DTR viene spesso utilizzato per determinare la connessione locale. Con USB anche nell'immagine, l'adattatore USB può essere disconnesso dall'host. Quindi devi chiarire cosa stai cercando di rilevare. La lettura dei dati proviene dal dispositivo seriale collegato, non dalla porta seriale o dall'adattatore USB. Se il dispositivo è un modem, allora hai un altro collegamento. – sawdust

+1

In questo caso, sto specificamente parlando del dispositivo USB-seriale disconnesso dalla macchina host. – chris12892

+1

Puoi usare libudev per guardare gli eventi del dispositivo attraverso un descrittore di file: http://www.signal11.us/oss/udev/ – purplepsycho

risposta

3

Innanzitutto pena ricordare che il comportamento seriale-usb segue:

Sul dispositivo usb disconnessione scollegato viene chiamato

@disconnect: Chiamato quando l'interfaccia non è più accessibile, solitamente perché il suo dispositivo è stato (o è in corso di essere) scollegato o il modulo driver viene scaricato.

nel nostro caso si tratta di usb_serial_disconnect (struct usb_interface * Interfaccia)

che usb_serial_console_disconnect (seriale) calles, che calles tty_hangup ... e così via.

È possibile seguire la catena ha iniziato da qui: http://lxr.free-electrons.com/source/drivers/usb/serial/usb-serial.c#L1091

In breve questo si traduce in seguito maniera classica:

segnali pselect che descrittore di file è pronto e ioctl (fd, FIONREAD, & len) restituisce zero len.

È così che hai scollegato il dispositivo.

Summurizing (derivato dal codice):

while(1) 
{ 
    FD_ZERO(&rfds); 
    FD_SET(tty_fd, &rfds); 

    // have tried checking fcntl(tty_fd, F_GETFL); too 

    // Blocking call to wait until we have data 
    int ready = select(tty_fd + 1, &rfds, NULL, NULL, NULL); 

    if(ready && FD_ISSET(tty_fd, &rfds)) { 
     size_t len = 0; 
     ioctl(tty_fd, FIONREAD, &len); 
     errsv = errno; 

     if(len == 0) 
     { 
     printf("prog_name: zero read from the device: %s.", strerror(errsv)); 
     /* close fd and cleanup or reconnect etc...*/ 
     exit(EXIT_FAILURE); 
     } 

     // While we have data, collect it 
     while (read(tty_fd, &c, 1)>0 && bytesRead++<200) 
     { 
     serialBuffer.push_back(c); 
     } 

     bytesRead = 0; 

     // Try to parse it 
     BufferParse(); 
    } 
} 

E 'un peccato che non hai detto che tipo di dispositivo che si sta utilizzando.

Nel caso in cui il dispositivo sia in grado di controllare il flusso RTS/CTS è anche possibile rilevare un'interruzione di linea.

+0

Ehi, grazie per il commento dettagliato! Il dispositivo è un chip FTDI collegato a un Raspberry Pi. Raspian Jessie, se la distro è importante. Ci proverò un po 'più tardi e aggiornerò come ha funzionato. – chris12892

+0

Hah! Funziona magnificamente! Grazie mille! – chris12892

+0

Np, in realtà zero read deriva dalla sostituzione dei gestori ops predefiniti con quelli fittizi, che restituiscono zero in lettura. È praticamente lo stesso comportamento delle prese. – Maquefel