ramlife

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

转自: https://stackoverflow.com/questions/10522277/how-can-i-implement-timeout-for-read-when-reading-from-a-serial-port-c-c

Q

I am reading bytes from a serial port in C++ using a file descriptor and the posix/unix read() function. In this example, I am reading 1 byte from the serial port (baud rate settings and similiar are omitted for clarity):

#include <termios.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
   int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
   char buf[1];
   int bytesRead = read(fd, buf, 1);
   close(fd);
   return 0;
}

If the device connected to /dev/ttyS0 does not send any information, the program will hang. How can I set a timeout?

I have tried setting a time out like this:

struct termios options;
tcgetattr(fd, &options);
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
tcsetattr(fd, TCSANOW, &options);

I thought it was supposed to give 1 second timeout, but it makes no difference. I think I have misunderstood VMIN and VTIME. What is VMIN and VTIME used for?

Then I searched the web and found somebody talking about the select() function. Is that the solution and if so, how would one apply that to the program above to make 1 second timeout?

Any help is appreciated. Thanks in advance 😃

A

Yes, use select(2). Pass in a file descriptor set containing just your fd in the read set and empty write/exception sets, and pass in an appropriate timeout. For example:

int fd = open(...);

// Initialize file descriptor sets
fd_set read_fds, write_fds, except_fds;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&except_fds);
FD_SET(fd, &read_fds);

// Set timeout to 1.0 seconds
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;

// Wait for input to become ready or until the time out; the first parameter is
// 1 more than the largest file descriptor in any of the sets
if (select(fd + 1, &read_fds, &write_fds, &except_fds, &timeout) == 1)
{
    // fd is ready for reading
}
else
{
    // timeout or error
}
posted on 2020-03-06 13:21  ramlife  阅读(110)  评论(0编辑  收藏  举报