鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    fish_protocol串口使用问题

    已定时 已固定 已锁定 已移动 已解决
    综合问题
    ros2 fishprotocol 串口
    3
    3
    417
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • 31520790703
      。。。
      最后由 编辑

      fish_protocol
      里面的普通串口如何在节点里面创建而且在话题回调里面调用发送啊

      小鱼小 1 条回复 最后回复 回复 引用 0
      • senS
        Sen @小鱼
        最后由 小鱼 编辑

        @小鱼 @3152079070 之前的仓库已无法访问,小鱼串口文件没办法上传附件我直接贴在下面,这个串口文件目前只有串口,没有了tcp、udp等功能,酌情使用。```
        proto_utils.cpp

        /**
         * @brief 文件描述:协议处理工具,打印、crc、转义与反转义
         * @author 小鱼 (fishros@foxmail.com)
         * @version V1.0.0
         * @date 2022-07-17
         * @copyright 版权所有:FishBot Open Source Organization
         */
        
        #include "fish_protocol/protocol_util.h"
        #include <iostream>
        namespace fish_protocol {
        using namespace std;
        
        // ------------------------查表法crc8校验-------
        static const uint8_t  crc8tab[] = 
        {0x00,0x5e,0xbc,0xe2,0x61,0x3f,0xdd,0x83,0xc2,0x9c,0x7e,0x20,0xa3,0xfd,0x1f,0x41,
        0x9d,0xc3,0x21,0x7f,0xfc,0xa2,0x40,0x1e,0x5f,0x01,0xe3,0xbd,0x3e,0x60,0x82,0xdc,
        0x23,0x7d,0x9f,0xc1,0x42,0x1c,0xfe,0xa0,0xe1,0xbf,0x5d,0x03,0x80,0xde,0x3c,0x62,
        0xbe,0xe0,0x02,0x5c,0xdf,0x81,0x63,0x3d,0x7c,0x22,0xc0,0x9e,0x1d,0x43,0xa1,0xff,
        0x46,0x18,0xfa,0xa4,0x27,0x79,0x9b,0xc5,0x84,0xda,0x38,0x66,0xe5,0xbb,0x59,0x07,
        0xdb,0x85,0x67,0x39,0xba,0xe4,0x06,0x58,0x19,0x47,0xa5,0xfb,0x78,0x26,0xc4,0x9a,
        0x65,0x3b,0xd9,0x87,0x04,0x5a,0xb8,0xe6,0xa7,0xf9,0x1b,0x45,0xc6,0x98,0x7a,0x24,
        0xf8,0xa6,0x44,0x1a,0x99,0xc7,0x25,0x7b,0x3a,0x64,0x86,0xd8,0x5b,0x05,0xe7,0xb9,
        0x8c,0xd2,0x30,0x6e,0xed,0xb3,0x51,0x0f,0x4e,0x10,0xf2,0xac,0x2f,0x71,0x93,0xcd,
        0x11,0x4f,0xad,0xf3,0x70,0x2e,0xcc,0x92,0xd3,0x8d,0x6f,0x31,0xb2,0xec,0x0e,0x50,
        0xaf,0xf1,0x13,0x4d,0xce,0x90,0x72,0x2c,0x6d,0x33,0xd1,0x8f,0x0c,0x52,0xb0,0xee,
        0x32,0x6c,0x8e,0xd0,0x53,0x0d,0xef,0xb1,0xf0,0xae,0x4c,0x12,0x91,0xcf,0x2d,0x73,
        0xca,0x94,0x76,0x28,0xab,0xf5,0x17,0x49,0x08,0x56,0xb4,0xea,0x69,0x37,0xd5,0x8b,
        0x57,0x09,0xeb,0xb5,0x36,0x68,0x8a,0xd4,0x95,0xcb,0x29,0x77,0xf4,0xaa,0x48,0x16,
        0xe9,0xb7,0x55,0x0b,0x88,0xd6,0x34,0x6a,0x2b,0x75,0x97,0xc9,0x4a,0x14,0xf6,0xa8,
        0x74,0x2a,0xc8,0x96,0x15,0x4b,0xa9,0xf7,0xb6,0xe8,0x0a,0x54,0xd7,0x89,0x6b,0x35};
        
        uint8_t getcrc8tab(const uint8_t *buf, int len) {
          uint8_t crc = 0x00;
          while(len--)
          {
            crc = crc8tab[crc ^ *buf++];
          }
          return crc;
        }
        /****************************
        函数功能:直接计算法获得8位循环冗余校验值
        入口参数:数组地址、长度
        出口参数:校验值
        ******************************/
        uint8_t getCrc8(uint8_t *ptr, uint16_t len)
        {
            uint8_t crc, i;
            crc = 0;
            while(len--)
            {
                crc ^= *ptr++;
                for(i = 0; i < 8; i++)
                {
                    if(crc&0x01)
                        crc=(crc>>1)^0x8C;
                    else 
                        crc >>= 1;
                }
            }
            return crc;
        }
        
        int frame_packing(const uint8_t *buf, uint8_t *frame, uint8_t len, uint8_t func) {
            uint8_t cnt = 0;
            frame[cnt++] = FIRST_CODE;
            frame[cnt++] = func;
            frame[cnt++] = len;
            for (int i = 0; i < len; i++) {
                frame[cnt++] = buf[i];
            }
            frame[cnt++] = getcrc8tab(buf, len);
            frame[cnt++] = END_CODE;
            return cnt;
        }
        
        int inverse_frame(uint8_t *result, const uint8_t *frame, uint8_t len, uint8_t& func) {
            if((frame[0] != FIRST_CODE) || (frame[len - 1] != END_CODE))//  检查帧头帧尾
                return 0;
            for(int i = 3; i < len-2; i++)
            {
                result[i - 3] = frame[i];
            }
            if(getcrc8tab(result, frame[2]) != frame[len - 2])//    检查crc8校验
                return 0;
            func = frame[1];
            return frame[2];
        }
        
        
        }  // namespace fish_protocol
        

        serial_protocol.cpp

        
        /**
         * @brief 文件描述:待完善
         * @author 小鱼 (fishros@foxmail.com)
         * @version V1.0.0
         * @date 2022-07-24
         * @copyright 版权所有:(鱼香ROS)fishros.org.cn
         */
        #include "fish_protocol/serial_protocol.h"
        
        
        namespace serial_protocol {
        
        
        /// @brief Flush a serial port's buffers.
        ///
        /// @param serial_port Port to flush.
        /// @param what Determines the buffers to flush.
        /// @param error Set to indicate what error occurred, if any.
        void SerialProtocol::flush_serial_port(
                boost::asio::serial_port& serial_port,
                flush_type what,
                boost::system::error_code& error)
        {
            if (0 == ::tcflush(serial_port.lowest_layer().native_handle(), what))
            {
                error = boost::system::error_code();
            }
            else
            {
                error = boost::system::error_code(errno,
                    boost::asio::error::get_system_category());
            }
        }
        
        SerialProtocol::~SerialProtocol()
        {
            io_service_.stop();
            serial_port_.cancel();
            serial_port_.close();
        }
        void SerialProtocol::_initSerialProtocol() {
            boost::system::error_code ec;
            try
            {
                serial_port_.open(protocol_config_.serial_address_, ec);
                if(!serial_port_.is_open())
                    throw ec;
            }
            catch(boost::system::error_code& ec)
            {
                std::cout << ec.message() << std::endl;
                return ;
            }
            std::cout << "串口已打开:" << protocol_config_.serial_address_ << std::endl;
            serial_port_.set_option(spb::baud_rate(protocol_config_.serial_baut_));
            serial_port_.set_option(spb::character_size(8));
            serial_port_.set_option(spb::stop_bits(spb::stop_bits::one));
            serial_port_.set_option(spb::parity(spb::parity::none));
            serial_port_.set_option(spb::flow_control(spb::flow_control::none));
            boost::thread td(boost::bind(&boost::asio::io_service::run, &io_service_));
            _asyncReadSomeData();
        }
        
        void SerialProtocol::_recvDataCallback(const boost::system::error_code& error,
                                                size_t bytes_transferred) {
            if (bytes_transferred > 0) {
                // 回调数据
                if(recv_uint8_callback)
                {
                    recv_uint8_callback(recv_data_buffer_, bytes_transferred);
                }
            }
            _asyncReadSomeData();
        }
        
        void SerialProtocol::_asyncReadSomeData() {
            serial_port_.async_read_some(
                boost::asio::buffer(recv_data_buffer_, sizeof(recv_data_buffer_)),
                boost::bind(&SerialProtocol::_recvDataCallback, this,
                            boost::placeholders::_1, boost::placeholders::_2));
        
        }
        
        int SerialProtocol::ProtocolSendString(const std::string& data) {
            serial_port_.write_some(boost::asio::buffer(data.data(), data.size()));
            return 0;
        }
        int SerialProtocol::ProtocolSenduint8_t(const std::uint8_t* data, const std::uint8_t len) {
            serial_port_.write_some(boost::asio::buffer(data, len));
            return 0;
        }
        
        void SerialProtocol::SetDataRecvCallback(
                std::function<void(const std::uint8_t*, const std::uint8_t)> callback) {
            recv_uint8_callback = callback;
        }
        
        
        }  // namespace fish_protocol
        
        

        protocol_util.h

        
        /**
         * @brief 文件描述:待完善
         * @author 小鱼 (fishros@foxmail.com)
         * @version V1.0.0
         * @date 2022-07-24
         * @copyright 版权所有:(鱼香ROS)fishros.org.cn
         */
        #ifndef _FISH_PROTOCOL_PROTO_UTIL_H_
        #define _FISH_PROTOCOL_PROTO_UTIL_H_
        
        #include <cstdint>
        #include <cstdio>
        namespace fish_protocol {
        
        #define FIRST_CODE 0x55
        #define END_CODE 0xBB
        
        
        
        /**
         * @brief 截取指定位数据并赋值
         *        小端模式: 高位在前(低内存),低位在后(高内存)
         *
         */
        #define SET_SUB_BYTES1(target, data) target = (data & 0xFF)
        #define SET_SUB_BYTES2(target, data) target |= ((data << 8) & 0xFF00)
        
        /**
         * @brief 查表法crc8校验
         *
         * @param buf 输入数组
         * @param len 数组长度
         * @return uint8_t
         */
        uint8_t getcrc8tab(const uint8_t *buf, int len);
        
        /**
         * @brief 直接计算法crc8校验
         *
         * @param buf 输入数组
         * @param len 数组长度
         * @return uint8_t
         */
        uint8_t getCrc8(const uint8_t *buf, int len);
        
        /**
         * @brief 将数据进行转义
         *
         * @param frame 帧数据
         * @param result 结果
         * @param len 长度
         * @return int 转义完成后新的帧的大小
         */
        int frame_packing(const uint8_t *buf, uint8_t *frame, uint8_t len, uint8_t func);
        
        /**
         * @brief 将数据帧进行反转义
         *
         * @param frame 帧数据
         * @param result 结果
         * @param len 长度
         * @return int
         */
        int inverse_frame(uint8_t *result, const uint8_t *frame, uint8_t len, uint8_t& func);
        
        
        }  // namespace fish_protocol
        
        #endif  // _PROTO_UTILS_H_
        
        

        serial_protocol.h

        
        /**
         * @brief 文件描述:待完善
         * @author 小鱼 (fishros@foxmail.com)
         * @version V1.0.0
         * @date 2022-07-24
         * @copyright 版权所有:(鱼香ROS)fishros.org.cn
         */
        #ifndef _FISH_PROTOCOL_SERIAL_PROTOCOL_H_
        #define _FISH_PROTOCOL_SERIAL_PROTOCOL_H_
        #include <unistd.h>
        
        #include <boost/asio.hpp>
        #include <boost/bind.hpp>
        #include <boost/system/error_code.hpp>
        #include <boost/system/system_error.hpp>
        #include <boost/thread.hpp>
        #include <iostream>
        #include <string>
        
        namespace serial_protocol{
        
        class ProtocolConfig {
         public:
          // serial
          int serial_baut_;
          std::string serial_address_;
        
          ProtocolConfig& operator=(const ProtocolConfig& config) {
            serial_baut_ = config.serial_baut_;
            serial_address_ = config.serial_address_;
            return *this;
          };
        
         public:
          ProtocolConfig(){};
          ~ProtocolConfig(){};
        };
        
        enum flush_type
        {
          flush_receive = TCIFLUSH,
          flush_send = TCOFLUSH,
          flush_both = TCIOFLUSH
        };
        
        class SerialProtocol{
            using spb = boost::asio::serial_port_base;
        protected:
            std::function<void(const std::uint8_t*, const std::uint8_t)> recv_uint8_callback;
            ProtocolConfig protocol_config_;
        private:
            void _asyncReadSomeData();
            void _initSerialProtocol();
            void _recvDataCallback(const boost::system::error_code& error,
                                size_t bytes_transferred);
            void flush_serial_port(
                    boost::asio::serial_port& serial_port,
                    flush_type what,
                    boost::system::error_code& error);
        public:
            SerialProtocol(const ProtocolConfig& protocol_config)
                : io_service_(),
                serial_port_(io_service_) {
                this->protocol_config_ = protocol_config;
                _initSerialProtocol();
            }
            ~SerialProtocol();
            int ProtocolSendString(const std::string& data);
            int ProtocolSenduint8_t(const std::uint8_t* data, const std::uint8_t len);
            void SetDataRecvCallback(std::function<void(const std::uint8_t*, const std::uint8_t)> callback);
        private:
            unsigned char recv_data_buffer_[1024] = {0};
            boost::asio::io_service io_service_;
            boost::asio::serial_port serial_port_;
        };
        }  // namespace fish_protocol
        #endif  // _FISH_PROTOCOL_SERIAL_PROTOCOL_H_
        
        1 条回复 最后回复 回复 引用 1
        • 小鱼小
          小鱼 技术大佬 @3152079070
          最后由 编辑

          @3152079070 可以参考开源库中的ros2串口例程,你只需要将对象封装成一个成员变量即可。
          可以参考这位同学的代码:

          @sen 在 使用小鱼的串口代码间歇性串口打开失败 中说:

          这是我的代码的github仓库:https://github.com/SenHe524/AGV.git

          新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

          senS 1 条回复 最后回复 回复 引用 0
          • senS
            Sen @小鱼
            最后由 小鱼 编辑

            @小鱼 @3152079070 之前的仓库已无法访问,小鱼串口文件没办法上传附件我直接贴在下面,这个串口文件目前只有串口,没有了tcp、udp等功能,酌情使用。```
            proto_utils.cpp

            /**
             * @brief 文件描述:协议处理工具,打印、crc、转义与反转义
             * @author 小鱼 (fishros@foxmail.com)
             * @version V1.0.0
             * @date 2022-07-17
             * @copyright 版权所有:FishBot Open Source Organization
             */
            
            #include "fish_protocol/protocol_util.h"
            #include <iostream>
            namespace fish_protocol {
            using namespace std;
            
            // ------------------------查表法crc8校验-------
            static const uint8_t  crc8tab[] = 
            {0x00,0x5e,0xbc,0xe2,0x61,0x3f,0xdd,0x83,0xc2,0x9c,0x7e,0x20,0xa3,0xfd,0x1f,0x41,
            0x9d,0xc3,0x21,0x7f,0xfc,0xa2,0x40,0x1e,0x5f,0x01,0xe3,0xbd,0x3e,0x60,0x82,0xdc,
            0x23,0x7d,0x9f,0xc1,0x42,0x1c,0xfe,0xa0,0xe1,0xbf,0x5d,0x03,0x80,0xde,0x3c,0x62,
            0xbe,0xe0,0x02,0x5c,0xdf,0x81,0x63,0x3d,0x7c,0x22,0xc0,0x9e,0x1d,0x43,0xa1,0xff,
            0x46,0x18,0xfa,0xa4,0x27,0x79,0x9b,0xc5,0x84,0xda,0x38,0x66,0xe5,0xbb,0x59,0x07,
            0xdb,0x85,0x67,0x39,0xba,0xe4,0x06,0x58,0x19,0x47,0xa5,0xfb,0x78,0x26,0xc4,0x9a,
            0x65,0x3b,0xd9,0x87,0x04,0x5a,0xb8,0xe6,0xa7,0xf9,0x1b,0x45,0xc6,0x98,0x7a,0x24,
            0xf8,0xa6,0x44,0x1a,0x99,0xc7,0x25,0x7b,0x3a,0x64,0x86,0xd8,0x5b,0x05,0xe7,0xb9,
            0x8c,0xd2,0x30,0x6e,0xed,0xb3,0x51,0x0f,0x4e,0x10,0xf2,0xac,0x2f,0x71,0x93,0xcd,
            0x11,0x4f,0xad,0xf3,0x70,0x2e,0xcc,0x92,0xd3,0x8d,0x6f,0x31,0xb2,0xec,0x0e,0x50,
            0xaf,0xf1,0x13,0x4d,0xce,0x90,0x72,0x2c,0x6d,0x33,0xd1,0x8f,0x0c,0x52,0xb0,0xee,
            0x32,0x6c,0x8e,0xd0,0x53,0x0d,0xef,0xb1,0xf0,0xae,0x4c,0x12,0x91,0xcf,0x2d,0x73,
            0xca,0x94,0x76,0x28,0xab,0xf5,0x17,0x49,0x08,0x56,0xb4,0xea,0x69,0x37,0xd5,0x8b,
            0x57,0x09,0xeb,0xb5,0x36,0x68,0x8a,0xd4,0x95,0xcb,0x29,0x77,0xf4,0xaa,0x48,0x16,
            0xe9,0xb7,0x55,0x0b,0x88,0xd6,0x34,0x6a,0x2b,0x75,0x97,0xc9,0x4a,0x14,0xf6,0xa8,
            0x74,0x2a,0xc8,0x96,0x15,0x4b,0xa9,0xf7,0xb6,0xe8,0x0a,0x54,0xd7,0x89,0x6b,0x35};
            
            uint8_t getcrc8tab(const uint8_t *buf, int len) {
              uint8_t crc = 0x00;
              while(len--)
              {
                crc = crc8tab[crc ^ *buf++];
              }
              return crc;
            }
            /****************************
            函数功能:直接计算法获得8位循环冗余校验值
            入口参数:数组地址、长度
            出口参数:校验值
            ******************************/
            uint8_t getCrc8(uint8_t *ptr, uint16_t len)
            {
                uint8_t crc, i;
                crc = 0;
                while(len--)
                {
                    crc ^= *ptr++;
                    for(i = 0; i < 8; i++)
                    {
                        if(crc&0x01)
                            crc=(crc>>1)^0x8C;
                        else 
                            crc >>= 1;
                    }
                }
                return crc;
            }
            
            int frame_packing(const uint8_t *buf, uint8_t *frame, uint8_t len, uint8_t func) {
                uint8_t cnt = 0;
                frame[cnt++] = FIRST_CODE;
                frame[cnt++] = func;
                frame[cnt++] = len;
                for (int i = 0; i < len; i++) {
                    frame[cnt++] = buf[i];
                }
                frame[cnt++] = getcrc8tab(buf, len);
                frame[cnt++] = END_CODE;
                return cnt;
            }
            
            int inverse_frame(uint8_t *result, const uint8_t *frame, uint8_t len, uint8_t& func) {
                if((frame[0] != FIRST_CODE) || (frame[len - 1] != END_CODE))//  检查帧头帧尾
                    return 0;
                for(int i = 3; i < len-2; i++)
                {
                    result[i - 3] = frame[i];
                }
                if(getcrc8tab(result, frame[2]) != frame[len - 2])//    检查crc8校验
                    return 0;
                func = frame[1];
                return frame[2];
            }
            
            
            }  // namespace fish_protocol
            

            serial_protocol.cpp

            
            /**
             * @brief 文件描述:待完善
             * @author 小鱼 (fishros@foxmail.com)
             * @version V1.0.0
             * @date 2022-07-24
             * @copyright 版权所有:(鱼香ROS)fishros.org.cn
             */
            #include "fish_protocol/serial_protocol.h"
            
            
            namespace serial_protocol {
            
            
            /// @brief Flush a serial port's buffers.
            ///
            /// @param serial_port Port to flush.
            /// @param what Determines the buffers to flush.
            /// @param error Set to indicate what error occurred, if any.
            void SerialProtocol::flush_serial_port(
                    boost::asio::serial_port& serial_port,
                    flush_type what,
                    boost::system::error_code& error)
            {
                if (0 == ::tcflush(serial_port.lowest_layer().native_handle(), what))
                {
                    error = boost::system::error_code();
                }
                else
                {
                    error = boost::system::error_code(errno,
                        boost::asio::error::get_system_category());
                }
            }
            
            SerialProtocol::~SerialProtocol()
            {
                io_service_.stop();
                serial_port_.cancel();
                serial_port_.close();
            }
            void SerialProtocol::_initSerialProtocol() {
                boost::system::error_code ec;
                try
                {
                    serial_port_.open(protocol_config_.serial_address_, ec);
                    if(!serial_port_.is_open())
                        throw ec;
                }
                catch(boost::system::error_code& ec)
                {
                    std::cout << ec.message() << std::endl;
                    return ;
                }
                std::cout << "串口已打开:" << protocol_config_.serial_address_ << std::endl;
                serial_port_.set_option(spb::baud_rate(protocol_config_.serial_baut_));
                serial_port_.set_option(spb::character_size(8));
                serial_port_.set_option(spb::stop_bits(spb::stop_bits::one));
                serial_port_.set_option(spb::parity(spb::parity::none));
                serial_port_.set_option(spb::flow_control(spb::flow_control::none));
                boost::thread td(boost::bind(&boost::asio::io_service::run, &io_service_));
                _asyncReadSomeData();
            }
            
            void SerialProtocol::_recvDataCallback(const boost::system::error_code& error,
                                                    size_t bytes_transferred) {
                if (bytes_transferred > 0) {
                    // 回调数据
                    if(recv_uint8_callback)
                    {
                        recv_uint8_callback(recv_data_buffer_, bytes_transferred);
                    }
                }
                _asyncReadSomeData();
            }
            
            void SerialProtocol::_asyncReadSomeData() {
                serial_port_.async_read_some(
                    boost::asio::buffer(recv_data_buffer_, sizeof(recv_data_buffer_)),
                    boost::bind(&SerialProtocol::_recvDataCallback, this,
                                boost::placeholders::_1, boost::placeholders::_2));
            
            }
            
            int SerialProtocol::ProtocolSendString(const std::string& data) {
                serial_port_.write_some(boost::asio::buffer(data.data(), data.size()));
                return 0;
            }
            int SerialProtocol::ProtocolSenduint8_t(const std::uint8_t* data, const std::uint8_t len) {
                serial_port_.write_some(boost::asio::buffer(data, len));
                return 0;
            }
            
            void SerialProtocol::SetDataRecvCallback(
                    std::function<void(const std::uint8_t*, const std::uint8_t)> callback) {
                recv_uint8_callback = callback;
            }
            
            
            }  // namespace fish_protocol
            
            

            protocol_util.h

            
            /**
             * @brief 文件描述:待完善
             * @author 小鱼 (fishros@foxmail.com)
             * @version V1.0.0
             * @date 2022-07-24
             * @copyright 版权所有:(鱼香ROS)fishros.org.cn
             */
            #ifndef _FISH_PROTOCOL_PROTO_UTIL_H_
            #define _FISH_PROTOCOL_PROTO_UTIL_H_
            
            #include <cstdint>
            #include <cstdio>
            namespace fish_protocol {
            
            #define FIRST_CODE 0x55
            #define END_CODE 0xBB
            
            
            
            /**
             * @brief 截取指定位数据并赋值
             *        小端模式: 高位在前(低内存),低位在后(高内存)
             *
             */
            #define SET_SUB_BYTES1(target, data) target = (data & 0xFF)
            #define SET_SUB_BYTES2(target, data) target |= ((data << 8) & 0xFF00)
            
            /**
             * @brief 查表法crc8校验
             *
             * @param buf 输入数组
             * @param len 数组长度
             * @return uint8_t
             */
            uint8_t getcrc8tab(const uint8_t *buf, int len);
            
            /**
             * @brief 直接计算法crc8校验
             *
             * @param buf 输入数组
             * @param len 数组长度
             * @return uint8_t
             */
            uint8_t getCrc8(const uint8_t *buf, int len);
            
            /**
             * @brief 将数据进行转义
             *
             * @param frame 帧数据
             * @param result 结果
             * @param len 长度
             * @return int 转义完成后新的帧的大小
             */
            int frame_packing(const uint8_t *buf, uint8_t *frame, uint8_t len, uint8_t func);
            
            /**
             * @brief 将数据帧进行反转义
             *
             * @param frame 帧数据
             * @param result 结果
             * @param len 长度
             * @return int
             */
            int inverse_frame(uint8_t *result, const uint8_t *frame, uint8_t len, uint8_t& func);
            
            
            }  // namespace fish_protocol
            
            #endif  // _PROTO_UTILS_H_
            
            

            serial_protocol.h

            
            /**
             * @brief 文件描述:待完善
             * @author 小鱼 (fishros@foxmail.com)
             * @version V1.0.0
             * @date 2022-07-24
             * @copyright 版权所有:(鱼香ROS)fishros.org.cn
             */
            #ifndef _FISH_PROTOCOL_SERIAL_PROTOCOL_H_
            #define _FISH_PROTOCOL_SERIAL_PROTOCOL_H_
            #include <unistd.h>
            
            #include <boost/asio.hpp>
            #include <boost/bind.hpp>
            #include <boost/system/error_code.hpp>
            #include <boost/system/system_error.hpp>
            #include <boost/thread.hpp>
            #include <iostream>
            #include <string>
            
            namespace serial_protocol{
            
            class ProtocolConfig {
             public:
              // serial
              int serial_baut_;
              std::string serial_address_;
            
              ProtocolConfig& operator=(const ProtocolConfig& config) {
                serial_baut_ = config.serial_baut_;
                serial_address_ = config.serial_address_;
                return *this;
              };
            
             public:
              ProtocolConfig(){};
              ~ProtocolConfig(){};
            };
            
            enum flush_type
            {
              flush_receive = TCIFLUSH,
              flush_send = TCOFLUSH,
              flush_both = TCIOFLUSH
            };
            
            class SerialProtocol{
                using spb = boost::asio::serial_port_base;
            protected:
                std::function<void(const std::uint8_t*, const std::uint8_t)> recv_uint8_callback;
                ProtocolConfig protocol_config_;
            private:
                void _asyncReadSomeData();
                void _initSerialProtocol();
                void _recvDataCallback(const boost::system::error_code& error,
                                    size_t bytes_transferred);
                void flush_serial_port(
                        boost::asio::serial_port& serial_port,
                        flush_type what,
                        boost::system::error_code& error);
            public:
                SerialProtocol(const ProtocolConfig& protocol_config)
                    : io_service_(),
                    serial_port_(io_service_) {
                    this->protocol_config_ = protocol_config;
                    _initSerialProtocol();
                }
                ~SerialProtocol();
                int ProtocolSendString(const std::string& data);
                int ProtocolSenduint8_t(const std::uint8_t* data, const std::uint8_t len);
                void SetDataRecvCallback(std::function<void(const std::uint8_t*, const std::uint8_t)> callback);
            private:
                unsigned char recv_data_buffer_[1024] = {0};
                boost::asio::io_service io_service_;
                boost::asio::serial_port serial_port_;
            };
            }  // namespace fish_protocol
            #endif  // _FISH_PROTOCOL_SERIAL_PROTOCOL_H_
            
            1 条回复 最后回复 回复 引用 1
            • 小鱼小 小鱼 将这个主题标记为已解决,在
            • 第一个帖子
              最后一个帖子
            皖ICP备16016415号-7
            Powered by NodeBB | 鱼香ROS