c++ - Linux C++ 读取 UART 设备工作不一致

标签 c++ linux serial-port beagleboneblack uart

我正在使用 BeagleBone Black 通过 UART 端口读取来自微 Controller 的数据。我需要读取 UART 端 Eloquent 能成为阻塞调用。此外,对于此软件的使用,将使用一些非标准波特率(也不是由 termios 提供)。此外,UART 应遵循 8-N-1(8 个数据位,无奇偶校验,1 个停止位)。

我打开串口的代码如下:

int UART::UART_open(unsigned int baudRate) 
{
    mFd = open(mPath.c_str(), O_RDWR | O_NOCTTY);
    if(mFd < 0)
    {
        return -1;
    }

    struct termios2 tty;

    if(ioctl(mFd, TCGETS2, &tty) == -1)
    {
        return -1;
    }

    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 5;
    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
    tty.c_cflag &= ~CBAUD;
    tty.c_cflag |= (BOTHER | CREAD | CLOCAL);
    tty.c_ispeed = baudRate;
    tty.c_ospeed = baudRate;

    if(ioctl(mFd, TCSETS2, &tty) == -1)
    {
        return -1;
    }

    return 0;
}

我读取串口的代码如下:

int UART::UART_read(unsigned char* buf, int length)
{
    if(mFd < 0)
    {
        return -1;
    }
    if(read(mFd, buf, length) != length)
    {
        return -1;
    }
    return length;
}

发生了一些奇怪的行为。发生的情况是,读数不一致。有时,当我使用 Mbed 微 Controller 通过 UART 将数据连续(中间有小延迟)发送到正确的端口,以及一个测试程序连续读取 BeagleBone Black 上的 UART 端口并打印出它获得的数据时,它进行了测试工作正常,我能够打印出发送的数据,一切都按预期进行。然而,经常发生的是第一次读取只是永远阻塞。这些函数没有发生错误,UART_read 函数只是挂起。因此,为了调试错误,我做的第一件事是使用“屏幕”来监视我尝试读取的/dev/ttyO* 端口。我发现数据被发送到那个端口就好了。然后,奇怪的是,在我使用屏幕后,如果我运行我的测试程序来连续读取 UART 端口,它工作正常。这种情况也一直发生,如果我在端口不工作时快速“屏蔽”它,我看到正在发送数据,那么我的测试程序就可以工作。我尝试更改一些打开的 termios2 结构选项,但无济于事。任何帮助将不胜感激!

最佳答案

您的 termios 初始化显然不完整。原始模式有部分配置,例如

tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 5;

但您从未真正启用非规范模式。

read()“永远阻塞” 行为是串行终端(错误)配置为规范模式的症状,当仅接收到二进制数据时(即有没有行终止符来“完成”请求)。

“永远阻塞” 行为的另一个可能原因是在不使用时未能禁用硬件流控制。

插入以下语句将启用非规范模式并禁用 HW 握手:

cfmakeraw(&tty);
tty.c_cflag &= ~CRTSCTS;

引用this answer一个完整的例子。


if(read(mFd, buf, length) != length)
{
    return -1;
}

不要求串行终端的read() 填充缓冲区。根据配置,“成功”读取可以返回零个或多个字节,直至达到请求的数量。 因此,短读取实际上并不是错误情况。

关于c++ - Linux C++ 读取 UART 设备工作不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50282910/

相关文章:

c++ - 调用 Gdiplus::PrivateFontCollection.AddMemoryFont 时出现访问冲突错误

c++ - sendto : no error code [was: raw socket error with sendto: no such device] 的原始套接字错误

linux - 通过在端口 443 上使用 ssh 避免流量整形

c++ - 计算最大利润的代码

c++ - 我什么时候在 C++ 中使用 const volatile、register volatile、static volatile?

c++ - 以十六进制打印出 DWORD 在 win32 c++ 中返回 0x7FFFFFFF

linux - 创建一个虚假的现实 : Testing Using Virtual Block Devices

c++ - Unix:如何清除串口I/O缓冲区?

Linux串口1.5停止位

java - 从 Arduino 读取串行数据