读取串行端口异步升压

时间:2013-07-09 15:01:12

标签: c++ eclipse boost serial-port boost-asio

我试图从串口异步读取几个字节。目前我使用的代码(源是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 个答案:

答案 0 :(得分:3)

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以获得至少所需的数据量。