初始
This commit is contained in:
commit
0133cc2920
38
.clang-format
Normal file
38
.clang-format
Normal file
@ -0,0 +1,38 @@
|
||||
# .clang-format
|
||||
|
||||
# 风格格式化
|
||||
BasedOnStyle: Google
|
||||
# 4 空格缩进
|
||||
IndentWidth: 4
|
||||
# 连续对齐变量的声明
|
||||
AlignConsecutiveDeclarations: true
|
||||
# 指针左侧对齐
|
||||
PointerAlignment: Left
|
||||
# 访问说明符(public、private等)的偏移
|
||||
AccessModifierOffset: -4
|
||||
# 大括号
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
# 函数定义后面大括号在新行
|
||||
AfterFunction: true
|
||||
# class定义后面
|
||||
AfterClass: true
|
||||
|
||||
# 去除C++11的列表初始化的大括号{后和}前的空格
|
||||
Cpp11BracedListStyle: true
|
||||
# 允许重新排版注释
|
||||
ReflowComments: true
|
||||
# 允许排序#include
|
||||
SortIncludes: false
|
||||
# 在尾随的评论前添加的空格数(只适用于//)
|
||||
SpacesBeforeTrailingComments: 3
|
||||
# tab宽度
|
||||
TabWidth: 4
|
||||
# 构造函数的初始化列表要么都在同一行,要么都各自一行
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
# 每行字符的限制,0表示没有限制
|
||||
ColumnLimit: 100
|
||||
# 允许短的块放在同一行
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
# 是否允许短函数在一行
|
||||
AllowShortFunctionsOnASingleLine: InlineOnly
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
build
|
||||
.cache
|
||||
*.user
|
122
.vscode/settings.json
vendored
Normal file
122
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
{
|
||||
"files.autoSave": "onFocusChange",
|
||||
"editor.fontSize": 16,
|
||||
"editor.fontFamily": "'FiraCode Nerd Font Mono', 'FiraCode Nerd Font Mono', 'FiraCode Nerd Font Mono'",
|
||||
"cmake.configureOnOpen": true,
|
||||
"cmake.debugConfig": {
|
||||
"console": "integratedTerminal",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "-gdb-set charset utf-8",
|
||||
"text": "-gdb-set charset UTF-8"
|
||||
},
|
||||
{
|
||||
"description": "Enable gdb pretty-printing",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"cmake.environment": {
|
||||
"PATH": "${env:PATH};C:/"
|
||||
},
|
||||
"cmake.options.statusBarVisibility": "visible",
|
||||
"cmake.generator": "Ninja",
|
||||
"C_Cpp.default.compileCommands": "${workspaceRoot}/build/compile_commands.json",
|
||||
"C_Cpp.default.cppStandard": "c++14",
|
||||
"editor.inlayHints.enabled": "off",
|
||||
"editor.unicodeHighlight.allowedLocales": {
|
||||
"ja": true,
|
||||
"zh-hant": true,
|
||||
"zh-hans": true
|
||||
},
|
||||
"files.associations": {
|
||||
"xstring": "cpp",
|
||||
"vector": "cpp",
|
||||
"*.ipp": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"chrono": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"complex": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"exception": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"fstream": "cpp",
|
||||
"functional": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"iterator": "cpp",
|
||||
"limits": "cpp",
|
||||
"list": "cpp",
|
||||
"locale": "cpp",
|
||||
"map": "cpp",
|
||||
"memory": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"ostream": "cpp",
|
||||
"queue": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"set": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"strstream": "cpp",
|
||||
"system_error": "cpp",
|
||||
"thread": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"utility": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xmemory0": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp"
|
||||
}
|
||||
}
|
20
CMakeLists.txt
Normal file
20
CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(SerialOprTest LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_PREFIX_PATH
|
||||
${CMAKE_PREFIX_PATH}
|
||||
"C:/dev/boost"
|
||||
)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
if (MSVC)
|
||||
add_compile_options(/source-charset:utf-8)
|
||||
endif()
|
||||
|
||||
include_directories(libserial)
|
||||
add_subdirectory(libserial)
|
||||
add_executable(SerialOprTest main.cpp)
|
||||
target_link_libraries(SerialOprTest PRIVATE SerialOpr)
|
17
libserial/CMakeLists.txt
Normal file
17
libserial/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(SerialOpr LANGUAGES CXX)
|
||||
|
||||
if (MSVC)
|
||||
add_definitions(-D_WIN32_WINNT=0x0601)
|
||||
add_compile_options(/source-charset:utf-8)
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/3rd/asio-1.30.2/include)
|
||||
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
find_package(Boost REQUIRED COMPONENTS system)
|
||||
|
||||
add_library(SerialOpr SHARED serial.h serial.cpp)
|
||||
target_link_libraries(SerialOpr PRIVATE ${Boost_LIBRARIES})
|
||||
target_compile_definitions(SerialOpr PRIVATE SERIALOPR_LIB DYNAMIC_DLL)
|
246
libserial/serial.cpp
Normal file
246
libserial/serial.cpp
Normal file
@ -0,0 +1,246 @@
|
||||
#include "serial.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
|
||||
namespace cppbox {
|
||||
|
||||
using serial_port = boost::asio::serial_port;
|
||||
class CSerialOprImp
|
||||
{
|
||||
public:
|
||||
CSerialOprImp()
|
||||
: timer_(io_),
|
||||
baud_rate_(serial_port::baud_rate(19200)),
|
||||
stop_bits_(serial_port::stop_bits::one),
|
||||
parity_(serial_port::parity::none),
|
||||
flow_control_(serial_port::flow_control::none)
|
||||
{
|
||||
port_ = new boost::asio::serial_port(io_);
|
||||
error_ = new char[1024];
|
||||
std::memset(error_, 0x0, 1024);
|
||||
}
|
||||
~CSerialOprImp() { delete[] error_; }
|
||||
|
||||
public:
|
||||
void set_port(const char* port)
|
||||
{
|
||||
std::memset(port_name_, 0x0, sizeof(port_name_));
|
||||
std::snprintf(port_name_, sizeof(port_name_), "%s", port);
|
||||
}
|
||||
int open()
|
||||
{
|
||||
port_->open(port_name_, ec_);
|
||||
if (!port_->is_open()) {
|
||||
std::memset(error_, 0x0, 1024);
|
||||
std::snprintf(error_, 1024, "%s", ec_.what().c_str());
|
||||
return ec_.value();
|
||||
}
|
||||
port_->set_option(baud_rate_, ec_);
|
||||
port_->set_option(flow_control_, ec_);
|
||||
port_->set_option(parity_, ec_);
|
||||
port_->set_option(stop_bits_, ec_);
|
||||
port_->set_option(character_size_, ec_);
|
||||
return 0;
|
||||
}
|
||||
void close()
|
||||
{
|
||||
if (port_->is_open()) {
|
||||
port_->close();
|
||||
}
|
||||
}
|
||||
|
||||
void write(const char* data, int len)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int read(char* data, int size)
|
||||
{
|
||||
bytes_transferred_ = 0;
|
||||
io_.reset();
|
||||
|
||||
timer_.expires_from_now(boost::posix_time::milliseconds(time_out_));
|
||||
timer_.async_wait(
|
||||
boost::bind(&CSerialOprImp::time_out, this, boost::asio::placeholders::error));
|
||||
|
||||
port_->async_read_some(
|
||||
boost::asio::buffer(buffer_),
|
||||
boost::bind(&CSerialOprImp::handle_read, this, boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred));
|
||||
|
||||
io_.run();
|
||||
|
||||
if (size < bytes_transferred_) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bytes_transferred_ > 0) {
|
||||
std::memcpy(data, buffer_, bytes_transferred_);
|
||||
return static_cast<int>(bytes_transferred_);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
const char* get_last_error() const { return error_; }
|
||||
void set_timeout(uint64_t timeout) { time_out_ = timeout; }
|
||||
|
||||
void set_baudrate(uint32_t baudrate) { baud_rate_ = serial_port::baud_rate(baudrate); }
|
||||
void set_databits(serial_port::character_size size) { character_size_ = size; }
|
||||
void set_parity(serial_port::parity parity) { parity_ = parity; }
|
||||
void set_stopbits(serial_port::stop_bits stop_bits) { stop_bits_ = stop_bits; }
|
||||
void set_flow_control(serial_port::flow_control flow_control) { flow_control_ = flow_control; }
|
||||
|
||||
private:
|
||||
void time_out(const boost::system::error_code& code)
|
||||
{
|
||||
if (code) {
|
||||
return;
|
||||
}
|
||||
port_->cancel();
|
||||
}
|
||||
void handle_read(const boost::system::error_code& error, std::size_t bytes_transferred)
|
||||
{
|
||||
if (!error) {
|
||||
bytes_transferred_ = bytes_transferred;
|
||||
timer_.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
char port_name_[128]{};
|
||||
serial_port::baud_rate baud_rate_;
|
||||
serial_port::character_size character_size_{8};
|
||||
serial_port::stop_bits stop_bits_;
|
||||
serial_port::parity parity_;
|
||||
uint64_t time_out_{1000};
|
||||
serial_port::flow_control flow_control_;
|
||||
|
||||
private:
|
||||
std::size_t bytes_transferred_{};
|
||||
boost::asio::io_context io_{};
|
||||
boost::asio::serial_port* port_{};
|
||||
boost::system::error_code ec_{};
|
||||
char buffer_[512]{};
|
||||
boost::asio::deadline_timer timer_;
|
||||
char* error_{};
|
||||
};
|
||||
|
||||
CSerialOpr::CSerialOpr()
|
||||
{
|
||||
imp_ = new CSerialOprImp();
|
||||
}
|
||||
|
||||
CSerialOpr::~CSerialOpr()
|
||||
{
|
||||
delete imp_;
|
||||
}
|
||||
|
||||
void CSerialOpr::set_port(const char* port)
|
||||
{
|
||||
imp_->set_port(port);
|
||||
}
|
||||
|
||||
void CSerialOpr::set_baudrate(uint32_t baudrate)
|
||||
{
|
||||
imp_->set_baudrate(baudrate);
|
||||
}
|
||||
|
||||
void CSerialOpr::set_data_bits(DataBits data_bits)
|
||||
{
|
||||
switch (data_bits) {
|
||||
case D5:
|
||||
imp_->set_databits(serial_port::character_size(5));
|
||||
break;
|
||||
case D6:
|
||||
imp_->set_databits(serial_port::character_size(6));
|
||||
break;
|
||||
case D7:
|
||||
imp_->set_databits(serial_port::character_size(7));
|
||||
break;
|
||||
case D8:
|
||||
imp_->set_databits(serial_port::character_size(8));
|
||||
break;
|
||||
default:
|
||||
imp_->set_databits(serial_port::character_size(5));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CSerialOpr::set_stop_bits(StopBits stop_bits)
|
||||
{
|
||||
switch (stop_bits) {
|
||||
case OneStop:
|
||||
imp_->set_stopbits(serial_port::stop_bits(serial_port::stop_bits::one));
|
||||
break;
|
||||
case OneAndHalfStop:
|
||||
imp_->set_stopbits(serial_port::stop_bits(serial_port::stop_bits::onepointfive));
|
||||
break;
|
||||
case TwoStop:
|
||||
imp_->set_stopbits(serial_port::stop_bits(serial_port::stop_bits::two));
|
||||
break;
|
||||
default:
|
||||
imp_->set_stopbits(serial_port::stop_bits(serial_port::stop_bits::one));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CSerialOpr::set_parity(Parity parity)
|
||||
{
|
||||
switch (parity) {
|
||||
case EvenParity:
|
||||
imp_->set_parity(serial_port::parity(serial_port::parity::even));
|
||||
break;
|
||||
case OddParity:
|
||||
imp_->set_parity(serial_port::parity(serial_port::parity::odd));
|
||||
break;
|
||||
default:
|
||||
imp_->set_parity(serial_port::parity(serial_port::parity::none));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CSerialOpr::set_flow_control(FlowControl flow_control)
|
||||
{
|
||||
switch (flow_control) {
|
||||
case NoFlowControl:
|
||||
imp_->set_flow_control(serial_port::flow_control(serial_port::flow_control::none));
|
||||
break;
|
||||
case HardwareControl:
|
||||
imp_->set_flow_control(serial_port::flow_control(serial_port::flow_control::hardware));
|
||||
break;
|
||||
case SoftwareControl:
|
||||
imp_->set_flow_control(serial_port::flow_control(serial_port::flow_control::software));
|
||||
break;
|
||||
default:
|
||||
imp_->set_flow_control(serial_port::flow_control(serial_port::flow_control::none));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CSerialOpr::set_timeout(uint64_t timeout)
|
||||
{
|
||||
imp_->set_timeout(timeout);
|
||||
}
|
||||
|
||||
int CSerialOpr::open()
|
||||
{
|
||||
return imp_->open();
|
||||
}
|
||||
|
||||
void CSerialOpr::close()
|
||||
{
|
||||
imp_->close();
|
||||
}
|
||||
int CSerialOpr::read(char* data, int size)
|
||||
{
|
||||
return imp_->read(data, size);
|
||||
}
|
||||
int CSerialOpr::write(const char* data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const char* CSerialOpr::get_last_error() const
|
||||
{
|
||||
return imp_->get_last_error();
|
||||
}
|
||||
} // namespace cppbox
|
67
libserial/serial.h
Normal file
67
libserial/serial.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef SERIAL_OPERATE
|
||||
#define SERIAL_OPERATE
|
||||
|
||||
#if defined(DYNAMIC_DLL)
|
||||
#if defined(_MSC_VER)
|
||||
#define CPP_SERIALOPR_EXPORT __declspec(dllexport)
|
||||
#define CPP_SERIALOPR_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
#define CPP_SERIALOPR_EXPORT __attribute__((visibility("default")))
|
||||
#define CPP_SERIALOPR_IMPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#ifdef SERIALOPR_LIB
|
||||
#define SERIALOPR_API CPP_SERIALOPR_EXPORT
|
||||
#else
|
||||
#define SERIALOPR_API CPP_SERIALOPR_IMPORT
|
||||
#endif
|
||||
#else
|
||||
#define SERIALOPR_API
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace cppbox {
|
||||
|
||||
enum DataBits { D5 = 5, D6 = 6, D7 = 7, D8 = 8, UnKnowBits = -1 };
|
||||
|
||||
enum StopBits { OneStop = 1, OneAndHalfStop = 3, TwoStop = 2, UnknownStopBits = -1 };
|
||||
|
||||
enum Parity {
|
||||
NoParity = 0,
|
||||
EvenParity = 2,
|
||||
OddParity = 1
|
||||
};
|
||||
|
||||
enum FlowControl { NoFlowControl, HardwareControl, SoftwareControl, UnknownFlowControl = -1 };
|
||||
|
||||
class CSerialOprImp;
|
||||
class SERIALOPR_API CSerialOpr
|
||||
{
|
||||
public:
|
||||
CSerialOpr();
|
||||
~CSerialOpr();
|
||||
|
||||
public:
|
||||
void set_port(const char* port);
|
||||
void set_baudrate(uint32_t baudrate);
|
||||
void set_data_bits(DataBits data_bits);
|
||||
void set_stop_bits(StopBits stop_bits);
|
||||
void set_parity(Parity parity);
|
||||
void set_flow_control(FlowControl flow_control);
|
||||
void set_timeout(uint64_t timeout);
|
||||
|
||||
public:
|
||||
int open();
|
||||
void close();
|
||||
int read(char* data, int size);
|
||||
int write(const char* data);
|
||||
const char* get_last_error() const;
|
||||
|
||||
private:
|
||||
CSerialOprImp* imp_{};
|
||||
};
|
||||
|
||||
} // namespace cppbox
|
||||
|
||||
#endif
|
28
main.cpp
Normal file
28
main.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include <iostream>
|
||||
#include <serial.h>
|
||||
|
||||
using namespace cppbox;
|
||||
|
||||
int main()
|
||||
{
|
||||
char buffer[512]{};
|
||||
|
||||
CSerialOpr opr;
|
||||
|
||||
opr.set_baudrate(19200);
|
||||
opr.set_data_bits(DataBits::D8);
|
||||
opr.set_flow_control(FlowControl::NoFlowControl);
|
||||
opr.set_parity(Parity::EvenParity);
|
||||
opr.set_port("COM2");
|
||||
opr.set_timeout(10 * 1000);
|
||||
opr.set_stop_bits(StopBits::OneStop);
|
||||
|
||||
if (opr.open() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int read_size = opr.read(buffer, sizeof(buffer));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user