URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 3172
[ Назад ]

Исходное сообщение
"read() из ком-порта и таймауты"

Отправлено Ivan daniluk , 15-Июл-04 13:19 
Есть устройство, разговаривающее с компом через rs232. Ставлю на дескриптор таймаут на чтение:

fd = open(path, O_RDWR | O_NOCTTY);
if (fd == -1)
{
    perror("open serial port");
    return fd;
}

/* Set up serial port */
fcntl(fd, F_SETFL, 0);
tcgetattr(fd, &options);
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);
options.c_cflag |= (CLOCAL | CREAD);
/* set 8N1 */
options.c_cflag |= CS8;
/* set timeouts */
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 4;
tcsetattr(fd, TCSANOW, &options);


По документации, с такими опциями(c_cc[VMIN] == 0 && c_cc[VTIME] > 0), функция read() будет выходить по таймауту - либо раньше, если что-либо в буффер попадет. Так вот, на одном из циклов чтения(читает по 1 байту BTW), read() замерзает. Просто ожидает вечно чего-то на вход и не выходит по таймауту. Прошелся с ddd, параметры порта нигде не изменяются, таймаут вроде устанавливается правильно. Делал уже и таймаут через select - та же херня - select() возвращает 1, а read() замерзает. По идее ведь с установленным таймаутом, read() не должен "замерзать" никогда?! Или есть еще ситуации?
Я теряюсь, не знаю, куда дальше копать. Ядро 2.6.7.


Содержание

Сообщения в этом обсуждении
"read() из ком-порта и таймауты"
Отправлено Ivan Daniluk , 15-Июл-04 20:18 
Проблема была в том, что по умолчанию для ком-порта устанавливался канонический режим чтения, а от девайса передавались управляющие символы вроде 0x04, 0x05, которые в данном контексте не должны были быть управляющими.
Проблемы решилась установкой следующих флагов:
.c_lflag |= IEXTEN;
.c_lflag &= ~ICANON;