Linux последовательный порт бед - PullRequest
1 голос
/ 08 октября 2011

Я пишу код для общения с другим устройством через последовательный порт в Linux

Я хочу неблокировать с таймаутом, даже если прибывает 0 символов. Структура termios позволяет вам установить VTIME и VMIN, но если VMIN больше 0 и если возвращается 0 символов, вызов чтения будет блокироваться навсегда ... WTF, почему. Похоже, это не относится к случаю, когда другое устройство отключается в течение короткого периода времени, и теперь мое приложение блокируется при вызове чтения. Это кажется критическим поведением, которым пренебрегать Я действительно не хочу реализовывать свои собственные тайм-ауты.

Write command
Read block timeout of around .3s(if 0 characters, still wait max of .3s)

Ответы [ 2 ]

2 голосов
/ 08 октября 2011

Если вы хотите, чтобы read возвращался без данных после тайм-аута, вы можете установить MIN == 0 и TIME > 0.От tcsetattr(3):

MIN == 0;ВРЕМЯ> 0: ВРЕМЯ указывает ограничение для таймера в десятых долях секунды.Таймер запускается при вызове read (2).read (2) возвращает либо когда доступен хотя бы один байт данных, либо когда истекает таймер.Если время таймера истекает, а вход не становится доступным, read (2) возвращает 0.

Этот режим можно использовать для создания коммуникационных функций более высокого уровня, которые вы должны в любом случае реализовать для частичного чтения (то есть если другой конец падает в середине «пакета»), неправильные пакеты, разделенные пакеты и так далее.Это все, что простой read не может сделать для вас.

1 голос
/ 08 октября 2011

Взгляните на select.Он ждет, пока данные не будут готовы к чтению (но на самом деле ничего не читает).На справочной странице :

timeout указана верхняя граница количества времени, прошедшего до возврата select () .Это может быть ноль, в результате чего select () немедленно вернется.(Это полезно для опроса.) Если время ожидания равно NULL (нет времени ожидания), select () может блокироваться бесконечно.

Код будет выглядеть как-токак:

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 300000;

fd_set infds;
FD_ZERO(&infds);
FD_SET(fd, &infds);

// Assume fd is the file descriptor for the serial device
if (select(fd + 1, &infds, NULL, NULL, &tv) > 0)
{
    // The read will not block now
    // Assume buffer and size are declared and set appropriately
    amountRead = read(fd, buffer, size);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...