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