314 lines
7.9 KiB
Markdown
314 lines
7.9 KiB
Markdown
# USB CDC 串口通信协议规范
|
||
|
||
## 概述
|
||
|
||
本协议定义了上位机(PC)与设备之间通过USB CDC进行音频数据传输和命令控制的通信格式。协议采用二进制帧格式,支持命令、音频数据和MD5校验等功能。
|
||
|
||
## 协议版本
|
||
|
||
- 版本号:1.0
|
||
- 更新日期:2026-01-07
|
||
|
||
## 帧格式
|
||
|
||
### 基本帧结构
|
||
|
||
```
|
||
+--------+--------+--------+--------+--------+--------+
|
||
| Magic | Type | Length | Data | Check |
|
||
| 2 Bytes| 1 Byte | 4 Bytes | N Bytes| 1 Byte |
|
||
+--------+--------+--------+--------+--------+--------+
|
||
```
|
||
|
||
**注意:** 音频数据帧(Type=0x03)的Check字段固定填充为0x00,不进行实际校验计算,保持协议格式一致性。
|
||
|
||
### 字段说明
|
||
|
||
| 字段 | 长度 | 说明 |
|
||
|------|------|------|
|
||
| Magic | 2 字节 | 魔数,固定为 `0xAA55`(大端序),用于帧同步 |
|
||
| Type | 1 字节 | 数据类型,见下表 |
|
||
| Length | 4 字节 | 数据长度(小端序),仅指Data字段的长度<br>**命令/响应/MD5帧**: ≤64字节<br>|
|
||
| Data | N 字节 | 实际数据内容,长度由Length字段指定 |
|
||
| Check | 1 字节 | 校验和,对整个帧(除Check字段外)进行XOR校验<br>**音频帧固定填充0x00** |
|
||
|
||
**数据长度限制说明:**
|
||
- 命令请求/响应/MD5帧的Data字段最大64字节
|
||
- 这种区分设计可节省非音频帧的内存占用
|
||
|
||
### 数据类型(Type)
|
||
|
||
| 类型值 | 名称 | 方向 | 说明 |
|
||
|--------|------|------|------|
|
||
| 0x01 | CMD_REQUEST | PC → 设备 | 命令请求 |
|
||
| 0x02 | CMD_RESPONSE | 设备 → PC | 命令响应 |
|
||
| 0x03 | AUDIO_DATA | 设备 → PC | 音频数据 |
|
||
| 0x04 | MD5_DATA | 设备 → PC | MD5校验值 |
|
||
|
||
## 命令定义
|
||
|
||
### 命令码
|
||
|
||
| 命令码 | 名称 | 说明 |
|
||
|--------|------|------|
|
||
| 0x01 | CMD_START_RECORD | 开始录音 |
|
||
| 0x02 | CMD_STOP_RECORD | 停止录音 |
|
||
| 0x03 | CMD_QUERY_STATUS | 查询状态 |
|
||
|
||
### 命令请求格式(CMD_REQUEST)
|
||
|
||
**Data字段格式:**
|
||
```
|
||
+--------+--------+
|
||
| CmdID | Params |
|
||
| 1 Byte | N Bytes|
|
||
+--------+--------+
|
||
```
|
||
|
||
- **CmdID**: 命令码
|
||
- **Params**: 命令参数(可选,长度根据具体命令而定)
|
||
|
||
### 命令响应格式(CMD_RESPONSE)
|
||
|
||
**Data字段格式:**
|
||
```
|
||
+--------+--------+--------+
|
||
| CmdID | Status | Data |
|
||
| 1 Byte | 1 Byte | N Bytes|
|
||
+--------+--------+--------+
|
||
```
|
||
|
||
- **CmdID**: 对应的命令码
|
||
- **Status**: 状态码(0x00=成功,0x01=失败,0x02=忙碌,0x03=不支持)
|
||
- **Data**: 响应数据(可选)
|
||
|
||
### 状态码定义
|
||
|
||
| 状态码 | 名称 | 说明 |
|
||
|--------|------|------|
|
||
| 0x00 | STATUS_OK | 命令执行成功 |
|
||
| 0x01 | STATUS_ERROR | 命令执行失败 |
|
||
| 0x02 | STATUS_BUSY | 设备忙碌 |
|
||
| 0x03 | STATUS_UNSUPPORTED | 不支持的命令 |
|
||
|
||
## 数据格式
|
||
|
||
### 音频数据(AUDIO_DATA)
|
||
|
||
**Data字段格式:**
|
||
```
|
||
+--------+--------+
|
||
| SeqNum | PCM |
|
||
| 4 Bytes| N Bytes|
|
||
+--------+--------+
|
||
```
|
||
|
||
- **SeqNum**: 序列号(小端序),用于检测丢包,从0开始递增
|
||
- **PCM**: 原始PCM音频数据
|
||
|
||
**注意:** 音频数据帧保留Check校验字节,但固定填充为0x00,不进行实际校验计算。这样保持协议格式一致性,数据完整性由最终的MD5校验保证。
|
||
|
||
### MD5数据(MD5_DATA)
|
||
|
||
**Data字段格式:**
|
||
```
|
||
+--------+
|
||
| MD5 |
|
||
|16 Bytes|
|
||
+--------+
|
||
```
|
||
|
||
- **MD5**: 音频数据的MD5哈希值(128位)
|
||
|
||
## 通信流程
|
||
|
||
### 开始录音流程
|
||
|
||
```
|
||
PC 设备
|
||
| |
|
||
|---- CMD_START_RECORD ---->|
|
||
| | 开始录音
|
||
|<--- CMD_RESPONSE(OK) -----|
|
||
| |
|
||
|<--- AUDIO_DATA(SeqNum=0)--|
|
||
|<--- AUDIO_DATA(SeqNum=1)--|
|
||
|<--- AUDIO_DATA(SeqNum=2)--|
|
||
| ... |
|
||
```
|
||
|
||
### 停止录音流程
|
||
|
||
```
|
||
PC 设备
|
||
| |
|
||
|---- CMD_STOP_RECORD ----->|
|
||
| | 停止录音
|
||
|<--- AUDIO_DATA(last) -----|
|
||
|<--- MD5_DATA -------------|
|
||
|<--- CMD_RESPONSE(OK) -----|
|
||
| |
|
||
```
|
||
|
||
### 查询状态流程
|
||
|
||
```
|
||
PC 设备
|
||
| |
|
||
|---- CMD_QUERY_STATUS ---->|
|
||
| |
|
||
|<--- CMD_RESPONSE ---------|
|
||
| (Status + Data) |
|
||
| |
|
||
```
|
||
|
||
**查询状态响应Data格式:**
|
||
```
|
||
+--------+--------+--------+--------+
|
||
| State | TotalBytes | SeqNum |
|
||
| 1 Byte | 4 Bytes | 4 Bytes|
|
||
+--------+--------+--------+--------+
|
||
```
|
||
|
||
- **State**: 当前状态(0x00=空闲,0x01=正在录音)
|
||
- **TotalBytes**: 已传输的总字节数(小端序)
|
||
- **SeqNum**: 当前序列号(小端序)
|
||
|
||
## 校验算法
|
||
|
||
### XOR校验
|
||
|
||
对除Check字段外的所有字节进行XOR运算:
|
||
|
||
```c
|
||
uint8_t calculate_checksum(uint8_t *data, uint32_t len) {
|
||
uint8_t checksum = 0;
|
||
for (uint32_t i = 0; i < len; i++) {
|
||
checksum ^= data[i];
|
||
}
|
||
return checksum;
|
||
}
|
||
```
|
||
|
||
### MD5校验
|
||
|
||
使用标准MD5算法对所有音频数据进行校验:
|
||
|
||
1. 设备端:对发送的所有PCM数据进行MD5计算
|
||
2. 停止录音后,设备发送MD5_DATA帧
|
||
3. PC端:对接收的所有PCM数据进行MD5计算并与设备端发送的MD5对比
|
||
|
||
## 示例
|
||
|
||
### 示例1:开始录音命令
|
||
|
||
**PC发送:**
|
||
```
|
||
AA 55 01 01 00 00 00 01 FA
|
||
```
|
||
|
||
解析:
|
||
- Magic: `AA 55`
|
||
- Type: `01` (CMD_REQUEST)
|
||
- Length: `01 00 00 00` (1字节,小端序)
|
||
- Data: `01` (CMD_START_RECORD)
|
||
- Check: `FA` (XOR校验)
|
||
|
||
**设备响应:**
|
||
```
|
||
AA 55 02 02 00 00 00 01 00 F8
|
||
```
|
||
|
||
解析:
|
||
- Magic: `AA 55`
|
||
- Type: `02` (CMD_RESPONSE)
|
||
- Length: `02 00 00 00` (2字节)
|
||
- Data: `01 00` (CmdID=0x01, Status=0x00成功)
|
||
- Check: `F8`
|
||
|
||
### 示例2:音频数据
|
||
|
||
**设备发送:**
|
||
```
|
||
AA 55 03 08 00 00 00 00 00 00 00 XX XX XX XX
|
||
```
|
||
|
||
解析:
|
||
- Magic: `AA 55`
|
||
- Type: `03` (AUDIO_DATA)
|
||
- Length: `08 00 00 00` (8字节)
|
||
- Data: `00 00 00 00 XX XX XX XX` (SeqNum=0, PCM数据4字节)
|
||
- Check: **无** (音频帧不包含校验字节)
|
||
|
||
### 示例3:MD5数据
|
||
|
||
**设备发送:**
|
||
```
|
||
AA 55 04 10 00 00 00 [16字节MD5] XX
|
||
```
|
||
|
||
解析:
|
||
- Magic: `AA 55`
|
||
- Type: `04` (MD5_DATA)
|
||
- Length: `10 00 00 00` (16字节)
|
||
- Data: 16字节MD5值
|
||
- Check: `XX`
|
||
|
||
## 错误处理
|
||
|
||
### 帧错误
|
||
|
||
1. **魔数错误**:丢弃当前字节,继续搜索魔数
|
||
2. **校验错误**:丢弃整个帧,请求重传(可选)
|
||
3. **长度异常**:丢弃整个帧
|
||
|
||
### 超时处理
|
||
|
||
- **命令超时**:PC端发送命令后,2秒内未收到响应视为超时
|
||
- **数据超时**:录音过程中,5秒内未收到数据视为断连
|
||
|
||
### 序列号检查
|
||
|
||
- PC端应检查音频数据的SeqNum是否连续
|
||
- 如果发现跳号,说明有数据丢失
|
||
|
||
## 实现注意事项
|
||
|
||
### 设备端(C语言)
|
||
|
||
1. **内存管理**:使用环形缓冲区管理数据帧
|
||
2. **多线程**:命令处理和数据发送应分开不同任务
|
||
3. **优先级**:命令处理优先级应高于音频数据发送
|
||
4. **MD5计算**:使用增量方式计算MD5,避免一次性读取所有数据
|
||
|
||
### PC端(Python)
|
||
|
||
1. **异步接收**:使用独立线程接收数据
|
||
2. **帧解析**:实现状态机进行帧解析,处理粘包/拆包
|
||
3. **超时机制**:实现命令超时和数据超时检测
|
||
4. **MD5对比**:实时计算接收数据的MD5,录音结束后对比
|
||
|
||
## 扩展性
|
||
|
||
协议预留了扩展空间:
|
||
|
||
1. **命令扩展**:可以添加新的命令码(0x04-0xFF)
|
||
2. **数据类型扩展**:可以添加新的数据类型(0x05-0xFF)
|
||
3. **参数扩展**:每个命令的Params字段可以自定义格式
|
||
|
||
## 参考实现
|
||
|
||
- 设备端实现:[src/middleware/usb/app_usb_cdc.c](../src/middleware/usb/app_usb_cdc.c)
|
||
- PC端实现:[tools/audio/serial_capture.py](../tools/audio/serial_capture.py)
|
||
- 协议库:[src/middleware/usb/cdc_protocol.c](../src/middleware/usb/cdc_protocol.c)
|
||
|
||
## 版本历史
|
||
|
||
| 版本 | 日期 | 说明 |
|
||
|------|------|------|
|
||
| 1.0 | 2026-01-07 | 初始版本,定义基本协议格式和命令 |
|
||
|
||
## 联系方式
|
||
|
||
如有问题或建议,请联系开发团队。
|