2013-08-06 12 views
5

Przeanalizowałem wiele przydatnych tematów i kilka samouczków, ale nadal mam pewne problemy z czymś, co powinno być bardzo proste. Dla porównania oto kilka wątków, które ja perused:Linux Serial Port: Blocking Read with Timeout

How to implement a timeout in read function call?

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

W każdym razie, mam mały problem. Mój kod działa poprawnie, jeśli otrzymam dane. Jeśli nie, funkcja read() zatrzymuje się i jedynym sposobem na wyjście z mojego programu jest użycie kill -9 (UWAGA: Używam obsługi sygnału do sygnalizowania wątkowi odczytywania danych szeregowych w celu zakończenia. winowajcę, wywołanie read() nadal zatrzymuje się, nawet jeśli usunąłem obsługę sygnałów). Co próbuję zrobić, to mieć odczyt, który blokuje i odczytywa kawałek (co oszczędza zużycie procesora), jednak jeśli odczyt nie otrzyma żadnych danych, nie będę tracił czasu.

Oto ustawienia, które mam zastosowanie do portu:

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 

I wtedy ustawić te ustawienia z tcsetattr() i potwierdzić, że port otrzymał ustawienia poprzez tcgetattr(). Myślę, że moje ustawienia mogą być w konflikcie, ponieważ moje odczyty wydają się blokować i czekać, aż zostaną odebrane 64 bajty, ale nie robić nic w odniesieniu do limitu czasu. Rozumiem, że mogę użyć select(), aby poradzić sobie z przekroczeniem limitu czasu, ale mam nadzieję uniknąć wielu wywołań systemowych.

Jak zawsze, dziękuję z góry za pomoc.

+1

P: Co to jest urządzenie (np./Dev/ttyS0)? Co to jest urządzenie na tym porcie (port RS232 COM? Coś jeszcze?) RÓWNIEŻ: jest to doskonały link, jeśli jeszcze go nie znasz: http://www.tldp.org/HOWTO/Serial-Programming -JAK/. Prawdopodobnie interesują Cię części "asynchroniczne I/O". – paulsm4

Odpowiedz

6

Od man 3 termios:

MIN> 0; TIME> 0: TIME określa limit timera w dziesiątych częściach sekundy. Po udostępnieniu początkowego bajtu wejścia licznik jest restartowany po otrzymaniu każdego kolejnego bajtu. read (2) zwraca, gdy odczytano mniejszą liczbę bajtów lub bajt MIN lub upłynął limit czasu między bajtami. Ponieważ timer jest uruchamiany dopiero po udostępnieniu początkowego bajtu, zostanie odczytany co najmniej jeden bajt.

Uwaga nie początek że zegar działa do momentu otrzymania przynajmniej jeden bajt danych. Po otrzymaniu pierwszego bajtu danych, odczyt wygaśnie, jeśli kiedykolwiek pojawi się przerwa o TIME dziesiętnych sekundy między odebraniem kolejnych bajtów danych.

+0

AHA! Więc termios nie ma możliwości ustawienia "prawdziwego" limitu czasu w przypadku, gdy żadne dane nie są przekazywane? Jak mogę to rozwiązać? Z select()? –

+0

Tak: Powyższy link również omawia "select()". P: Co to za urządzenie? – paulsm4

+0

@ It'sPete Myślę, że prawie każdy program ostatecznie wzrasta do punktu, w którym kończy się albo (a) przy użyciu 'select' lub' poll' do multipleksowania I/O lub (b) obsługi oddzielnych strumieni z osobnymi wątkami. Oby też to się skończyło. – Casey