Неблокирование чтения с фиксированными данными на входе

Я хочу использовать serial port для связи с другим устройством txdev, проблема в том, что txdev отправляет данные асинхронно, и я не хочу, чтобы функция read блокировалась, хорошо, что txdev отправляет данные с фиксированным размером, но я не знаете, как использовать этот трюк. что я делаю:

 fd = open(DEVICE_NAME, O_RDWR | O_NOCTTY); bzero(&termios_p, sizeof(termios_p)); termios_p.c_cflag = CS8|CSTOPB|CLOCAL|CREAD; termios_p.c_iflag = IGNPAR; termios_p.c_oflag = 0; termios_p.c_lflag = ~ICANON; termios_p.c_cc[VMIN]=DATA_LENGTH; termios_p.c_cc[VTIME]=10; cfsetispeed(&termios_p, BAUDRATE); cfsetospeed(&termios_p, BAUDRATE); tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&termios_p); 

из этого сообщения я undrestand, что это заставляет блокировку чтения VTIME = 0 также блокировать.

Может ли кто-нибудь помочь мне разобраться в решении? Думаю, мне нужно использовать обработчик прерываний вместо read , согласны ли вы?

Второй вопрос: поскольку отправитель не может синхронизироваться с приемником, есть обработчик прерываний, который хранит полученные данные в указанном буфере (i undrestand, что это имеет место для канонического режима, но не в неканоническом режиме), или это делается только когда функция read будет достигнута, если я ошибаюсь, исправьте меня

Как обычно, большое спасибо.

Я хочу использовать serial port для связи с другим устройством txdev, проблема в том, что txdev передает данные асинхронно, и я не хочу, чтобы функция чтения блокировала,

Вы, кажется, неправильно понимаете, как программа Linux должна читать и записывать в serial port. Все данные буферизуются между вашей программой и UART. Ваша программа не должна всегда быть готовой к чтению данных, когда она выходит из провода. ОС (в частности, драйвер устройства UART и подсистема tty, которая включает в себя линейные дисциплины) делает это и буферизирует данные для вашей программы.

RS-232 по определению является асинхронной линией связи. Символы / байты могут быть переданы в любое время. Пакеты сообщений будут поступать в любой момент времени, поэтому прикладной программе придется ждать байтов, входящих в пакет сообщений. Это случай использования блокирующих чтений.

Типичная проблема получения последовательных данных заключается в том, как выполнить лексическое сканирование полученных данных для идентификации полного пакета сообщений. Текстовые сообщения (канонический режим) просто используют символы управления строкой ASCII для разграничения сообщений / строк. Даже пакеты с фиксированной длиной нуждаются в проверке (чтобы убедиться, что сообщение действительно начинается с правильного байта). См. Этот пример сканирования пакетов фиксированной длины .

Я думаю, что я должен использовать обработчик прерываний вместо чтения, согласны ли вы?

Нет, драйвер устройства UART уже обслуживает свои прерывания (или использует DMA) для захвата каждого байта, который получен от последовательной связи.

Поскольку отправитель не может синхронизироваться с приемником, есть обработчик прерываний, который хранит полученные данные в указанном буфере (i undrestand, что это имеет место для канонического режима, но не в неканоническом режиме), или это делается только при чтении функции достигается,

Нет необходимости, чтобы serial port на конце приема «синхронизировался» с последовательным портом отправки на уровне байта. RS-232 является асинхронной линией связи: отправитель может / будет передавать символ / байт в любое время, а другой конец должен быть готов к его приему (если на уровне драйвера устройства не установлено ни аппаратное, ни программное обеспечение) (а не прикладной программы).

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

«Синхронизация» обычно является проблемой, которая должна быть разрешена протоколом на уровне сообщения или пакета. Master-slave является общей конфигурацией для определения протокола последовательной связи. Ведущая сторона отправляет сообщение запроса на подчиненную сторону. Ведомое устройство всегда должно быть готово для получения запроса. Ведомая сторона может ответить запросом транзакции или захватом данных или любым другим, или сообщением NAK, чтобы указать, что у него нет ничего для мастера. Этот диалог запроса-ответа предназначен для управления или изменения streamа данных (и обработки нагрузки) между двумя блоками.

добавление

то, что я планирую сделать, это на самом деле блокировка чтения (VTIME = 0 VMIN = DATA_LENGTH) в бесконечном цикле

Предположительно, вы всегда будете запускать свою программу перед передающим устройством, чтобы первый переданный DATA_LENGTH совпадал с первым, прочитанным программой.

Это, вероятно, будет работать большую часть времени в идеальной или контролируемой ситуации.
Но для промышленных приложений 24/7 вероятность потери выравнивания кадра сообщения реальна (например, отправка устройства перезапускается в середине передачи), и поэтому схема, которая не имеет активных средств для проверки и восстановления выравнивания кадра сообщения, неадекватна.

IOW необработанное чтение () последовательного порта может не возвращать выровненное сообщение в вашем буфере (т.е. buf [0] может не содержать первый байт сообщения).
Гораздо меньший VMIN с ненулевым VTIME – это типичная конфигурация termios, основанная на предпосылке, что после каждого сообщения последовательная связь бездействует (на короткий промежуток времени).
Но код должен быть надежным для обработки любых / всех fragmentов сообщения по мере их чтения. Поэтому для восстановления всего сообщения может потребоваться более одного read () .