当端口上的字符时,select()调用不返回

时间:2009-08-27 22:08:58

标签: c++ linux select

我有一个选择调用似乎没有检测到串行端口上的字符。有什么我想念的吗?

如果我删除上面块中的read()代码,select会返回一段时间,直到清空现有端口缓冲区,然后再检测不到更多内容。

我正在将字符串流到端口,并且运行minicom会在端口上显示连续输入流。

有人能看到这段代码有什么问题吗?

int main(void)

{


  int ret;
  char buf[1280];
  fd_set         m_Inputs;  // fd_set for the select call for com input

  int            m_maxFD;   // max FD for select() call.

  struct timeval tv;



  int fd1;
  fd1 = open("/dev/ttyXR6", O_RDWR | O_NOCTTY | O_NONBLOCK);

  fcntl(fd1, F_SETFL, 0);

  struct termios options;

  tcgetattr(fd1, &options);  // Get the current options for the port...

  // Set the baud rates...
  cfsetispeed(&options, B9600);
  cfsetospeed(&options, B9600);

  // Enable the receiver and set local mode...
  options.c_cflag |= (CLOCAL | CREAD | CS8);
  options.c_cflag &= ~PARENB;  // ignore parity
  options.c_cflag &= ~CSTOPB;  // 1 stop bit (2 if set)
  options.c_cflag &= ~CSIZE;   // clear the size bits
  options.c_cflag &= ~CRTSCTS; //No hard flow control
  options.c_cflag &= ~HUPCL;   //Hang Up on last Close
  options.c_cflag |= CS8;      // reset the size to 8 bits / char
  options.c_cc[VMIN]=1;
  options.c_cc[VTIME] = 1;
  options.c_oflag = 0;
  options.c_lflag = 0;       //ICANON;
  // Set the new options for the port...
  tcsetattr(fd1, TCSANOW, &options);

  // test to make sure the characters are coming in on the port

  for (short i =0; i < 60; i++)
  {
    ret = read(fd1, buf, 32);
    buf[ret] = '\0';
    cout << buf;
    usleep(500);
  }

  fd_set         rfds;  // fd_set for the select call for com input

  FD_ZERO(&rfds);

  FD_SET(fd1, &rfds);


  cout << endl << "FD1 = " << fd1 << endl;

  while (1)
  {
    tv.tv_sec = 0;

    tv.tv_usec = 1000;

    ret = select(fd1 + 1, &rfds, NULL, NULL, &tv);


    if (ret > 0)

    {
      ret = read(fd1, buf, 127);
      buf[ret] = '\0';
      cout << buf;
    }
    usleep(500);
  }

  return 0;

}

1 个答案:

答案 0 :(得分:7)

在返回之前,select()修改rfds以指示哪些描述符已准备好读取数据。

在您的情况下,第一次在达到1ms超时后返回并且您的描述符上没有可用数据时,它将从rfds集中删除您的描述符以指示没有可用数据。然后,当你下次循环时再次调用select()时,rfds是一个空集,所以在那之后它甚至都不会再费心去检查你的描述符了。

每次进行循环选择之前,都需要调用FD_SET(fd1,&amp; rfds)。