清除串口缓冲区

时间:2012-10-22 14:19:43

标签: c linux serial-port flush

这就是我打开串口的功能(使用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);可以解决这个问题,通过在初始化端口之前刷新IO缓冲区,但没有这样的运气。有什么见解吗?

3 个答案:

答案 0 :(得分:24)

我想我明白了。出于某种原因,我需要在刷新之前添加延迟。在返回fd 之前添加了这两行似乎来完成这个技巧:

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

答案 1 :(得分:5)

此问题的原因在于使用USB串行端口。如果您使用常规串行端口,则不会出现此问题。

大多数USB串口驱动程序都不支持正确刷新,可能是因为无法知道内部移位寄存器,FIFO或USB子系统中是否还有数据。 / p>

另请参阅Greg对早先报告的类似问题的回复here

您的sleep可以解决问题,但这只是一种解决方法。不幸的是,除了使用常规串行端口之外,没有其他解决方案。

答案 2 :(得分:4)

我一直遇到类似的症状,Arduino Uno板重置open()。我在调用Arduino板之前生成的open()调用之后接收数据,因此在调用open()之前。

使用ioctl()调用来跟踪问题我了解到,在调用tcflush()时,数据尚未到达输入缓冲区。所以tcflush()确实有效,但没有数据可以刷新。 open()调用后睡眠1000 us似乎解决了这个问题。这是因为延迟允许数据在调用tcflush()之前到达,因此tcflush()确实刷新了输入缓冲区。

您可能遇到了同样的问题。