Случайная потеря ответа при чтении с USB-порта
Я пишу и читаю через последовательный порт USB (ttyACMx), который соединяет модем с процессором. У меня есть процесс последовательной связи на процессоре под управлением Linux, который принимает пользовательский ввод (команды AT модема) и записывает его в последовательный порт модема. Чтобы получить ответ, у меня есть поток, который прослушивает дескриптор файла последовательного порта (fd) с помощью select(), а затем выполняет read() на fd.
Когда я читаю из порта, я ожидаю полного ответа на команду AT, которую я посылаю модему. Который работает в большинстве случаев. Изредка я получаю только часть ответа (например, два символа -), которую я ожидаю для AT-команды, которую я отправляю, и мне больше нечего читать (select() не возвращает).
У меня вопрос, есть ли способ определить, есть ли в буфере приема моего последовательного порта что-то для чтения, но нужно ли его сбросить, учитывая, что я предполагаю, что модем всегда отправляет полный ответ процессору?
Фрагмент последовательного порта получения потока и конфигурации порта:
while(1)
{
numfd = select(max_fd, &read_fd, NULL, NULL, NULL);
if(numfd > 0)
{
if(FD_ISSET(serial_fd, &read_fd))
{
ioctl(serial_fd, FIONREAD, &bytes);
if(bytes)
{
num_read = read(serail_fd, buf, buf_len);
if(num_read <= 0)
{
//error
}
else
{
// construct complete AT command response from buf
}
}
}
}
where serial_fd is:
serial_fd = open("/dev/ttyACM0", O_RDWR|O_EXCL|O_NOCTTY|O_NONBLOCK);
and it is configured as:
tcflush(serial_fd, TCIOFLUSH);
ioctl(serial_fd, TIOCGSERIAL, &serail_info_buf);
serail_info_buf.closing_wait = ASYNC_CLOSING_WAIT_NONE;
ioctl (serial_fd, TIOCSSERIAL, &serail_info_buf);
tcgetattr(serial_fd, &termios_buf);
termios_buf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | PARENB | PARODD | CRTSCTS);
termios_buf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXOFF | IXANY);
termios_buf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET);
termios_buf.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL);
termios_buf.c_cc[VMIN] = 2;
termios_buf.c_cc[VTIME] = 1;
termios_buf.c_cc[VEOF] = 0;
termios_buf.c_iflag |= IGNPAR;
termios_buf.c_cflag |= (CLOCAL | CREAD);
termios_buf.c_cflag &= ~PARENB;
termios_buf.c_cflag &= ~CSTOPB;
termios_buf.c_cflag &= ~CSIZE;
termios_buf.c_cflag |= CS8;
cfsetispeed(&termios_buf, B115200);
cfsetospeed(&termios_buf, B115200);
tcsetattr (serial_fd, TCSANOW, &termios_buf)