使用Boost Asio从串行端口读取消息 [英] Reading messages from a serial port with Boost Asio

查看:81
本文介绍了使用Boost Asio从串行端口读取消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用提升Asio 来读取序列中的可变长度消息港口.我想阅读并等待足够长的时间,以确保线路空闲,但我不想完全阻塞.

I would like to use Boost Asio to read variable length messages from the serial port. I would like to read and wait long enough to be sure that the line is idle, but I do not want to block completely.

以下是我到目前为止的代码,我正在对其进行测试:

The following code is what I have so far, and I am in the process of testing it:

long readData(void *_pData, unsigned long _uSize, size_t millis)
{
    size_t n = 0;    // n will return the message size.
    if (millis > 0)  // millis is the acceptable idle time, 0 is invalid in my case.
    {
        size_t uBytesTransferred = 0;
        boost::asio::deadline_timer timeout(m_ioService);
        ReadCallback readCallback(uBytesTransferred, timeout);
        WaitCallback waitCallback(m_port);

        while (_uSize - (unsigned long)n > 0)
        {
            // Setup asynchronous read with timeout
            m_ioService.reset();
            m_port.async_read_some(boost::asio::buffer((char*)_pData + n, _uSize - (unsigned long)n), readCallback);
            timeout.expires_from_now(boost::posix_time::milliseconds(millis));
            timeout.async_wait(waitCallback);

            // Block until asynchronous callbacks are finished
            m_ioService.run();

            // Continue if any bytes were received, stop otherwise
            if (uBytesTransferred > 0)
            {
                n += uBytesTransferred;
                m_uBytesReceived += uBytesTransferred;
            }
            else
            {
                break;
            }
        }
    }
    return n;
}

我想知道这是使用Boost Asio执行此操作的正确方法(即读取直到该行空闲)吗?

I would like to know if this is the correct way of doing this (that is, reading until the line is idle) with Boost Asio?

这是我的回调处理程序:

Here are my callback handlers:

struct ReadCallback
{
    ReadCallback(std::size_t &_uBytesTransferred, boost::asio::deadline_timer &_timeout)
        :m_uBytesTransferred(_uBytesTransferred), m_timeout(_timeout)
    {}

    void operator()(const boost::system::error_code &_error, std::size_t _uBytesTransferred)
    {
        m_uBytesTransferred = _uBytesTransferred;
        if (!_error && (_uBytesTransferred > 0) )
        {
            m_timeout.cancel();
        }
    }

    std::size_t                        &m_uBytesTransferred;
    boost::asio::deadline_timer        &m_timeout;

    private:
        ReadCallback();
        ReadCallback &operator=(const ReadCallback&);
};

struct WaitCallback
{
    WaitCallback(boost::asio::serial_port &_port)
        :m_port(_port)
    {}

    void operator()(const boost::system::error_code &_error)
    {
        if (!_error)
        {
            m_port.cancel();
        }
    }

    boost::asio::serial_port &m_port;

    private:
        WaitCallback();
        WaitCallback &operator=(const WaitCallback&);
};

推荐答案

现在使用增强线程从串行端口读取和缓冲数据.现在,我可以将串行数据读取为流,而且还可以窥视,执行非阻塞和阻塞读取.

Now using a boost thread to read and buffer the data from the serial port. I can now read the serial data as a stream, but also have the ability to peek, do non-blocking and blocking reads.

我将串行io包装在boost线程中-只是无法使asio回调按我想要的方式工作.我现在正在缓冲线程中的读取数据,但仍使用阻塞写入来将等待时间保持在尽可能低的水平.

I wrapped the serial io in a boost thread -- just couldn't make the asio callbacks work the way I wanted. I'm now buffering the read data in the thread, but still using blocking writes to keep the latency as low as possible.

这篇关于使用Boost Asio从串行端口读取消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆