LINUX.ORG.RU

[C][чайник] Асинхронная работа с ком-портом - ЧЯДНТ?

 ,


0

0

Хочу асинхронно общаться с модемом. На основе Serial Programming Howto (http://www.faqs.org/docs/Linux-HOWTO/Serial-Programming-HOWTO.html) и некоторого гуглинга набросал программу на plain C: http://pastebin.org/320905 . Компилируется без ошибок, запускаю — и создается ощущение, что попадаю в бесконечный цикл — получаю что-то типа такого:

 
:ATI:3
 = received SIGIO signal.
 = received SIGIO signal.
:ATI:3
 = received SIGIO signal.
 = received SIGIO signal.

И так постоянно. Подозреваю, что я что-то недопонимаю в параметрах termios. Где я неправ?

Для асинхронной работы есть select/poll/epoll, его лучше и использовать.

vga ★★
()
Ответ на: комментарий от vga

Спасибо, разбираюсь с селектом.

Для тех, кто это потом будет читать: в Serial Programming Howto есть ошибки. Например, в том же описании работы с select у макроса FD_ISSET указан только один аргумент, а нужно два:


FD_ISSET(fd2, &readfs)

decadent
() автор топика
Ответ на: комментарий от decadent

Там еще не помешает поставить на дескрипторы O_NONBLOCK, как написано в примере выше, и отлавливать EWOULDBLOCK/EAGAIN в read/write. В man select пишут

Under Linux, select() may report a socket file descriptor as «ready for reading», while nevertheless a sub- sequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.

Не уверен, что это относится и к последовательным портам, а не только к сокетам, но лучше перестраховаться.

vga ★★
()
        int fd, c, res;
        struct termios oldtio, newtio;
        struct sigaction saio;

Инициализировать эту красоту кто будет? А.С. Пушкин?

       char buf[255];
...
                        res = read(fd, buf, 255);
                        buf[res] = '\0';

Нутыпонел.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Нутыпонел.

Дык я же говорю — набросал, а не написал. Мне надо понять принцип, а потом уже буду вылизывать.


 char buf[255]; 
 res = read(fd, buf, 255); 
 buf[res] = '\0'; 

А как иначе? По одному байту читать?

decadent
() автор топика
Ответ на: комментарий от decadent

сначала разберись с Си, а потом уже лезь в более высокие материи типа портов и т.п ;)

kuzulis ★★
()
Ответ на: комментарий от decadent

Подсказка: читаешь ты как раз правильно. ;)

LamerOk ★★★★★
()
Ответ на: комментарий от decadent

У вас не лады с количеством байт, не только в read(), но и

res = write(fd, «ATI\r», 3);

Почему 3 байта? И проверяте результаты syscall'ов, может res быть и 0 и -1...

ИМХО, saio.sa_mask лучше делать полной, а не пустой, чтобы во время обработчика сигнала не было обработки других сигналов, тем более если в обработчике вызывать printf().

Сам вызов read() не вполне правилен. Если вы ожидаете прихода сигнала, то нужно сначала запретить обработку сигналов (через sigprocmask()), потом проверить значение wait_flag, а потом «засыпать» на sigsuspend() с маской, разрешающей обработку сигналов.

А относительно бесконечного цикла, дак наверное у вас к порту прицеплен модем с включеным echo режимом, вы постоянно пишите/читаете то, что написали.

mky ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.