【问题标题】:Linux serial port I/O questionLinux串口I/O问题
【发布时间】:2011-02-04 15:42:41
【问题描述】:

在以下用于嵌入式设备的 C 程序中,每次用户在通过串行电缆连接到我的设备的远程计算机上在其终端程序上输入一些字符时,我都会尝试显示一个点(“.”)并按 ENTER 键。

我看到的是,一旦检测到第一个回车,printf 就会在无限循环中显示点。我期待 FD_ZERO 和 FD_CLR 来“重置”等待条件。

怎么做?

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>

main()
{
    int    fd1;       /* Input sources 1 and 2 */
    fd_set readfs;    /* File descriptor set */
    int    maxfd;     /* Maximum file desciptor used */
    int    loop=1;    /* Loop while TRUE */

    /*
       open_input_source opens a device, sets the port correctly, and
       returns a file descriptor.
    */
    fd1 = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd1<0)
    {
        exit(0);
    }

    maxfd =fd1+1;  /* Maximum bit entry (fd) to test. */

    /* Loop for input */
    while (loop)
    {
        FD_SET(fd1, &readfs);  /* Set testing for source 1. */

        /* Block until input becomes available. */
        select(maxfd, &readfs, NULL, NULL, NULL);

        if (FD_ISSET(fd1, &readfs))
        {
            /* input from source 1 available */
            printf(".");
            FD_CLR(fd1, &readfs);
            FD_ZERO( &readfs);
        }
    }
}

【问题讨论】:

  • 你试过查看select()的返回值吗?

标签: linux embedded serial-port


【解决方案1】:

所有FD_CLRFD_ZERO 都会重置fd_set,它不会清除底层条件。为此,您需要read()所有数据,直到没有可用数据为止。

实际上,如果您一次只想执行一个 fd,最好完全放弃 select(),而只需使用阻塞 read() 来查看数据何时可用。

在旁注中,FD_ZEROFD_CLR 做同样的事情,但对于所有 fds。如果你做一个,你就不需要另一个。

【讨论】:

  • 然后下一个循环迭代再次执行FD_SET,撤消FD_CLR
  • 并且不要忘记在每个 printf 之后fflush(stdout),否则您将看不到点。
【解决方案2】:

首先,使用正确的函数头,例如int main(void)。其次,FD_SET有存储fds的上限,也就是说不是所有的fds都可以用select监控。 (poll 没有这个限制。)

第三也是最后,在您的循环中,您只检查 fd 上是否有可用数据,但您从未读取过它。因此,它会在下一次迭代中继续可用。

【讨论】:

    猜你喜欢
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多