【问题标题】:How can I setup a deadline_timer in this environment?如何在这种环境中设置截止时间计时器?
【发布时间】:2012-10-25 14:39:29
【问题描述】:

我有点迷失在图书馆的结构中,我不得不将它们纠缠在一起。我需要帮助才能在这个结构中引入一些计时器。

我有以下:

  • com.cpp 其中有 main 并包含 com.hpp
  • com.hpp 包含一个 host.h 并且需要的 boost 包含并定义了一个类 comClient
  • host.c 包含 host.h
  • wrapper.cpp 包含 com.hpp 和一些需要的提升包括

现在,我的 com.cpp 正在创建一个 comClient 并将其用于 com 端口上的异步通信。使用boost::asio::serial_portboost::asio::io_service

我需要使用一些计时器,以便捕捉数据包传输时间过长。

当创建comClient的实例时,paket-timer应该被初始化。

comClient的私有函数中使用asynch_read_some,我调用comClient的私有handler,然后这个handler调用host.c,它调用 wrapper.cpp 一个函数来重新启动计时器。

这是初始化定时器的函数:

//wrapper.cpp
void    IniPacketTimer(void *pCHandle){

    boost::asio::io_service io;
    boost::asio::deadline_timer t(io, boost::posix_time::milliseconds(25));
    t.async_wait(&hostOnTimeout(pCHandle));
    io.run();
}

这就是简单的命令链:

//comClient.cpp
main{
  comClient cc();
}
//comClient.hpp
class comClient(boost::asio::io_service& io_service){
  comClient(){
   hostInit();
   aread();
  }
  private:
    aread( call aread_done)
    areaddone(call hostNewData())
}

//host.c
hostInit(){ 
   IniPacketTimer()
}
hostNewData(){
  resetTimer
}

//wrapper.cpp
resetTimer(){
  t.expires_from_now
}

问题:

如何提供一个异步定时器,不影响我的串口的异步读/写操作,但在到达deadline时触发函数的执行?

我应该使用已经存在的io_service 还是可以,如果我只是创建另一个?

为什么我会收到错误 C2102 '&' expects L-Value for my line t.async_wait

【问题讨论】:

    标签: c++ boost timer boost-asio


    【解决方案1】:

    您的问题不清楚,并且由于您没有发布真实代码,因此很难猜测您的问题是什么。
    特别是您的线程不清楚,但对于 asio 非常重要。

    下面是一个可以编译但不运行的示例。我希望它能为您提供有关如何进行的提示。
    它将打开一个串行端口和一个计时器。每当计时器到期时,它将开始一个新的。这是我前段时间使用的代码的精简版本,所以也许它会对你有所帮助。

    #include <boost/asio.hpp>
    #include <boost/asio/serial_port.hpp>
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    #include <vector>
    
    
    class SerialCommunication
    {
        public:
        SerialCommunication(boost::asio::io_service& io_service, const std::string& serialPort)
            : m_io_service(io_service)
            , m_serialPort(m_io_service)
            , m_timeoutTimer(m_io_service, boost::posix_time::milliseconds(5))
        {
            configureSerialPort(serialPort);
        }
    
        void configureSerialPort(const std::string& serialPort)
        {
            if(m_serialPort.is_open())
            {
                m_serialPort.close();
                m_timeoutTimer.cancel();
            }
            boost::system::error_code ec;
            m_serialPort.open(serialPort, ec);
            if(m_serialPort.is_open())
            {
                // start Timer
                m_timeoutTimer.async_wait(boost::bind(&SerialCommunication::TimerExpired, this, _1));
                header_sync();
            }
        }
    
        void header_sync()
        {
            m_serialPort.async_read_some(boost::asio::buffer(&m_header.back(), 1),
                boost::bind(&SerialCommunication::header_sync_complete, this,
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));
        }
    
        void header_sync_complete(
            const boost::system::error_code& error, size_t bytes_transferred)
        {
            // stripped
            read_payload(&m_payload[0], 0);
        }
    
    
        void read_payload(uint8_t* buffer, uint8_t length)
        {
            m_serialPort.async_read_some(boost::asio::buffer(buffer, length),
                boost::bind(&SerialCommunication::payload_read_complete, this,
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));
        }
    
        void payload_read_complete(
            const boost::system::error_code& error, size_t bytes_transferred)
        {
            // stripped
            // timer cancel and reset
            m_timeoutTimer.cancel();
            m_timeoutTimer.expires_at(boost::posix_time::microsec_clock::local_time() +
                                boost::posix_time::milliseconds(5));
            m_timeoutTimer.async_wait(boost::bind(&SerialCommunication::TimerExpired, this, _1));
            memset(&m_header[0], 0, 3);
            header_sync();
        }
    
        void TimerExpired(const boost::system::error_code& e)
        {
            m_timeoutTimer.expires_at(m_timeoutTimer.expires_at() + boost::posix_time::milliseconds(5));
            m_timeoutTimer.async_wait(boost::bind(&SerialCommunication::TimerExpired, this, _1));
        }
    
        boost::asio::io_service& m_io_service;
        boost::asio::deadline_timer m_timeoutTimer;
        boost::asio::serial_port m_serialPort;
        std::vector<uint8_t> m_header;
        std::vector<uint8_t> m_payload;
    };
    
    
    
    int main()
    {
        boost::asio::io_service io_service;
        SerialCommunication cc(io_service, "/dev/ttyS0");
    
        io_service.run();
        return 0;
    }
    

    【讨论】:

    • 对不起,如果问题仍然有些不清楚。它有很多代码。我希望有一个你给出的例子,它似乎有相当正确的部分。现在我可以从中学习和适应。这需要一点时间 - 但非常感谢这段代码!
    • 嘿,感谢你和其他一些帖子,我终于让我的计时器有点工作了——只是不像预期的那样。这是我的后续问题:stackoverflow.com/questions/13089110/…。再次感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    相关资源
    最近更新 更多