# libxcom
**Repository Path**: leo-iot/libxcom
## Basic Information
- **Project Name**: libxcom
- **Description**: 是一种轻量型数据序列化和反序列化语言。与平台无关,可以自己配置解析函数。目前在串口指令方面使用较成熟。
- **Primary Language**: C++
- **License**: Apache-2.0
- **Default Branch**: tree-sitter
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2024-11-11
- **Last Updated**: 2025-06-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Xcom 串口协议解析库
## 简介
这是一个用于解析和构建串口通信协议但不限于串口的 C++ 库,自定义协议的构建。支持任意的16进制序列化与反序列化。该项目适用于工业自动化场景中的数据采集与通信需求,提供灵活的协议定义方式和高效的数据处理能力。
## 快速入门
### 第一步:协议构建(Modbus 示例)
Modbus 协议的基本结构如下:
- 请求帧:`地址(Address) + 功能码(Function Code) + 起始地址(Start Address) + 数据长度(Data Length)`
- 响应帧:`地址(Address) + 功能码(Function Code) + 数据长度(Data Length) + 数据(Data) + 校验(CRC16)`
协议配置实例:
```
def crc_modbus: $crc16($1,0x8005,0xffff,0x0000,1,1)
def modbus_read_req:[$num($addr) $fcode $itom(2,$reg) $itom(2,$reglen) $crc_modbus($group(0,$pos))]
def modbus_read_resp:[$num($addr) $fcode $ditch(1,{dl=$int($0)}) $ditch($dl, {data=$0}) $ditch(2,{$chk($0,$crc_modbus($group(0,$pos)))})]
def modbus_write_req:[$num($addr) $fcode $itom(2,$reg) $itom(2,$reglen) $len($1) $1 $crc_modbus($group(0,$pos))]
def modbus_write_resp:[$num($addr) $fcode $ditch(1,{dl=$int($0)}) $ditch($dl,{data=$0}) $ditch(2,{$chk($0,$crc_modbus($group(0,$pos)))})]
```
可以用#开头进行注释
### 第二步:c++代码接入
提前将上述内容放到文件,或作为字符串,赋值给std::string templ= read(...);
```
libxcom::DataItem ditem("测试协议", templ, "$int($data)", 1);
ditem.SetVar("addr", OpValue("01"));
// 最好使用static_cast(0x03), 避免向上兼容成int32_t类型
ditem.SetVar("fcode", 0x03);
ditem.SetVar("reglen", 2);
ditem.SetVar("reg", 0x0000);
ditem.EmptyParam();
// 指令序列化, 绑定send函数
OpValue cmd = ditem.GenerateCmd("modbus_read_req"); // 关联函数modbus_read_req
cmd.Show(); // 如果成功,生成的是01 03 00 00 00 02 CRC码
if (cmd.IsEmpty()) {
return -1;
}
CmdValue genCmd = cmd.GenCmd();
// 后面省略掉发送过程。。。
// 下面处理接收
ditem.ParseRecvCmd("modbus_read_resp");
// 处理接收指令, 这里假设数据是一次性到的,也可以分多次到达
// OpValue result;
// uint8_t cmd_buf[] = {0xff, 0xff, 0xff, 0x51, 0x03, 0x04, 0x00, 0x00, 0x00, 0x1E, 0x3E, 0x2A};
// CmdValue recv(cmd_buf, sizeof(cmd_buf) / sizeof(cmd_buf[0]));
while ((len = recv(fd, buf, timeout)) > 0) {
int32_t result = ditem.ProcessRealRecv(buf, len);
if (result == RECV_COMPLETE || result == RECV_FAILED) {// 完成或失败都退出
break;
}
}
/** 结果是依据第一行$int($data)得到的,其中$data是modbus_read_resp
/* 提取的16进制数据序列,即0x00, 0x00, 0x00, 0x1E, 整个表达式表示将data
/* 转换成int32_t类型的值,默认大端模式,即0x1E
*/
result = ditem.Result();
result.Show();// 输出30
```
## 构建与测试
本项目使用 CMake 构建系统,支持主流操作系统(Linux、macOS、Windows)。测试部分使用 Google Test 框架。
### 构建步骤
1. 安装依赖:CMake、C++ 编译器、Google Test
2. 构建项目:
```bash
mkdir build && cd build
cmake ..
make
```
### 运行测试
```bash
./test/basic_test
./test/dataitem_test
./test/express_test
./test/template_test
```
## 贡献指南
欢迎贡献代码和改进文档。请遵循以下步骤:
1. Fork 项目
2. 创建新分支 (`git checkout -b feature/new-feature`)
3. 提交更改 (`git commit -am 'Add new feature'`)
4. 推送分支 (`git push origin feature/new-feature`)
5. 创建 Pull Request
## 许可证
本项目采用 MIT 许可证。详情请查看 LICENSE 文件。