异步提升读取串行端口

Reading a Serial Port Asynchronously Boost

本文关键字:串行端口 读取 异步      更新时间:2023-10-16

我正在尝试从串行端口异步读取几个字节。目前我正在使用的代码(源代码是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();
}

read_callback中,取消计时器,不开始新的读取
那么你希望ASIO做什么呢?你刚刚取消了所有的处理程序,就像文档中的状态一样,当没有处理程序时,run方法将返回。

因此,如果你想拥有比收到的一个字节更多的数据,你可以做两件事:
首先,只需向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来至少获得所需的数据量。