【问题标题】:Linux - serial port read returning EAGAINLinux - 串口读取返回 EAGAIN
【发布时间】:2009-10-23 14:39:56
【问题描述】:

我在通过以下方式打开的串行端口读取一些数据时遇到了一些问题。我已经多次使用此代码实例并且一切正常,但现在,由于某种我无法弄清楚的原因,我完全无法从串行端口读取任何内容。

我可以写,并且在另一端正确接收到所有内容,但从未收到回复(正确发送)(不,电缆都正常;))

我用来打开串口的代码如下:

fd = open("/dev/ttyUSB0", O_RDWR | O_NONBLOCK | O_NOCTTY);
if (fd == -1)
{
    Aviso("Unable to open port");
    return (fd);
}
else
{
    //Get the current options for the port...
    bzero(&options, sizeof(options)); /* clear struct for new port settings */
    tcgetattr(fd, &options);

    /*-- Set baud rate -------------------------------------------------------*/
    if (cfsetispeed(&options, SerialBaudInterp(BaudRate))==-1)
        perror("On cfsetispeed:");
    if (cfsetospeed(&options, SerialBaudInterp(BaudRate))==-1)
        perror("On cfsetospeed:");

    //Enable the receiver and set local mode...
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB; /* Parity disabled */
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;  /* Mask the character size bits */
    options.c_cflag |= SerialDataBitsInterp(8);           /* CS8 - Selects 8 data bits */
    options.c_cflag &= ~CRTSCTS;                            // disable hardware flow control
    options.c_iflag &= ~(IXON | IXOFF | IXANY);           // disable XON XOFF (for transmit and receive)
    options.c_cflag |= CRTSCTS;                         /* enable hardware flow control */
    
    options.c_cc[VMIN] = 0;     //min carachters to be read
    options.c_cc[VTIME] = 0;    //Time to wait for data (tenths of seconds)

    //Set the new options for the port...
    tcflush(fd, TCIFLUSH);
    if (tcsetattr(fd, TCSANOW, &options)==-1)
    {
        perror("On tcsetattr:");
    }

    PortOpen[ComPort] = fd;
}

return PortOpen[ComPort];

端口初始化后,我通过简单的写入命令向它写入一些东西...

int nc = write(hCom, txchar, n);

其中 hCom 是文件描述符(没关系),并且(正如我所说)这有效。但是......当我之后阅读时,我从 errno 收到“资源暂时不可用”错误。

我测试了 select 以查看文件描述符何时有未读取的内容...但它总是超时!

我这样读取数据:

ret = read(hCom, rxchar, n);

我总是得到一个 EAGAIN,但我不知道为什么。

更新:

硬件工作正常!我可以看到串行端口上有入站数据,因为我制作了一条调试电缆来读取另一个终端上发生的事情。所以...

我知道非阻塞应该做什么。我的问题是......为什么没有任何内容被阅读!相同的设置在 Windows 上运行良好,因此所有硬件都运行良好...

这快把我逼疯了!我敢肯定这很简单!我什至尝试摆脱 O_NONBLOCK 看看我什么时候会收到一些东西......但是什么都没有......

【问题讨论】:

  • 我也有同样的问题。我可以发送但不能接收(通过 USB-RS232 适配器电缆)。我尝试了另一个具有 RS232 端口的 linux 机器,它工作得很好。我所做的唯一更改是从/dev/ttyUSB0/dev/ttyS0。第一台电脑是 Fedora,第二台是 Debian。除此之外,不知道。另一件事。当我关闭 com 程序并重新启动它时,我的程序会读取数据!数据是输入缓冲区,但我的程序不知道。此外,gtkterm 工作正常,所以硬件一切正常。我的程序没有看到 UART 中断。这个 linux h/w 抽象层相当混乱

标签: c linux serial-port


【解决方案1】:

阅读this

EAGAIN 非阻塞 I/O 已 使用 O_NONBLOCK 选择并且没有数据 立即可供阅读。

【讨论】:

  • 这正是问题所在,如果有点简洁的话。我想更广泛的问题是,如果您不准备处理它的行为,为什么要指定 O_NONBLOCK?
【解决方案2】:

您需要先检查串口终端设置。

使用命令- stty -F /dev/ttyUSB0 -a

检查ctsrts 是否被选为-ctsrts 并使用stty 实用程序进行其他必需的设置,您就完成了。

【讨论】:

    【解决方案3】:

    EAGAINO_NONBLOCK 表示端口上没有接收到数据。检查端口和电缆是否正常工作(使用 minicom 或其他已知良好的程序),以及遥控器是否确实在发送一些数据。

    【讨论】:

      【解决方案4】:

      查看我的代码示例,如果 EAGAIN,您会尝试再次阅读:

      ...
      options.c_cflag &= ~PARENB; 
      options.c_iflag &= ~INPCK; 
      ...
      options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // input
      options.c_oflag &= ~OPOST; // output
      ...
      fd = open("/dev/ttyUSB0", O_RDWR | O_NDELY | O_NOCTTY);
      fcntl(fd, F_SETFL, 0);
      ...
      int nc = write(hCom, txchar, n);
      msleep(500); // wait 500ms
      fcntl(hCom, F_SETFL, FNDELAY); // don't block serial read
      ret = read(hCom, rxchar, n);
      if (ret > 0) {
          here had read n bytes or just partial data, read again if partial.
      } 
      if (ret < 0) {
          if (EAGAIN == errno) {
              not a real error, just read again.
          } else {
              oops, errors.
          }
      }
      ...
      

      【讨论】:

      • 去过那里 ;) 循环检查。然后使用 select 来检查数据何时可用......我能记住的所有......我试过了;)
      • 零调制解调器电缆或外部环回电缆?如果是后者,引脚分配情况如何?
      • 只是将 RS232 端口的 Tx 和 Rx 焊接到另一个,然后在另一台机器上从 hyperterm 中读取它
      • 好吧,我的代码已经在外部环回情况和 c 代码与超术语情况下进行了测试和工作。没有NONBLOCK但在写入时等待(500ms)如何使用,并在阅读之前设置FNDELAY,就像我的代码一样?如果仍然不适合你,我也不知道。
      • 抱歉,除了#2-#3 和#3-#2 之外,您是否也尝试将引脚#5 连接在一起?在 PC-PC 情况下需要声音 #5。
      猜你喜欢
      • 1970-01-01
      • 2018-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-09
      • 2015-12-31
      相关资源
      最近更新 更多