412 lines
8.2 KiB
Markdown
412 lines
8.2 KiB
Markdown
# TCP2UART AT 固件使用手册
|
||
|
||
## 1. 文档范围
|
||
|
||
本文档定义 `TCP2UART` 项目的最终 AT 外部协议。
|
||
|
||
本文档只描述最终协议模型,不保留任何历史展开式实例字段,不包含测试记录,不讨论旧版兼容命令。
|
||
|
||
适用对象:
|
||
|
||
- 上位机开发人员
|
||
- 联调与测试人员
|
||
- 固件接口实现人员
|
||
|
||
## 2. 设备与接口
|
||
|
||
- 主控:`STM32F103R8T6`
|
||
- 以太网芯片:`CH390D`
|
||
- 配置口:`USART1`
|
||
- 数据口:`USART2`、`USART3`
|
||
|
||
职责划分:
|
||
|
||
- `USART1`:AT 配置口
|
||
- `USART2 / USART3`:业务数据口,可工作于普通透传或 MUX 透传模式
|
||
|
||
## 3. 最终协议模型
|
||
|
||
本项目最终控制协议由三部分组成:
|
||
|
||
1. `MUX`:全局数据承载模式开关
|
||
2. `NET`:全局静态网络配置记录
|
||
3. `LINK[ROLE]`:按角色名组织的链路配置记录(`S1/S2/C1/C2`)
|
||
|
||
约束如下:
|
||
|
||
- 设备只有一张网卡,因此本地网络参数只配置一次
|
||
- DHCP 不属于最终协议范围
|
||
- 所有 AT 文本命令必须以 `\r\n` 结尾
|
||
- 当 `DSTMASK=0x00` 时,MUX 数据口中的系统控制帧进入 AT 解析路径,其控制文本同样必须以 `\r\n` 结尾
|
||
|
||
## 4. MUX 帧格式
|
||
|
||
当 `MUX=1` 时,数据口使用如下帧格式:
|
||
|
||
```text
|
||
SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL
|
||
```
|
||
|
||
字段定义:
|
||
|
||
- `SYNC`:帧起始标记,建议固定为 `0x7E`
|
||
- `LEN_H / LEN_L`:`PAYLOAD` 长度,高字节在前
|
||
- `SRCID`:单字节源端点 ID
|
||
- `DSTMASK`:单字节目标端点位图
|
||
- `PAYLOAD`:负载数据
|
||
- `TAIL`:帧结束标记,建议固定为 `0x7F`
|
||
|
||
规则:
|
||
|
||
- `DSTMASK != 0x00`:业务数据帧
|
||
- `DSTMASK = 0x00`:系统控制帧
|
||
- 系统控制帧的 `PAYLOAD` 为 AT 文本,必须以 `\r\n` 结束
|
||
|
||
## 5. 统一端点编码
|
||
|
||
`UART` 与 `TCP` 逻辑实例统一进入同一套编码空间:
|
||
|
||
| 端点 | 编码 |
|
||
|------|------|
|
||
| `C1` | `0x01` |
|
||
| `C2` | `0x02` |
|
||
| `UART2` | `0x04` |
|
||
| `UART3` | `0x08` |
|
||
| `S1` | `0x10` |
|
||
| `S2` | `0x20` |
|
||
|
||
说明:
|
||
|
||
- `SRCID` 必须为单一端点值
|
||
- `DSTMASK` 可以是一个或多个端点编码按位或的结果
|
||
- `DSTMASK=0x00` 保留给系统控制帧
|
||
|
||
## 6. AT 命令总则
|
||
|
||
### 6.1 命令结尾
|
||
|
||
所有 AT 命令均必须以 `\r\n` 结尾。
|
||
|
||
例如:
|
||
|
||
```text
|
||
AT\r\n
|
||
AT+MUX?\r\n
|
||
AT+NET=192.168.1.100,255.255.255.0,192.168.1.1,02:00:00:00:00:01\r\n
|
||
```
|
||
|
||
### 6.2 持久化规则
|
||
|
||
参数设置成功后只写入当前运行配置,不会自动写入 Flash。
|
||
|
||
若要掉电保持,必须执行:
|
||
|
||
1. `AT+SAVE\r\n`
|
||
2. `AT+RESET\r\n`
|
||
|
||
### 6.3 响应风格
|
||
|
||
- 成功:`OK`
|
||
- 需要保存后生效时,允许追加提示文本
|
||
- 失败:`ERROR: <reason>`
|
||
|
||
## 7. 默认配置
|
||
|
||
### 7.1 MUX 默认值
|
||
|
||
```text
|
||
MUX = 0
|
||
```
|
||
|
||
### 7.2 NET 默认值
|
||
|
||
```text
|
||
NET = 192.168.1.100,255.255.255.0,192.168.1.1,02:00:00:00:00:01
|
||
```
|
||
|
||
### 7.3 LINK 默认值
|
||
|
||
```text
|
||
LINK:S1 = 1,8080,0.0.0.0,0,U0
|
||
LINK:S2 = 0,8081,0.0.0.0,0,U1
|
||
LINK:C1 = 1,9001,192.168.1.200,9000,U1
|
||
LINK:C2 = 0,9002,192.168.1.201,9001,U0
|
||
```
|
||
|
||
说明:
|
||
|
||
- `S1/S2/C1/C2` 为对外可见角色名
|
||
- 内部索引映射由固件管理,不对外暴露
|
||
|
||
UART 记号约定:
|
||
|
||
- `U0 = USART2`
|
||
- `U1 = USART3`
|
||
|
||
## 8. AT 命令定义
|
||
|
||
### 8.1 测试设备在线
|
||
|
||
命令:
|
||
|
||
```text
|
||
AT\r\n
|
||
```
|
||
|
||
返回:
|
||
|
||
```text
|
||
OK
|
||
```
|
||
|
||
### 8.2 查询摘要
|
||
|
||
命令:
|
||
|
||
```text
|
||
AT+?\r\n
|
||
AT+QUERY\r\n
|
||
```
|
||
|
||
推荐返回格式:
|
||
|
||
```text
|
||
+NET:IP=192.168.1.100,MASK=255.255.255.0,GW=192.168.1.1,MAC=02:00:00:00:00:01
|
||
+LINK:S1,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0
|
||
+LINK:S2,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1
|
||
+LINK:C1,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1
|
||
+LINK:C2,EN=0,LPORT=9002,RIP=192.168.1.201,RPORT=9001,UART=U0
|
||
+MUX:0
|
||
+MAP:UART2=0x04,UART3=0x08,C1=0x01,C2=0x02,S1=0x10,S2=0x20
|
||
+BAUD:U0=115200,U1=115200
|
||
OK
|
||
```
|
||
|
||
### 8.3 MUX 类命令
|
||
|
||
#### 设置 MUX
|
||
|
||
```text
|
||
AT+MUX=1\r\n
|
||
```
|
||
|
||
参数:
|
||
|
||
- `0`:普通透传模式
|
||
- `1`:MUX 透传模式
|
||
|
||
查询:
|
||
|
||
```text
|
||
AT+MUX?\r\n
|
||
```
|
||
|
||
返回示例:
|
||
|
||
```text
|
||
+MUX:1
|
||
OK
|
||
```
|
||
|
||
### 8.4 NET 类命令
|
||
|
||
#### 设置 NET
|
||
|
||
```text
|
||
AT+NET=192.168.1.100,255.255.255.0,192.168.1.1,02:00:00:00:00:01\r\n
|
||
```
|
||
|
||
字段顺序:
|
||
|
||
```text
|
||
IP,MASK,GW,MAC
|
||
```
|
||
|
||
查询:
|
||
|
||
```text
|
||
AT+NET?\r\n
|
||
```
|
||
|
||
返回示例:
|
||
|
||
```text
|
||
+NET:IP=192.168.1.100,MASK=255.255.255.0,GW=192.168.1.1,MAC=02:00:00:00:00:01
|
||
OK
|
||
```
|
||
|
||
**MAC 设置说明:**
|
||
|
||
当MAC设置为全0时,固件将使用硬件MAC地址,此时通过AT+?查询到的MAC地址即为当前生效的硬件MAC地址。
|
||
|
||
### 8.5 LINK 类命令
|
||
|
||
#### 设置单条 LINK 记录
|
||
|
||
```text
|
||
AT+LINK=S1,1,8080,0.0.0.0,0,U0\r\n
|
||
AT+LINK=C1,1,9001,192.168.1.200,9000,U1\r\n
|
||
```
|
||
|
||
字段顺序:
|
||
|
||
```text
|
||
ROLE,EN,LPORT,RIP,RPORT,UART
|
||
```
|
||
|
||
字段说明:
|
||
|
||
- `ROLE`:链路角色名,固定为 `S1/S2/C1/C2`
|
||
- `EN`:`0/1`
|
||
- `LPORT`:本地端口
|
||
- `RIP`:对端 IP
|
||
- `RPORT`:对端端口
|
||
- `UART`:`U0/U1`
|
||
|
||
说明:
|
||
|
||
- `Server` 与 `Client` 共用同一条 `LINK` 记录模型
|
||
- `Server` 中 `RIP/RPORT` 可作为允许接入的对端约束或预设对端信息
|
||
- `Client` 中 `RIP/RPORT` 表示远端目标地址与端口
|
||
|
||
#### 查询单条 LINK
|
||
|
||
```text
|
||
AT+LINK=S1\r\n
|
||
```
|
||
|
||
返回示例:
|
||
|
||
```text
|
||
+LINK:S1,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0
|
||
OK
|
||
```
|
||
|
||
#### 查询全部 LINK
|
||
|
||
```text
|
||
AT+LINK?\r\n
|
||
```
|
||
|
||
返回示例:
|
||
|
||
```text
|
||
+LINK:S1,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0
|
||
+LINK:S2,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1
|
||
+LINK:C1,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1
|
||
+LINK:C2,EN=0,LPORT=9002,RIP=192.168.1.201,RPORT=9001,UART=U0
|
||
OK
|
||
```
|
||
|
||
## 9. 保存与复位命令
|
||
|
||
### 9.1 保存配置
|
||
|
||
```text
|
||
AT+SAVE\r\n
|
||
```
|
||
|
||
成功返回:
|
||
|
||
```text
|
||
OK: Configuration saved
|
||
```
|
||
|
||
### 9.2 软件复位
|
||
|
||
```text
|
||
AT+RESET\r\n
|
||
```
|
||
|
||
返回:
|
||
|
||
```text
|
||
OK: Resetting...
|
||
```
|
||
|
||
### 9.3 恢复默认值
|
||
|
||
```text
|
||
AT+DEFAULT\r\n
|
||
```
|
||
|
||
返回:
|
||
|
||
```text
|
||
OK: Defaults restored
|
||
```
|
||
|
||
## 10. 常见错误返回
|
||
|
||
| 场景 | 返回 |
|
||
|------|------|
|
||
| 未知命令 | `ERROR: Unknown command` |
|
||
| 非法端口 | `ERROR: Invalid port` |
|
||
| 非法波特率 | `ERROR: Invalid baudrate` |
|
||
| 非法 IP 地址 | `ERROR: Invalid IP format` |
|
||
| 非法掩码 | `ERROR: Invalid mask format` |
|
||
| 非法网关 | `ERROR: Invalid gateway format` |
|
||
| 非法远端 IP | `ERROR: Invalid remote IP format` |
|
||
| 非法 MAC | `ERROR: Invalid MAC format` |
|
||
| 非法 `SRCID` / `DSTMASK` | `ERROR: Invalid route field` |
|
||
| Flash 保存失败 | `ERROR: Save failed` |
|
||
|
||
## 11. 推荐配置流程
|
||
|
||
```text
|
||
AT+NET=192.168.1.123,255.255.255.0,192.168.1.1,02:00:00:00:00:01\r\n
|
||
AT+LINK=S1,1,10001,0.0.0.0,0,U1\r\n
|
||
AT+LINK=S2,1,10003,0.0.0.0,0,U1\r\n
|
||
AT+LINK=C1,1,20001,192.168.1.201,10002,U0\r\n
|
||
AT+MUX=1\r\n
|
||
AT+SAVE\r\n
|
||
AT+RESET\r\n
|
||
```
|
||
|
||
## 12. 故障排查建议
|
||
|
||
### 12.1 发送 `AT` 没有返回
|
||
|
||
优先检查:
|
||
|
||
1. 是否连接到 `USART1`
|
||
2. 串口参数是否为 `115200 8N1`
|
||
3. 是否严格使用 `\r\n` 作为命令结尾
|
||
4. 接线是否正确
|
||
5. 设备是否正常上电运行
|
||
|
||
### 12.2 设置成功但重启后参数丢失
|
||
|
||
检查是否漏掉以下步骤:
|
||
|
||
1. `AT+SAVE\r\n`
|
||
2. `AT+RESET\r\n`
|
||
|
||
### 12.3 MUX 模式数据口有丢包
|
||
|
||
若 `MUX=1` 下出现“主机侧已发送,但设备对端收到数量明显偏少”的现象,优先按以下顺序检查:
|
||
|
||
1. 固件版本是否已经包含 `2026-04-18` 的 MUX 丢包修复。
|
||
2. MUX 帧是否完整,尤其是:
|
||
- `SYNC=0x7E`
|
||
- `LEN_H/LEN_L`
|
||
- `SRCID`
|
||
- `DSTMASK`
|
||
- `TAIL=0x7F`
|
||
3. 上位机发送方式是否把一帧拆成多个不连续小片段,或在帧间插入无效字节。
|
||
4. TCP 对端是否出现拥塞、窗口缩小或应用层不及时取数,导致发送路径出现背压。
|
||
5. RTT 中是否存在链路错误、发送失败或持续重连现象。
|
||
|
||
当前版本的修复点如下:
|
||
|
||
1. MUX 解析器改为在整帧完整到齐前不推进 UART RX ring 读指针,避免半帧被破坏性消费。
|
||
2. TCP 发送路径与 UART 写入路径不再把背压和短写静默视为成功,便于及早暴露链路承载问题。
|
||
|
||
现场回归结果:在修复后的固件中,MUX 模式持续发送 `670` 包,接收端 `670` 包全部到达,`0` 丢包。
|
||
|
||
## 13. 相关文件
|
||
|
||
- AT 命令实现:[config.c](/D:/code/STM32Project/TCP2UART/App/config.c)
|
||
- 配置结构与默认值:[config.h](/D:/code/STM32Project/TCP2UART/App/config.h)
|
||
- 调试与测试记录:[uart-ch390-debug-handoff.md](/D:/code/STM32Project/TCP2UART/uart-ch390-debug-handoff.md)
|