CSerialPort自动重连机制

在工作中,从事软硬件工作的小伙伴经常会用到串口通信,尤其是windows系统下,传输消息。笔者前段时间做的麦克风阵列上的本地AI引擎(ASR、TTS、NLP)用于语音交互,其中的结果通过串口协议发送给PC机上,在Github找了个两个串口模块,分别是WzSerialPort和CSerialPort,二者均封装了Windows的API,从工程化程度和使用对比看,CSerialPort更优。主要是因为WzSerialPort在调试中经常出现偶现的报错,没有具体去分析原因。
在使用CSerialPort的过程中,希望能实现串口自动重连,实现热插拔功能,官方也是将该功能放在TODO List中,但是尚未实现,笔者就从上层实现了一个热插拔功能。

主要的原理是通过接口异常来检测串口是否异常,开启线程读取串口数据,如果读取失败,则认为串口异常,重启串口。
1.放弃使用样例中的信号-槽模式,他是通过回调的方式来通知接收串口数据,在异常场景下,该回调无法被触发
2.写接口调用时间不确定,无法及时获取串口异常信息,故采用读接口

主要实现方法如下:
开启线程开实时读取串口消息

// 启动时开启线程
  ...
  boost::function0<void> f_run = boost::bind(&serial::run, this);
  run_thread_ = new boost::thread(f_run);
  ...
  
  // 线程函数
  void serial::run() {
        int ret = HY_SUCCESS;
        char str[10240] = { 0 };      // 大小可适当放大点,防止读取数据超过buffer

        while (!exit_flag_) {
              //read
              int recLen = com_->readAllData(str);

              if (recLen > 0)
              {
                    std::string msg(str, recLen);
                    LOG->information("serial::run | receive com port msg : %s", msg);      // 日志信息

                    // WS::get_mutable_instance().send_msg(msg);      // 消息处理,笔者通过websocket发送给客户端
              }
              else if (recLen < 0){
                    reset_serial();
                    LOG->information("serial::run | reset com port");
              }
        }
  }

  // reset 
  int serial::reset_serial() {
        if (com_) {
              com_->close();

              int ret = open_port();      // 具体方法自行实现
              if (ret != HY_SUCCESS) {
                    LOG->error("serial::run | restart com port failed, ret = %d", ret);

                    boost::thread::sleep(boost::get_system_time() + boost::posix_time::seconds(5));      // 防止频繁调用,占用CPU
              }
              else {
                    LOG->information("serial::run | restart com port success");
              }
        }

        return HY_SUCCESS;
  }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值