Очистка буфера последовательного порта

Это то, что моя функция выглядит как открыть последовательный порт (используя Ubuntu 12.04):

int open_port(void)
{
  int fd; /* File descriptor for the port */

  fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);

  if (fd == -1)
  {
   // Could not open the port.          
   perror("open_port: Unable to open /dev/ttyUSB0 - ");
  }
  else
    fcntl(fd, F_SETFL, 0);

  struct termios options;

  tcgetattr(fd, &options); 
  //setting baud rates and stuff
  cfsetispeed(&options, B19200);
  cfsetospeed(&options, B19200);
  options.c_cflag |= (CLOCAL | CREAD);
  tcsetattr(fd, TCSANOW, &options);

  tcsetattr(fd, TCSAFLUSH, &options);

  options.c_cflag &= ~PARENB;//next 4 lines setting 8N1
  options.c_cflag &= ~CSTOPB;
  options.c_cflag &= ~CSIZE;
  options.c_cflag |= CS8;

  //options.c_cflag &= ~CNEW_RTSCTS;

  options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //raw input

  options.c_iflag &= ~(IXON | IXOFF | IXANY); //disable software flow control

  return (fd);
}

В чем проблема, когда я запускаю эту программу, и если мое последовательное устройство уже подключено, в буфере есть контент. Мне нужно очистить буфер, прежде чем я начну читать его. Я думал, что использование tcsetattr(fd, TCSAFLUSH, &options); поможет устранить эту проблему, сбросив буферы ввода-вывода до инициализации порта, но не удачи. Любое понимание?

Ответ 1

Думаю, я понял это. По какой-то причине мне нужно добавить задержку перед промывкой. Эти две строки, добавленные перед возвратом fd, похоже, сделали трюк:

  sleep(2); //required to make flush work, for some reason
  tcflush(fd,TCIOFLUSH);

Ответ 2

Причиной этой проблемы является использование последовательного порта USB. Если вы используете обычный последовательный порт, у вас не будет этой проблемы.

Большинство драйверов последовательного порта USB не поддерживают корректную очистку, вероятно, потому, что нет способа узнать, есть ли еще данные во внутреннем регистре сдвига, FIFO или в подсистеме USB.

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

Ваш sleep может вылечить проблему, но это только обход. К сожалению, нет другого решения, кроме использования обычного последовательного порта.

Ответ 3

У меня были подобные симптомы с платой Arduino Uno, которая сбрасывается на open(). Я получал данные после вызова open(), который был создан до того, как плата Arduino была reset и, таким образом, до вызова функции open().

Отслеживая проблему с помощью вызовов ioctl(), я узнал, что данные просто не пришли во входной буфер к тому времени, когда был вызван tcflush(). Таким образом, tcflush() действительно работал, но не было данных для очистки. Сон 1000 нас после вызова open(), похоже, решил проблему. Это связано с тем, что задержка позволила получить данные до того, как был вызван tcflush(), и поэтому tcflush() действительно сбросил входной буфер.

Возможно, вы столкнулись с одной и той же проблемой.