【问题标题】:Linux serial port woesLinux串口问题
【发布时间】:2011-10-08 01:11:41
【问题描述】:

我正在编写代码以在 linux 中通过串行方式与另一台设备通信

即使有 0 个字符到达,我也希望不阻塞超时。 termios 结构体允许您设置 VTIME 和 VMIN,但如果 VMIN 大于 0,并且如果返回 0 个字符,则读取调用将永远阻塞... WTF,为什么。这似乎没有涵盖其他设备在短时间内停机并且现在我的应用程序在读取调用时被阻止的情况。这似乎是一个不容忽视的关键行为。我真的不想实现自己的超时。

Write command
Read block timeout of around .3s(if 0 characters, still wait max of .3s)

【问题讨论】:

    标签: linux serial-port


    【解决方案1】:

    如果您希望read 在超时后返回没有数据,您可以设置MIN == 0TIME > 0。来自tcsetattr(3)

    最小值 == 0; TIME > 0:TIME 以十分之一为单位指定计时器的限制 一秒。调用 read(2) 时启动计时器。阅读(2) 当至少一个字节的数据可用时返回,或者当 计时器到期。如果计时器到期而没有任何输入变为 可用,read(2) 返回 0。

    此模式可用于构建更高级别的通信功能,您必须实现这些功能以处理部分读取(即如果另一端在“数据包”中间崩溃)、错误数据包、拆分数据包等在。这就是简单的read 无法为您做的所有事情。

    【讨论】:

      【解决方案2】:

      看看select。它一直等到数据准备好读取(但实际上并不读取任何内容)。来自man page

      timeoutselect() 之前经过的时间量的上限 返回。它可能为零,导致 select() 立即返回。 (这是 对轮询有用。)如果 timeout 为 NULL(无超时),select() 可以阻塞 无限期。

      代码如下所示:

      struct timeval tv;
      tv.tv_sec = 0;
      tv.tv_usec = 300000;
      
      fd_set infds;
      FD_ZERO(&infds);
      FD_SET(fd, &infds);
      
      // Assume fd is the file descriptor for the serial device
      if (select(fd + 1, &infds, NULL, NULL, &tv) > 0)
      {
          // The read will not block now
          // Assume buffer and size are declared and set appropriately
          amountRead = read(fd, buffer, size);
      }
      

      【讨论】:

      • 你确定串口可以select()吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      相关资源
      最近更新 更多