hunting/utils/McuProtocol/README.md
2024-06-15 08:36:44 +08:00

170 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 1. MCU协议模块
  负责对MCU协议进行封包/解包,负责协议的多态替换。协议数据统一使用网络字节序(大端字节序)。
**注:协议数据统一使用网络字节序(大端字节序)**
| 版本 | 时间 | 说明 |
| ---- | ---- | ---- |
| V1.0 | 2024-5-14 | 首次评审。 |
| V1.1 | 2024-5-16 | 补充数据同步协议。 |
## 1.1. 协议格式
| 协议头 | 流水号 | 命令字 | 长度 | 数据段 | 校验码 |
|----|----|----|----|----|----|
| 2字节<br>0xFAC1 | 4字节 | 2字节 | 2字节<br>协议包总长度 | - | 2字节 |
**流水号**
&emsp;&emsp;流水号用于强绑定问答型协议的发送数据和回复数据,回复者原数据回传即可。例如:
```
unsigned char ASK_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x01, 0x81, 0x01, 0x00, 0x0C, 0x71, 0x88};
unsigned char REPLY_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x0D, 0x01, 0xAA, 0x89};
```
&emsp;&emsp;流水号管理发送方和接收方互相独立,各自往外发的协议中流水号存在重复的可能,接收方直接复制回传即可。
&emsp;&emsp;流水号必须大于等于10用于代码初始化值代码意义上表示无效的流水号。
**协议收发匹配逻辑**
&emsp;&emsp;协议发送时,附带自管理的流水号,对端回复时,根据流水号绑定发送的协议,为了避免对端回复时,流水号错误导致的业务逻辑错乱,本端除了匹配流水号,还需要根据协议匹配回复的命令字,保证回复内容的有效匹配。如果流水号和命令字无法同时匹配,该回复的数据包被丢弃。
**校验码算法**
&emsp;&emsp;校验码算法使用ModBus CRC16方法计算。
**参考代码(查表法)**
```
/* Table of CRC values for highorder byte */
unsigned char chCRCHi[] ={
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
};
/* Table of CRC values for loworder byte */
unsigned char chCRCLo[] ={
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
};
/**
* @brief 计算校验和
*
* @param pData 数据指针
* @param length 数据长度
* @return unsigned short
*/
unsigned short calculate_check_sum(const unsigned char* pData, unsigned short length)
{
unsigned char CRCHi = 0xFF;
unsigned char CRCLo = 0xFF;
int uIndex;
while (length--)
{
uIndex = CRCHi ^ *pData++;
CRCHi = CRCLo ^ chCRCHi[uIndex];
CRCLo = chCRCLo[uIndex];
}
return (CRCHi << 8 | CRCLo);
}
```
## 1.2. 协议内容
**基本描述**
1. 大于等于0x8000的命令字由CPU发给MCU;
2. 小于0x8000的命令字由MCU发给CPU;
3. 大于0x0801而小于0xC101的命令由CPU主动发送给MCU大于等于0xC101的命令由CPU回复发送给MCU
4. 问答型协议只有按位最高位相反其它位相等例如0x8101与0x0101是一问一答的协议
| 命令字 | CPU | MCU | 数据段 | 协议解析 | 备注 |
| ---- | ---- | ---- | ---- | ---- | ---- |
| 0x8101 | ask | - | - | 获取启动模式 | - |
| 0x0101 | - | reply | Data[0]:启动模式<br>0x01:PIR启动 <br>0x02:TEST启动 <br>0x03:ON启动 <br>0x04:连拍启动 <br>0x05:PIR延时启动 <br>0x06:定时(间隔一定时间)启动 <br>0x07:关机 <br>0x08:低电关机 <br>0x09:异常启动 | 回复启动模式 | 异常启动数据Data[1]<br>0x00:喂狗异常启动<br>0x01:超时异常启动 |
| 0x8102 | ask | - | - | 断电关机 | 断电关机不用回复 |
| 0x8103 | ask | - | - | 喂狗 | 喂狗不用回复 |
| 0x8104 | ask | - | Data[2]两字节的数字单位s | 设置喂狗周期 | 0s代表关闭喂狗 修改为两个字节单位s |
| 0x0104 | - | reply | Data[0]:结果<br>0x01:成功<br>0x02:失败 | 设置喂狗周期回复 | - |
| 0x8105 | ask | - | - | 关闭狗 | 取消 |
| 0x0105 | - | reply | Data[0]:结果<br>0x01:成功<br>0x02:失败 | 关闭狗回复 | 取消 |
| 0x8106 | ask | - | Data[0]:Hour<br>0-23<br>Data[1]:Min<br>0-59<br>Data[2]:Sec<br>0-59 | 设置间隔启动时间 | 定时启动 |
| 0x0106 | - | reply | Data[0]:结果<br>0x01:成功<br>0x02:失败 | 设置间隔启动时间回复 | - |
| 0x8107 | ask | - | Data[0]:Year<br>0-255<br>Data[1]:Mon<br>1-12<br>Data[2]:Day<br>0-31<br>Data[3]:Hour<br>0-23<br>Data[4]:Min<br>0-59<br>Data[5]:Sec<br>0-59 | 设置日期和时间 | 年份需要+1970修正 |
| 0x0107 | - | reply | Data[0]:结果<br>0x01:成功<br>0x02:失败 | 设置日期和时间回复 | - |
| 0x8108 | ask | - | Data[0]:灵敏度<br>0-9 | 设置PIR灵敏度 | - |
| 0x0108 | - | reply | Data[0]:结果<br>0x01:成功<br>0x02:失败 | 设置PIR灵敏度回复 | - |
| 0x8109 | ask | - | Data[0]连拍间隔单位s | 设置连拍启动 | 设置连拍启动后会立即关机一般连拍间隔较大时使用该功能连拍间隔较小时Linux单次完成连拍。 |
| 0x0109 | - | reply | Data[0]:结果<br>0x01:成功<br>0x02:失败 | 设置连拍启动回复 | - |
| 0x810A | ask | - | Data[0]:控制模式<br>0-关闭红外灯<br>1-开启红外灯 | 红外灯控制 | 取消 |
| 0x010A | - | reply | Data[0]:结果<br>0x01:成功<br>0x02:失败 | 红外灯控制回复 | 取消 |
| 0x810B | ask | - | - | 获取光敏值 | 取消 |
| 0x010B | - | reply | Data[0]:结果<br>0-100 | 获取光敏值回复 | 取消 |
| ====== | === | ====== | ============================ | ==================== | ======= |
| 0xC101 | reply | - | Data[0]:结果<br>0x01:成功<br>0x02:失败 | 发送启动模式回复 | - |
| 0x4101 | - | ask | Data[0]:启动模式<br>0x01:PIR启动 <br>0x02:TEST启动 <br>0x03:ON启动 <br>0x04:连拍启动 <br>0x05:PIR延时启动 <br>0x06:定时(间隔一定时间)启动 <br>0x07:关机 <br>0x08:低电关机 <br>0x09:异常启动 | 发送启动模式 | 异常启动数据Data[1]<br>0x00:喂狗异常启动<br>0x01:超时异常启动 |
| 0xC102 | reply | - | - | 回复心跳包 | 取消 |
| 0x4102 | - | ask | - | 发送心跳包 | 取消 |
| 0xC106 | reply | - | Data[0]:Hour<br>0-23<br>Data[1]:Min<br>0-59<br>Data[2]:Sec<br>0-59 | 回复获取间隔启动时间 | - |
| 0x4106 | - | ask | - | 获取间隔启动时间 | - |
| 0xC107 | reply | - | Data[0]:Year<br>0-255<br>Data[1]:Mon<br>1-12<br>Data[2]:Day<br>0-31<br>Data[3]:Hour<br>0-23<br>Data[4]:Min<br>0-59<br>Data[5]:Sec<br>0-59 | 回复获取日期和时间 | 年份需要+1970修正 |
| 0x4107 | - | ask | - | 获取日期和时间 | - |
| 0xC108 | reply | - | Data[0]:灵敏度<br>0-9 | 回复获取PIR灵敏度 | - |
| 0x4108 | - | ask | - | 获取PIR灵敏度 | - |
### 1.2.1. 名词解析
| 名词 | 解析 |
| ---- | ---- |
| 超时异常启动 | MCU给主控上电后**非TEST启动**不管主控是否正常喂狗如果单次上电时长超过3min未关机给主控断电重启一次。 |
| 间隔启动时间 | 例如60min/次。 |