繁体   English   中英

Linux - 串口读取返回EAGAIN

[英]Linux - serial port read returning EAGAIN

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

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

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

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得到一个“暂时不可用的资源”错误。

我测试了选择以查看文件描述符何时读取...但它总是超时!

我读了这样的数据:

ret = read(hCom, rxchar, n);

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

更新:

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

我知道非阻塞应该做什么。 我的问题是......为什么不读任何东西! 相同的设置在Windows上工作正常,所以所有硬件都工作正常...

这让我疯了! 我确定这很简单! 我甚至试图摆脱O_NONBLOCK,看看我什么时候收到东西......但没有......

这个

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

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

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

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

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

看到我的代码示例,如果是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.
    }
}
...

我有着同样的问题。 我可以发送但不接收(通过USB-RS232适配器电缆)。 我尝试了另一个有RS232端口的linux机箱,它运行得很好。 我做的唯一更改是从/dev/ttyUSB0/dev/ttyS0 第一台计算机是Fedora,第二台是Debian。 除此之外,idunno。

另一件事。 当我关闭com程序并重新启动它时,我的程序会读取数据! 数据是输入缓冲区,但我的程序不知道它。 另外,gtkterm运行正常,所以h / w都可以。 我的程序没有看到UART中断。

这个linux h / w抽象层是相当虚伪的。 这应该不是问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM