清除串口缓冲区

cap*_*com 16 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);
}
Run Code Online (Sandbox Code Playgroud)

问题是,当我运行这个程序并且我的串行设备已经插入时,缓冲区中有内容.在我开始阅读缓冲区之前,我需要一种清除缓冲区的方法.我认为使用tcsetattr(fd, TCSAFLUSH, &options);可以解决这个问题,通过在初始化端口之前刷新IO缓冲区,但没有这样的运气.任何见解?

cap*_*com 24

我想我明白了.出于某种原因,我需要在刷新之前添加延迟.返回之前添加的这两行fd 似乎已经完成了诀窍:

  sleep(2); //required to make flush work, for some reason
  tcflush(fd,TCIOFLUSH);
Run Code Online (Sandbox Code Playgroud)

  • 希望有人可以启发我们为什么这样做:-) (14认同)
  • Linux 4.8.0,ubuntu 16.04x64,cp210x USB UART驱动程序(USB VID/PID:10c4:ea60) - 在此设置中遇到了同样的问题.解决方案:在`open()`之后输入`usleep(10000);`.两秒钟太长了,但@areslagae建议的1000us太短了.在我的情况下,10毫秒是正确的. (2认同)

小智 7

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

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

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

  • 最后,我不是唯一的。 (2认同)

Rob*_*ert 5

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

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

又见格雷格对早些时候报道了类似的问题的答复这里.

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