【问题标题】:Serial read() does not return a value without data receivingSerial read() 不接收数据不返回值
【发布时间】:2018-01-21 03:19:30
【问题描述】:

我正在尝试使用带有串行连接的 read() 函数。

我用以下设置初始化串口:

bool HardwareSerial::begin(speed_t speed) {


    int USB = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);

    if (USB == 1) {

        std::cout << "\n  Error! in Opening ttyUSB0\n" << std::endl;
    } else {

        std::cout << "\n  ttyUSB0 Opened Successfully\n" << std::endl;
    }

    struct termios tty;
    struct termios tty_old;
    memset(&tty, 0, sizeof tty);

    // Error Handling
    if (tcgetattr(USB, &tty) != 0) {
        std::cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << std::endl;
    }

    //Save old tty parameters
    tty_old = tty;

    // Set Baud Rate 
    cfsetospeed(&tty, (speed_t) speed);
    cfsetispeed(&tty, (speed_t) speed);

    // Setting other Port Stuff 
    tty.c_cflag &= ~PARENB; // Make 8n1
    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;

    tty.c_iflag &= ~(IXON | IXOFF | IXANY);
    tty.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);

    tty.c_cflag &= ~CRTSCTS; // no flow control
    tty.c_cc[VMIN] = 1; // read doesn't block
    tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
    tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines

    // Make raw
    cfmakeraw(&tty);

    //Flush Port, then applies attributes
    tcflush(USB, TCIFLUSH);
    if (tcsetattr(USB, TCSANOW, &tty) != 0) {
        std::cout << "Error " << errno << " from tcsetattr" << std::endl;
    }

    _USB = USB;

    return true;

}

然后我定期调用调用流读取的类成员 read() 函数:

int HardwareSerial::read() {

    int n = 0;
    char buf;

    n = ::read(_USB, &buf, 1);

    std::cout << std::hex << static_cast<int> (buf) << " n:";
    std::cout << n << std::endl;

}

当端口接收数据时,read() 按预期工作并打印传入字节。但是如果我停止发送字节,程序就会挂起,直到一些字节没有收到。 我希望 ::read 将返回 0,但它不返回任何内容并等待传入​​数据。收到新数据后,程序继续工作, ::read 返回 1;

那么我在配置中遗漏了什么? 我尝试了不同的 VMIN 和 VTIME 但结果是一样的。

【问题讨论】:

    标签: c++ linux ubuntu serial-port


    【解决方案1】:

    您正在以阻塞方式从 USB 读取数据,例如如果没有可用数据,则调用被阻塞,并且在数据到达之前进程不会取得任何进展。

    除此之外,您可以将描述符设置为以NON-BLOCKING 模式读取,类似于以下内容:

    int flags = fcntl(_USB, F_GETFL, 0);
    fcntl(_USB, F_SETFL, flags | O_NONBLOCK)
    

    现在,你可以尝试阅读:

    int count;
    char buffer;
    count = read(_USD, buf, 1);
    // Check whenever you succeeded to read something
    if(count >=0) {
        // Data is arrived
    } else if(count < 0 && errno == EAGAIN) {
        // No Data, need to wait, continue, or something else.
    }
    

    您也可以使用select 函数检查设备描述符何时准备好读取。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      相关资源
      最近更新 更多