From 740dda620f10f24ad16ff093bc95e3209a22417e Mon Sep 17 00:00:00 2001 From: xin Date: Thu, 25 Jan 2024 10:57:31 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Readme.md | 157 +++++++++++++++++++++++++++++++++++ src/Communication_Protocol.c | 119 ++++++++++++++++++++++++++ src/Communication_Protocol.h | 54 ++++++++++++ src/Communication_struct.h | 36 ++++++++ 5 files changed, 367 insertions(+) create mode 100644 .gitignore create mode 100644 Readme.md create mode 100644 src/Communication_Protocol.c create mode 100644 src/Communication_Protocol.h create mode 100644 src/Communication_struct.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8f1faee --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.vscode/ diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..c3f149e --- /dev/null +++ b/Readme.md @@ -0,0 +1,157 @@ +# IRIS通讯协议 V1.0 + +### 帧格式: + +| 帧头 | 命令类型 | 长度 | Data | Check | +| :-------: | :-----------: | :----: | :--: | :-----------: | +| 0x55 0xAA | Command 1字节 | 两字节 | Data | crc校验 2字节 | + +- **帧头**:固定的0x55 0xAA 两个字节 +- **命令类型**:一个字节 + - 0x01: 命令为字符串 即Data要转换为字符串 + - 0x00: 命令为json数据,应用json解析Data + - 0x02-0xff:自定义二进制通讯数据,Data的解析应改按照Communication_Protocol中约定进行 +- **长度**:Data+Check的总字节数 +- **Check**:长度+Data的 CRC校验 算法在Communication_Protocol提供了(如果Data过长,光谱数据,可以不计算,但是得提供,此时提供内容为0xEE 0xEE) +- **均采用小端方式存储** + + + +### json 定义 + +json定义比较灵活 但是根对象必须提供如下: + +- CN: 命令名称 + + + +- PA:命令参数 //发送时必须 返回可选 + + 返回时应提供相应状态 + +- ST:OK + +发送示例: + +```json +{ + "CN":"SetCamerTime", + "PA":{ + "time1":1000, + "time2":1000 + }, + "Other":"自己定义" +} + +``` + +接收示例 + +```json +{ + "CN":"SetCamerTime", + "Other":"自己定义", + "ST":"OK" +} +``` + + + +### Communication_Protocol.h及.c + +该文件主要定义了命令的名称 以#define方式进行。并且在末尾提供了一些通用函数 如下 + +```c +#ifndef COMMUNICATION_PROTOCOL_H +#define COMMUNICATION_PROTOCOL_H + + +#include +#include +// DEFINE The protocol Here + //Forexample +// #define MYCOMAN 0x02 //命令全大写 +// todo : define your protocol here +/*-------------------------------------------------------------------------------------------------------------*/ + + + + + + + + + + + +/*-------------------------------------------------------------------------------------------------------------*/ +/* +在此之下开始定义一些函数 +*/ +// 成功返回打包后的数据长度 +// -1: Error +// 成功返回打包后的数据长度 +int32_t IRIS_Protocol_Pack(uint8_t Command,uint16_t LenthofIn, uint8_t *BufferIn, uint8_t *PackData); + +// 成功返回解包后的数据长度 +// 0: 该命令返回无参数 +// -1: checksum error +// -100: parameter error +// -200: header error +// -300: command error +// -400: length error +// 成功返回解包后的数据长度 +int32_t IRIS_Protocol_Unpack(uint8_t *PackData, uint16_t LenthofIn, uint8_t Command, uint8_t *BufferOut); + +// 定义裁切命令 +// 成功返回裁切后的数据长度 +// -1: Error +int32_t IRIS_Cut_Befor_Header(uint8_t *PackData, uint16_t LenthofIn ); + +// 返回CRC校验值 +uint16_t IRIS_calcCRC(const void *pBuffer, uint16_t bufferSize); +#endif +``` + +### Communication_struct.h + +该文件主要定义了命令相关参数部分的定义 所有参数都应该以结构体定义 无需参数的不定义 具体如下 + +```c +#ifndef COMMUNICATION_STRUCT_H +#define COMMUNICATION_STRUCT_H + +// Define your communication structures here +// For example: +/* +如果发送和接受的数据结构一样,那么就定义一个结构体 +struct MyComan_struct //对应的命令结构体 小驼峰命名法+struct +{ + uint8_t Command; + uint16_t LenthofIn; +}; + + + +如果发送和接受的数据结构不一样,那么就分开定义 +struct MyComan_Send_struct //对应的命令结构体 小驼峰命名法+Send_struct +{ + uint8_t Command; + uint16_t LenthofIn; + +}; + +struct MyComan_Recv_struct //对应的命令结构体 小驼峰命名法+Recv_struct +{ + uint8_t Command; + uint16_t LenthofOut; + +}; +*/ + + + +#endif // COMMUNICATION_STRUCT_H + +``` + diff --git a/src/Communication_Protocol.c b/src/Communication_Protocol.c new file mode 100644 index 0000000..fd694a0 --- /dev/null +++ b/src/Communication_Protocol.c @@ -0,0 +1,119 @@ +#include "Communication_Protocol.h" +int32_t IRIS_Protocol_Pack(uint8_t Command,uint16_t LenthofIn, uint8_t *BufferIn, uint8_t *PackData) +{ + if( PackData == NULL || (LenthofIn!=0 && BufferIn == NULL)) + { + return -1; + } + + PackData[0] = 0x55; + PackData[1] = 0xAA; + PackData[2] = Command; + PackData[3] = LenthofIn & 0xFF; + PackData[4] = (LenthofIn >> 8) & 0xFF; + if(LenthofIn!=0) + { + memcpy(&PackData[5],BufferIn,LenthofIn); + } + uint16_t CRC = IRIS_calcCRC(PackData, LenthofIn+5); + PackData[LenthofIn+5] = CRC & 0xFF; + PackData[LenthofIn+6] = (CRC >> 8) & 0xFF; + return LenthofIn+7; + + + + + + +} + +int32_t IRIS_Protocol_Unpack(uint8_t *PackData, uint16_t LenthofIn, uint8_t Command, uint8_t *BufferOut) +{ + if( PackData == NULL || BufferOut == NULL) + { + return -100; + } + if(PackData[0] != 0x55 || PackData[1] != 0xAA) + { + return -200; + } + if(PackData[2] != Command) + { + return -300; + } + uint16_t LenthofOut = PackData[3] + (PackData[4] << 8); + if(LenthofOut > LenthofIn - 7) + { + return -400; + } + uint16_t CRC = IRIS_calcCRC(PackData, LenthofOut+5); + if(CRC != (PackData[LenthofOut+5] + (PackData[LenthofOut+6] << 8))) + { + return -1; + } + if(LenthofOut == 0) + { + return 0; + } + memcpy(BufferOut,&PackData[5],LenthofOut); + return LenthofOut; + +} + + +int32_t IRIS_Cut_Befor_Header(uint8_t *PackData, uint16_t LenthofIn ) +{ + if( PackData == NULL ) + { + return -1; + } + uint16_t i = 0; + for(i = 0; i < LenthofIn; i++) + { + if(PackData[i] == 0x55 && PackData[i+1] == 0xAA) + { + break; + } + } + if(i == LenthofIn) + { + //清空数据 + memset(PackData,0,LenthofIn); + return 0; + } + + uint16_t LenthofOut = LenthofIn - i; + memcpy(PackData,&PackData[i],LenthofOut); + return LenthofOut; +} + + + + + + + +uint16_t IRIS_calcCRC(const void *pBuffer, uint16_t bufferSize) +{ + const uint8_t *pBytesArray = (const uint8_t*)pBuffer; + uint16_t poly = 0x8408; + uint16_t crc = 0; + uint8_t carry; + uint8_t i_bits; + uint16_t j; + for (j =0; j < bufferSize; j++) + { + crc = crc ^ pBytesArray[j]; + for (i_bits = 0; i_bits < 8; i_bits++) + { + carry = crc & 1; + crc = crc / 2; + if (carry) + { + crc = crc^poly; + } + } + } + return crc; +} + diff --git a/src/Communication_Protocol.h b/src/Communication_Protocol.h new file mode 100644 index 0000000..2274547 --- /dev/null +++ b/src/Communication_Protocol.h @@ -0,0 +1,54 @@ + +#ifndef COMMUNICATION_PROTOCOL_H +#define COMMUNICATION_PROTOCOL_H + + +#include +#include +// DEFINE The protocol Here + //Forexample +// #define MYCOMAN 0x02 //命令全大写 +// todo : define your protocol here +/*-------------------------------------------------------------------------------------------------------------*/ + + + + + + + + + + + +/*-------------------------------------------------------------------------------------------------------------*/ +/* +在此之下开始定义一些函数 +*/ +// 成功返回打包后的数据长度 +// -1: Error +// 成功返回打包后的数据长度 +int32_t IRIS_Protocol_Pack(uint8_t Command,uint16_t LenthofIn, uint8_t *BufferIn, uint8_t *PackData); + +// 成功返回解包后的数据长度 +// 0: 该命令返回无参数 +// -1: checksum error +// -100: parameter error +// -200: header error +// -300: command error +// -400: length error +// 成功返回解包后的数据长度 +int32_t IRIS_Protocol_Unpack(uint8_t *PackData, uint16_t LenthofIn, uint8_t Command, uint8_t *BufferOut); + +// 定义裁切命令 +// 成功返回裁切后的数据长度 +// -1: Error +int32_t IRIS_Cut_Befor_Header(uint8_t *PackData, uint16_t LenthofIn ); + +// 返回CRC校验值 +uint16_t IRIS_calcCRC(const void *pBuffer, uint16_t bufferSize); +#endif + + + + diff --git a/src/Communication_struct.h b/src/Communication_struct.h new file mode 100644 index 0000000..d1f395b --- /dev/null +++ b/src/Communication_struct.h @@ -0,0 +1,36 @@ +#ifndef COMMUNICATION_STRUCT_H +#define COMMUNICATION_STRUCT_H + +// Define your communication structures here +// For example: +/* +如果发送和接受的数据结构一样,那么就定义一个结构体 +struct MyComan_struct //对应的命令结构体 小驼峰命名法+struct +{ + uint8_t Command; + uint16_t LenthofIn; +}; + + + +如果发送和接受的数据结构不一样,那么就分开定义 +struct MyComan_Send_struct //对应的命令结构体 小驼峰命名法+Send_struct +{ + uint8_t Command; + uint16_t LenthofIn; + +}; + +struct MyComan_Recv_struct //对应的命令结构体 小驼峰命名法+Recv_struct +{ + uint8_t Command; + uint16_t LenthofOut; + +}; + + + +*/ + + +#endif // COMMUNICATION_STRUCT_H