вызов select () не возвращается, когда символы на порту - PullRequest
1 голос
/ 28 августа 2009

У меня есть вызов select, который, кажется, не обнаруживает символы на последовательном порту. Есть ли что-то, что я пропускаю?

Если я удаляю код read (), который находится в блоке над блоком выбора, некоторое время будет возвращаться, пока не будет очищен существующий буфер порта, и больше ничего не будет обнаружено.

Я передаю символы на порт, а запущенный 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 Ответ

7 голосов
/ 28 августа 2009

Перед возвратом select () изменяет rfds, чтобы указать, какие дескрипторы имеют данные, готовые для чтения.

В вашем случае, когда он вернется в первый раз после истечения времени ожидания 1 мс, и в вашем дескрипторе нет данных, он удалит ваш дескриптор из набора rfds, чтобы указать, что данных нет. Затем, когда вы снова вызовете select () в следующий раз через цикл, rfds будет пустым набором, и после этого он даже не будет беспокоиться о проверке вашего дескриптора.

Вам нужно вызывать FD_SET (fd1, & rfds), прежде чем выбирать каждый раз, когда вы проходите цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...