异步读取串口 Boost

3
我正在尝试异步地从串口读取几个字节。目前我正在使用的代码(源自How do I perform a nonblocking read using asio?)只允许我读取1个字节,然后就退出了。如何让代码一直读取,直到串口中没有更多的传入数据呢?谢谢 :)
    void foo()
{
    boost::asio::io_service io_svc;
    boost::asio::serial_port ser_port(io_svc, "/dev/ttyS0");
    boost::asio::deadline_timer timeout(io_svc);
    unsigned char my_buffer[2];
    bool data_available = false;

    ser_port.async_read_some(boost::asio::buffer(my_buffer),
            boost::bind(&read_callback, boost::ref(data_available),
                    boost::ref(timeout),boost::asio::placeholders::error(),
                    boost::asio::placeholders::bytes_transferred()));
    timeout.expires_from_now(boost::posix_time::seconds(30));
    timeout.async_wait(boost::bind(&wait_callback, boost::ref(ser_port),boost::asio::placeholders::error()));

    io_svc.run();

    io_svc.

    if(!data_available)
    {
        ser_port.close();
        cout << "ser_port was closed";
    }

}

void read_callback(bool& data_available, boost::asio::deadline_timer& timeout, const boost::system::error_code& error, std::size_t bytes_transferred)
{
    if (error || !bytes_transferred)
    {
        // No data was read!
        data_available = false;
        return;
    }

    timeout.cancel();
    data_available = true;
}

void wait_callback(boost::asio::serial_port& ser_port, const boost::system::error_code& error)
{
    if (error)
    {
        // Data was read and this timeout was cancelled

        return;
    }

    ser_port.cancel();
}
1个回答

3
在你的read_callback中,你取消了计时器并且没有开始新的读取操作。
那么你希望ASIO做什么呢?你刚刚取消了所有的处理程序,就像文档所述,当没有处理程序时,运行方法将返回。
因此,如果你想要获取比接收到的一个字节更多的数据,你可以做两件事情:
首先,只需发出另一个调用以从端口读取更多数据。
void read_callback(bool& data_available, boost::asio::deadline_timer& timeout, const  boost::system::error_code& error, std::size_t bytes_transferred)
{
    if (error || !bytes_transferred)
    {
        // No data was read!
        data_available = false;
        return;
    }
    // do something with the data you just read
    ser_port.async_read_some(boost::asio::buffer(my_buffer),
        boost::bind(&read_callback, boost::ref(data_available),
                boost::ref(timeout),boost::asio::placeholders::error(),
                boost::asio::placeholders::bytes_transferred()));
    //restart your timer
    data_available = true;
}

您可以使用transfer_at_least来获取至少所需数据的数量。


好的,太棒了。既然这个函数中未定义串口和缓冲区,那么我应该在主函数中初始化它们吗? - user2554193
@user2554193,你可以在主函数中完成,并将指向端口/缓冲区的指针传递给回调函数。或者你可以将它们作为成员放入一个类中,并绑定到成员函数上。 - mkaes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接