У меня есть следующая настройка: компьютер под управлением Linux (TCL) и устройство, которое отправляет пакеты фиксированной длины (10 байтов) с фиксированной частотой (100 Гц).Как получить данные на последовательном порту синхронно?
На компьютере у меня есть этот последовательный порт, и я пытаюсь читать входящие данные. Однако, вместо того, чтобы получать его в 10-байтовых фрагментах все время, считывается меньшее количество данных, и я вынужден их снова собрать.
Моя цель - отправить ответ для каждого пакета после его поступления, сохраняя интервалы между пакетами как можно больше.
Это, как я открыть последовательный порт:
int fd = open(device_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
if(fd == -1)
{
LOGPRINT("Failed to open terminal file.\nError #%d (%s)\n",
errno, strerror(errno));
return fd;
}
LOGPRINT("Setting terminal attributes\n");
struct termios config;
struct termios *pterm = &config;
// set baud rate
LOGPRINT("Setting baud rate to %d.\n", baud_rates[baud_rate_index]);
// change to raw mode
LOGPRINT("Setting terminal to raw mode\n");
pterm->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR
| IGNCR | ICRNL | IXON);
pterm->c_oflag &= OPOST;
pterm->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
cfsetispeed(pterm, baud_bits[pconfig->baud_rate_index]);
cfsetospeed(pterm, baud_bits[pconfig->baud_rate_index]);
LOGPRINT("Set character size, parity and stop bit flags.\n");
// set character size
pterm->c_cflag &= ~CSIZE;
pterm->c_cflag |= csize_flag;
// set parity
pterm->c_cflag &= ~(PARENB | PARODD);
pterm->c_cflag |= parity_flag;
// set stopbits
pterm->c_cflag &= ~CSTOPB;
pterm->c_cflag |= stopbits_flag;
// enable reading; ignore control lines
pterm->c_cflag |= CREAD | CLOCAL;
// disable flow control
pterm->c_cc[VMIN] = 1;
pterm->c_cc[VTIME] = 0;
LOGPRINT("Flush terminal.\n");
// flush terminal
tcflush(fd, TCIOFLUSH);
LOGPRINT("Apply parameters.\n");
return WRAPSYSCALL(tcsetattr(fd, TCSANOW, pterm));
Кроме того я установить следующий дескриптор файла с fnctl:
int flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags | FASYNC | O_DIRECT);
Я чтение из дескриптора файла в цикле с select()
вызова в наборе дескрипторов файлов, содержащем fd
, затем считывая все байты avaiable (запрашивая количество байтов намного больше 10).
Что я должен изменить для обеспечения того, чтобы входящие данные обрабатывались по мере их правильного ввода, своевременно?
«считывается меньшее количество данных, и я вынужден их снова собрать» - да, это нормально с последовательными потоками байтов, а также использование подходящего протокола для установления границ сообщений. –
Меня беспокоит причина. Если это происходит из-за того, что не все данные полученного пакета сразу попадают в буфер файлов, это означает, что я читаю остальную часть пакета только тогда, когда следующий на урнах, который побеждает цель ответа на пакеты по мере их поступления. – Srv19
Большинство драйверов опубликует любой оставшиеся буферизованные данные, если больше не приходит в течение некоторого таймаута, обычно 3-5 символов. –