2013-08-06 15 views
5

Ho studiato molti thread utili e alcuni tutorial, ma ho ancora alcuni problemi con qualcosa che dovrebbe essere molto semplice. Per avere un riferimento qui ci sono alcune discussioni che ho emetterlo:Porta seriale Linux: blocco lettura con timeout

How to implement a timeout in read function call?

how to open, read, and write from serial port in C

In ogni caso, ho un po 'un problema. Il mio codice funziona bene se ricevo dati. Se non lo faccio, la funzione read() si blocca e l'unico modo per uscire dal mio programma è usare kill -9 (NOTA: uso la gestione del segnale per segnalare alla discussione la lettura dei dati seriali da terminare. il colpevole, la chiamata read() si blocca ancora, anche se ho rimosso la gestione del segnale). Quello che sto cercando di fare è avere una lettura che blocchi e legga un chunk alla volta (quindi risparmiando l'utilizzo della CPU), tuttavia se la lettura non riceve dati, non lo faccio per scadere.

Qui ci sono le impostazioni che sto applicando alla porta:

struct termios serial_struct; 
serial_struct.c_cflag = B115200 | CS8 | CLOCAL | CREAD; 
serial_struct.c_iflag = IGNPAR; 
serial_struct.c_oflag = 0; 
serial_struct.c_lflag = 0; 
serial_struct.c_cc[VTIME] = 1; // timeout after .1s that isn't working 
serial_struct.c_cc[VMIN] = 64; // want to read a chunk of 64 bytes at a given time 

ho quindi impostare queste impostazioni con tcsetattr() e verificare che il porto ha ricevuto le impostazioni tramite tcgetattr(). Sto pensando che le mie impostazioni potrebbero essere in conflitto, perché le mie letture sembrano bloccarsi e aspettare fino a 64 byte, ma non fare nulla per quanto riguarda il timeout. Capisco che posso usare select() per gestire un timeout, ma spero di evitare le chiamate di sistema multiple.

Come sempre, grazie in anticipo per l'aiuto.

+1

D: Qual è il dispositivo (ad esempio/dev/ttyS0)? Qual è il dispositivo su questa porta (una porta COM RS232? Qualcos'altro?) ANCHE: questo è un link eccellente, se non lo conosci già: http://www.tldp.org/HOWTO/Serial-Programming -COME/. Probabilmente ti interessano le parti "I/O asincrone". – paulsm4

risposta

6

Da man 3 termios:

MIN> 0; TIME> 0: TIME specifica il limite per un timer in decimi di secondo. Una volta che un byte iniziale di input diventa disponibile, il timer viene riavviato dopo ogni ulteriore byte ricevuto. read (2) restituisce quando il numero minore di byte richiesto o il byte MIN sono stati letti o quando scade il timeout tra byte. Poiché il timer viene avviato solo dopo che il byte iniziale diventa disponibile, verrà letto almeno un byte.

Nota non inizio che il timer fa fino alla ricezione di almeno un byte di dati. Dopo aver ricevuto il primo byte di dati, la lettura si interromperà se vi è uno scarto di TIME decimi di secondo tra la ricezione di byte di dati consecutivi.

+0

AHA! Quindi termios non ha modo di impostare un timeout "reale" nel caso in cui non venga passato alcun dato? Come posso risolvere questo allora? Con select()? –

+0

Sì: il collegamento che ho citato sopra discute anche "select()". D: Qual è il dispositivo? – paulsm4

+0

@ It'sPete Penso che quasi ogni programma cresca al punto che si finisce (a) usando 'select' o' poll' su multiplex I/O o (b) gestendo stream separati con thread separati. Può anche finire. – Casey