读取串行端口异步升压

时间:2023-02-10 15:10:33

I am trying to read several bytes asynchronously from a serial port. Currently the code I am using (source is How do I perform a nonblocking read using asio?), only allows me to read 1 byte and then it exits. How do I get it so that the code keeps reading until there is no more incoming data in the serial port? Thanks :)

我试图从串口异步读取几个字节。目前我正在使用的代码(源代码是如何使用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 个解决方案

#1


3  

In your read_callback you cancel your timer and do not start a new read.
So what do you expect ASIO to do. You just canceled all handlers and like the documentation states, the run method will return when no handlers are left.

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

So if you want to have more data than just the one byte you receive you can do two things:
First just issue another call to asio to read more from the port.

因此,如果您希望获得的数据多于您收到的一个字节,则可以执行以下两项操作:首先,只需再发出一次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;
}

or you can add use transfer_at_least to get at least the amount of data you need.

或者您可以添加使用transfer_at_least以获得至少所需的数据量。

#1


3  

In your read_callback you cancel your timer and do not start a new read.
So what do you expect ASIO to do. You just canceled all handlers and like the documentation states, the run method will return when no handlers are left.

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

So if you want to have more data than just the one byte you receive you can do two things:
First just issue another call to asio to read more from the port.

因此,如果您希望获得的数据多于您收到的一个字节,则可以执行以下两项操作:首先,只需再发出一次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;
}

or you can add use transfer_at_least to get at least the amount of data you need.

或者您可以添加使用transfer_at_least以获得至少所需的数据量。