Случайная потеря ответа при чтении с 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)

0 ответов

Другие вопросы по тегам