docs: rewrite mux/net/link protocol manuals
This commit is contained in:
+238
-496
@@ -1,137 +1,158 @@
|
|||||||
# TCP2UART AT 固件使用手册
|
# TCP2UART AT 固件使用手册
|
||||||
|
|
||||||
## 1. 文档说明
|
## 1. 文档范围
|
||||||
|
|
||||||
本文档用于说明 `TCP2UART` 固件的 `AT` 配置功能使用方法。
|
本文档定义 `TCP2UART` 项目的最终 AT 外部协议。
|
||||||
|
|
||||||
本手册适用于当前工程中的 STM32 固件版本,配置口通过 `USART1` 提供,主要用于:
|
本文档只描述最终协议模型,不保留任何历史展开式实例字段,不包含测试记录,不讨论旧版兼容命令。
|
||||||
|
|
||||||
- 查询当前设备参数
|
适用对象:
|
||||||
- 修改网络参数
|
|
||||||
- 修改串口透传参数
|
|
||||||
- 保存参数到 Flash
|
|
||||||
- 恢复默认参数
|
|
||||||
- 软件复位设备
|
|
||||||
|
|
||||||
本文档内容基于以下信息整理:
|
- 上位机开发人员
|
||||||
|
- 联调与测试人员
|
||||||
|
- 固件接口实现人员
|
||||||
|
|
||||||
- 当前代码实现 `App/config.c`、`App/config.h`
|
## 2. 设备与接口
|
||||||
- 当前默认配置定义
|
|
||||||
- 实板测试结果
|
|
||||||
- `uart-ch390-debug-handoff.md` 中已记录的 bench 经验
|
|
||||||
|
|
||||||
## 1.1 版本更新说明(2026-04-02)
|
|
||||||
|
|
||||||
为避免引入额外时序噪声与误判,当前固件已移除 CH390 的 bit-bang 诊断读路径。
|
|
||||||
|
|
||||||
当前版本仅保留 CH390 硬件 SPI 访问路径,启动探测与运行期寄存器访问均通过统一 SPI 接口执行。
|
|
||||||
|
|
||||||
## 2. 适用硬件
|
|
||||||
|
|
||||||
- 主控:`STM32F103R8T6`
|
- 主控:`STM32F103R8T6`
|
||||||
- 以太网芯片:`CH390D`
|
- 以太网芯片:`CH390D`
|
||||||
- 配置串口:`USART1`
|
- 配置口:`USART1`
|
||||||
- 透传串口:`USART2`、`USART3`
|
- 数据口:`USART2`、`USART3`
|
||||||
|
|
||||||
当前引脚用途如下:
|
职责划分:
|
||||||
|
|
||||||
- `PA9`:`USART1_TX`,配置口发送
|
- `USART1`:AT 配置口
|
||||||
- `PA10`:`USART1_RX`,配置口接收
|
- `USART2 / USART3`:业务数据口,可工作于普通透传或 MUX 透传模式
|
||||||
- `PA2/PA3`:`USART2`,对应 TCP Server 透传串口
|
|
||||||
- `PB10/PB11`:`USART3`,对应 TCP Client 透传串口
|
|
||||||
|
|
||||||
## 3. 配置口通信参数
|
## 3. 最终协议模型
|
||||||
|
|
||||||
连接配置口时,使用以下串口参数:
|
本项目最终控制协议由三部分组成:
|
||||||
|
|
||||||
- 波特率:`115200`
|
1. `MUX`:全局数据承载模式开关
|
||||||
- 数据位:`8`
|
2. `NET`:全局静态网络配置记录
|
||||||
- 校验位:`None`
|
3. `LINK[idx]`:按索引组织的链路配置记录
|
||||||
- 停止位:`1`
|
|
||||||
|
|
||||||
## 4. 最重要的使用规则
|
约束如下:
|
||||||
|
|
||||||
### 4.1 推荐使用 `\n` 作为命令结尾
|
- 设备只有一张网卡,因此本地网络参数只配置一次
|
||||||
|
- DHCP 不属于最终协议范围
|
||||||
|
- 所有 AT 文本命令必须以 `\r\n` 结尾
|
||||||
|
- 当 `DSTMASK=0x00` 时,MUX 数据口中的系统控制帧进入 AT 解析路径,其控制文本同样必须以 `\r\n` 结尾
|
||||||
|
|
||||||
这是当前固件 bench 联调中最重要的一条经验。
|
## 4. MUX 帧格式
|
||||||
|
|
||||||
在当前实板联调中,使用 `\n` 结尾是最稳妥的做法。例如:
|
当 `MUX=1` 时,数据口使用如下帧格式:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AT\n
|
SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL
|
||||||
AT+?\n
|
|
||||||
AT+IP=192.168.1.123\n
|
|
||||||
```
|
```
|
||||||
|
|
||||||
代码中的帧接收逻辑会在收到 `\r` 或 `\n` 时结束当前命令,但当前 bench 记录表明,实际使用时优先采用 `\n` 结尾更可靠。如果上位机默认发送 `\r\n` 后看起来“设备没有响应”,优先改成只发送 `\n` 再测试。
|
字段定义:
|
||||||
|
|
||||||
### 4.2 修改参数后不会立刻写入 Flash
|
- `SYNC`:帧起始标记,建议固定为 `0x7E`
|
||||||
|
- `LEN_H / LEN_L`:`PAYLOAD` 长度,高字节在前
|
||||||
|
- `SRCID`:单字节源端点 ID
|
||||||
|
- `DSTMASK`:单字节目标端点位图
|
||||||
|
- `PAYLOAD`:负载数据
|
||||||
|
- `TAIL`:帧结束标记,建议固定为 `0x7F`
|
||||||
|
|
||||||
大多数设置命令只会先修改 RAM 中的当前配置,不会自动写入 Flash。
|
规则:
|
||||||
|
|
||||||
如果要让参数在复位或重新上电后继续保持,必须执行:
|
- `DSTMASK != 0x00`:业务数据帧
|
||||||
|
- `DSTMASK = 0x00`:系统控制帧
|
||||||
|
- 系统控制帧的 `PAYLOAD` 为 AT 文本,必须以 `\r\n` 结束
|
||||||
|
|
||||||
1. `AT+SAVE`
|
## 5. 统一端点编码
|
||||||
2. `AT+RESET`
|
|
||||||
|
|
||||||
### 4.3 `AT+DEFAULT` 只恢复当前默认值,不自动保存
|
`UART` 与 `TCP` 逻辑实例统一进入同一套编码空间:
|
||||||
|
|
||||||
执行 `AT+DEFAULT` 后,当前参数会恢复为默认值,但如果要让默认值持久生效,仍然需要:
|
| 端点 | 编码 |
|
||||||
|
|------|------|
|
||||||
1. `AT+SAVE`
|
| `C1` | `0x01` |
|
||||||
2. `AT+RESET`
|
| `C2` | `0x02` |
|
||||||
|
| `UART2` | `0x04` |
|
||||||
## 5. 默认参数
|
| `UART3` | `0x08` |
|
||||||
|
| `S1` | `0x10` |
|
||||||
当前固件默认值如下:
|
| `S2` | `0x20` |
|
||||||
|
|
||||||
| 参数 | 默认值 |
|
|
||||||
|------|--------|
|
|
||||||
| MAC | `02:00:00:00:00:01` |
|
|
||||||
| DHCP | `0` |
|
|
||||||
| IP | `192.168.1.100` |
|
|
||||||
| MASK | `255.255.255.0` |
|
|
||||||
| GW | `192.168.1.1` |
|
|
||||||
| PORT | `8080` |
|
|
||||||
| RIP | `192.168.1.200` |
|
|
||||||
| RPORT | `9000` |
|
|
||||||
| BAUD1 | `115200` |
|
|
||||||
| BAUD2 | `115200` |
|
|
||||||
|
|
||||||
说明:
|
说明:
|
||||||
|
|
||||||
- `BAUD1` 对应 `USART2`,即 TCP Server 对应的透传串口
|
- `SRCID` 必须为单一端点值
|
||||||
- `BAUD2` 对应 `USART3`,即 TCP Client 对应的透传串口
|
- `DSTMASK` 可以是一个或多个端点编码按位或的结果
|
||||||
|
- `DSTMASK=0x00` 保留给系统控制帧
|
||||||
|
|
||||||
## 6. AT 命令总览
|
## 6. AT 命令总则
|
||||||
|
|
||||||
当前固件支持以下命令:
|
### 6.1 命令结尾
|
||||||
|
|
||||||
- `AT`
|
所有 AT 命令均必须以 `\r\n` 结尾。
|
||||||
- `AT+?`
|
|
||||||
- `AT+QUERY`
|
|
||||||
- `AT+IP=...`
|
|
||||||
- `AT+MASK=...`
|
|
||||||
- `AT+GW=...`
|
|
||||||
- `AT+RIP=...`
|
|
||||||
- `AT+MAC=...`
|
|
||||||
- `AT+PORT=...`
|
|
||||||
- `AT+RPORT=...`
|
|
||||||
- `AT+BAUD1=...`
|
|
||||||
- `AT+BAUD2=...`
|
|
||||||
- `AT+DHCP=0`
|
|
||||||
- `AT+SAVE`
|
|
||||||
- `AT+RESET`
|
|
||||||
- `AT+DEFAULT`
|
|
||||||
|
|
||||||
## 7. 命令详细说明
|
例如:
|
||||||
|
|
||||||
### 7.1 测试设备在线
|
```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
|
||||||
|
LINK0 = 1,8080,0.0.0.0,0,U0
|
||||||
|
LINK1 = 0,8081,0.0.0.0,0,U1
|
||||||
|
LINK2 = 1,9001,192.168.1.200,9000,U1
|
||||||
|
LINK3 = 0,9002,192.168.1.201,9001,U0
|
||||||
|
```
|
||||||
|
|
||||||
|
固定索引映射:
|
||||||
|
|
||||||
|
- `0 = S1`
|
||||||
|
- `1 = S2`
|
||||||
|
- `2 = C1`
|
||||||
|
- `3 = C2`
|
||||||
|
|
||||||
|
UART 记号约定:
|
||||||
|
|
||||||
|
- `U0 = USART2`
|
||||||
|
- `U1 = USART3`
|
||||||
|
|
||||||
|
## 8. AT 命令定义
|
||||||
|
|
||||||
|
### 8.1 测试设备在线
|
||||||
|
|
||||||
命令:
|
命令:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AT\n
|
AT\r\n
|
||||||
```
|
```
|
||||||
|
|
||||||
返回:
|
返回:
|
||||||
@@ -140,305 +161,147 @@ AT\n
|
|||||||
OK
|
OK
|
||||||
```
|
```
|
||||||
|
|
||||||
用途:
|
### 8.2 查询摘要
|
||||||
|
|
||||||
- 用于确认配置口通信正常
|
命令:
|
||||||
|
|
||||||
### 7.2 查询当前参数
|
|
||||||
|
|
||||||
命令 1:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AT+?\n
|
AT+?\r\n
|
||||||
|
AT+QUERY\r\n
|
||||||
```
|
```
|
||||||
|
|
||||||
命令 2:
|
推荐返回格式:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AT+QUERY\n
|
+NET:IP=192.168.1.100,MASK=255.255.255.0,GW=192.168.1.1,MAC=02:00:00:00:00:01
|
||||||
|
+LINK:0,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0
|
||||||
|
+LINK:1,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1
|
||||||
|
+LINK:2,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1
|
||||||
|
+LINK:3,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
|
```text
|
||||||
MAC: 02:00:00:00:00:01
|
+MUX:1
|
||||||
DHCP: 0
|
|
||||||
IP: 192.168.1.100
|
|
||||||
MASK: 255.255.255.0
|
|
||||||
GW: 192.168.1.1
|
|
||||||
PORT: 8080
|
|
||||||
RIP: 192.168.1.200
|
|
||||||
RPORT: 9000
|
|
||||||
BAUD1: 115200
|
|
||||||
BAUD2: 115200
|
|
||||||
```
|
|
||||||
|
|
||||||
用途:
|
|
||||||
|
|
||||||
- 查询当前运行配置
|
|
||||||
- 可用于保存前后、复位前后对比参数是否一致
|
|
||||||
|
|
||||||
### 7.3 设置设备 IP 地址
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+IP=192.168.1.123\n
|
|
||||||
```
|
|
||||||
|
|
||||||
成功返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
OK
|
OK
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
```
|
||||||
|
|
||||||
失败返回:
|
### 8.4 NET 类命令
|
||||||
|
|
||||||
|
#### 设置 NET
|
||||||
|
|
||||||
```text
|
```text
|
||||||
ERROR: Invalid IP format
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.5 LINK 类命令
|
||||||
|
|
||||||
|
#### 设置单条 LINK 记录
|
||||||
|
|
||||||
|
```text
|
||||||
|
AT+LINK=0,1,8080,0.0.0.0,0,U0\r\n
|
||||||
|
AT+LINK=2,1,9001,192.168.1.200,9000,U1\r\n
|
||||||
|
```
|
||||||
|
|
||||||
|
字段顺序:
|
||||||
|
|
||||||
|
```text
|
||||||
|
IDX,EN,LPORT,RIP,RPORT,UART
|
||||||
|
```
|
||||||
|
|
||||||
|
字段说明:
|
||||||
|
|
||||||
|
- `IDX`:实例索引,固定为 `0..3`
|
||||||
|
- `EN`:`0/1`
|
||||||
|
- `LPORT`:本地端口
|
||||||
|
- `RIP`:对端 IP
|
||||||
|
- `RPORT`:对端端口
|
||||||
|
- `UART`:`U0/U1`
|
||||||
|
|
||||||
说明:
|
说明:
|
||||||
|
|
||||||
- 推荐使用标准 IPv4 点分十进制格式
|
- `Server` 与 `Client` 共用同一条 `LINK` 记录模型
|
||||||
- 当前参数会立即更新到 RAM
|
- `Server` 中 `RIP/RPORT` 可作为允许接入的对端约束或预设对端信息
|
||||||
- 需要 `AT+SAVE` 和 `AT+RESET` 后才会以持久配置重新启动
|
- `Client` 中 `RIP/RPORT` 表示远端目标地址与端口
|
||||||
|
|
||||||
### 7.4 设置子网掩码
|
#### 查询单条 LINK
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AT+MASK=255.255.255.0\n
|
AT+LINK=0\r\n
|
||||||
```
|
```
|
||||||
|
|
||||||
成功返回:
|
返回示例:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
+LINK:0,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0
|
||||||
OK
|
OK
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
```
|
||||||
|
|
||||||
失败返回:
|
#### 查询全部 LINK
|
||||||
|
|
||||||
```text
|
```text
|
||||||
ERROR: Invalid mask format
|
AT+LINK?\r\n
|
||||||
```
|
```
|
||||||
|
|
||||||
### 7.5 设置网关
|
返回示例:
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+GW=192.168.1.1\n
|
|
||||||
```
|
|
||||||
|
|
||||||
成功返回:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
+LINK:0,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0
|
||||||
|
+LINK:1,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1
|
||||||
|
+LINK:2,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1
|
||||||
|
+LINK:3,EN=0,LPORT=9002,RIP=192.168.1.201,RPORT=9001,UART=U0
|
||||||
OK
|
OK
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
```
|
||||||
|
|
||||||
失败返回:
|
## 9. 保存与复位命令
|
||||||
|
|
||||||
|
### 9.1 保存配置
|
||||||
|
|
||||||
```text
|
```text
|
||||||
ERROR: Invalid gateway format
|
AT+SAVE\r\n
|
||||||
```
|
|
||||||
|
|
||||||
### 7.6 设置远端服务器 IP
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+RIP=192.168.1.201\n
|
|
||||||
```
|
|
||||||
|
|
||||||
成功返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
OK
|
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
|
||||||
|
|
||||||
失败返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ERROR: Invalid remote IP format
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- 该参数用于 TCP Client 主动连接的目标地址
|
|
||||||
|
|
||||||
### 7.7 设置 MAC 地址
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+MAC=02:12:34:56:78:9A\n
|
|
||||||
```
|
|
||||||
|
|
||||||
成功返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
OK
|
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
|
||||||
|
|
||||||
失败返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ERROR: Invalid MAC format
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- 推荐使用 `:` 分隔的标准 MAC 字符串
|
|
||||||
- 当前实现也兼容 `-` 分隔格式
|
|
||||||
|
|
||||||
### 7.8 设置 TCP Server 监听端口
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+PORT=10001\n
|
|
||||||
```
|
|
||||||
|
|
||||||
成功返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
OK
|
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
|
||||||
|
|
||||||
失败返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ERROR: Invalid port
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- 推荐使用 `1 ~ 65535` 范围内的十进制端口号
|
|
||||||
|
|
||||||
### 7.9 设置 TCP Client 远端端口
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+RPORT=10002\n
|
|
||||||
```
|
|
||||||
|
|
||||||
成功返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
OK
|
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
|
||||||
|
|
||||||
失败返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ERROR: Invalid port
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- 推荐使用 `1 ~ 65535` 范围内的十进制端口号
|
|
||||||
|
|
||||||
### 7.10 设置 USART2 波特率
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+BAUD1=57600\n
|
|
||||||
```
|
|
||||||
|
|
||||||
成功返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
OK
|
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
|
||||||
|
|
||||||
失败返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ERROR: Invalid baudrate
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- `BAUD1` 对应 `USART2`
|
|
||||||
- 推荐使用 `1200 ~ 921600` 范围内的标准波特率值
|
|
||||||
|
|
||||||
### 7.11 设置 USART3 波特率
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+BAUD2=38400\n
|
|
||||||
```
|
|
||||||
|
|
||||||
成功返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
OK
|
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
|
||||||
|
|
||||||
失败返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ERROR: Invalid baudrate
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- `BAUD2` 对应 `USART3`
|
|
||||||
- 推荐使用 `1200 ~ 921600` 范围内的标准波特率值
|
|
||||||
|
|
||||||
### 7.12 设置 DHCP
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+DHCP=0\n
|
|
||||||
```
|
|
||||||
|
|
||||||
成功返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
OK
|
|
||||||
Note: Use AT+SAVE then AT+RESET to apply changes
|
|
||||||
```
|
|
||||||
|
|
||||||
失败返回 1:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ERROR: Invalid value
|
|
||||||
```
|
|
||||||
|
|
||||||
失败返回 2:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ERROR: DHCP disabled in this build
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- 当前固件构建不支持 DHCP
|
|
||||||
- 因此 `AT+DHCP=1` 会明确返回失败
|
|
||||||
- 当前版本建议固定使用静态 IP
|
|
||||||
|
|
||||||
### 7.13 保存参数到 Flash
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+SAVE\n
|
|
||||||
```
|
```
|
||||||
|
|
||||||
成功返回:
|
成功返回:
|
||||||
@@ -447,23 +310,10 @@ AT+SAVE\n
|
|||||||
OK: Configuration saved
|
OK: Configuration saved
|
||||||
```
|
```
|
||||||
|
|
||||||
失败返回:
|
### 9.2 软件复位
|
||||||
|
|
||||||
```text
|
```text
|
||||||
ERROR: Save failed
|
AT+RESET\r\n
|
||||||
```
|
|
||||||
|
|
||||||
用途:
|
|
||||||
|
|
||||||
- 将当前 RAM 中的配置写入 Flash
|
|
||||||
- 只有执行成功后,参数才会在复位后保留
|
|
||||||
|
|
||||||
### 7.14 软件复位设备
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+RESET\n
|
|
||||||
```
|
```
|
||||||
|
|
||||||
返回:
|
返回:
|
||||||
@@ -472,17 +322,10 @@ AT+RESET\n
|
|||||||
OK: Resetting...
|
OK: Resetting...
|
||||||
```
|
```
|
||||||
|
|
||||||
用途:
|
### 9.3 恢复默认值
|
||||||
|
|
||||||
- 请求设备执行软件复位
|
|
||||||
- 通常用于 `AT+SAVE` 之后让新配置重新生效
|
|
||||||
|
|
||||||
### 7.15 恢复默认参数
|
|
||||||
|
|
||||||
命令:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AT+DEFAULT\n
|
AT+DEFAULT\r\n
|
||||||
```
|
```
|
||||||
|
|
||||||
返回:
|
返回:
|
||||||
@@ -491,14 +334,7 @@ AT+DEFAULT\n
|
|||||||
OK: Defaults restored
|
OK: Defaults restored
|
||||||
```
|
```
|
||||||
|
|
||||||
用途:
|
## 10. 常见错误返回
|
||||||
|
|
||||||
- 将当前配置恢复为固件默认值
|
|
||||||
- 如果要让默认值长期生效,仍然需要再执行 `AT+SAVE` 和 `AT+RESET`
|
|
||||||
|
|
||||||
## 8. 常见错误返回
|
|
||||||
|
|
||||||
当前固件已验证的错误返回如下:
|
|
||||||
|
|
||||||
| 场景 | 返回 |
|
| 场景 | 返回 |
|
||||||
|------|------|
|
|------|------|
|
||||||
@@ -510,133 +346,39 @@ OK: Defaults restored
|
|||||||
| 非法网关 | `ERROR: Invalid gateway format` |
|
| 非法网关 | `ERROR: Invalid gateway format` |
|
||||||
| 非法远端 IP | `ERROR: Invalid remote IP format` |
|
| 非法远端 IP | `ERROR: Invalid remote IP format` |
|
||||||
| 非法 MAC | `ERROR: Invalid MAC format` |
|
| 非法 MAC | `ERROR: Invalid MAC format` |
|
||||||
| 非法 DHCP 参数 | `ERROR: Invalid value` |
|
| 非法 `SRCID` / `DSTMASK` | `ERROR: Invalid route field` |
|
||||||
| DHCP 在当前构建中不可用 | `ERROR: DHCP disabled in this build` |
|
|
||||||
| Flash 保存失败 | `ERROR: Save failed` |
|
| Flash 保存失败 | `ERROR: Save failed` |
|
||||||
|
|
||||||
## 9. 推荐操作流程
|
## 11. 推荐配置流程
|
||||||
|
|
||||||
### 9.1 查询当前参数
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AT\n
|
AT+NET=192.168.1.123,255.255.255.0,192.168.1.1,02:00:00:00:00:01\r\n
|
||||||
AT+?\n
|
AT+LINK=0,1,10001,0.0.0.0,0,U1\r\n
|
||||||
|
AT+LINK=1,1,10003,0.0.0.0,0,U1\r\n
|
||||||
|
AT+LINK=2,1,20001,192.168.1.201,10002,U0\r\n
|
||||||
|
AT+MUX=1\r\n
|
||||||
|
AT+SAVE\r\n
|
||||||
|
AT+RESET\r\n
|
||||||
```
|
```
|
||||||
|
|
||||||
### 9.2 修改参数并永久保存
|
## 12. 故障排查建议
|
||||||
|
|
||||||
例如修改设备 IP、监听端口和远端地址:
|
### 12.1 发送 `AT` 没有返回
|
||||||
|
|
||||||
```text
|
优先检查:
|
||||||
AT+IP=192.168.1.123\n
|
|
||||||
AT+PORT=10001\n
|
|
||||||
AT+RIP=192.168.1.201\n
|
|
||||||
AT+RPORT=10002\n
|
|
||||||
AT+SAVE\n
|
|
||||||
AT+RESET\n
|
|
||||||
```
|
|
||||||
|
|
||||||
设备复位后,再执行:
|
1. 是否连接到 `USART1`
|
||||||
|
|
||||||
```text
|
|
||||||
AT+?\n
|
|
||||||
```
|
|
||||||
|
|
||||||
确认参数是否与修改值一致。
|
|
||||||
|
|
||||||
### 9.3 恢复出厂默认参数
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+DEFAULT\n
|
|
||||||
AT+SAVE\n
|
|
||||||
AT+RESET\n
|
|
||||||
AT+?\n
|
|
||||||
```
|
|
||||||
|
|
||||||
## 10. Flash 持久化说明
|
|
||||||
|
|
||||||
当前固件已在实板上验证以下保存/复位路径:
|
|
||||||
|
|
||||||
- 设置参数后执行 `AT+SAVE`
|
|
||||||
- 再执行 `AT+RESET`
|
|
||||||
- 设备重启后再次查询参数
|
|
||||||
- 查询结果与保存前一致
|
|
||||||
- 原始 Flash 参数页 `0x0800FC00` 在 reset 前后读回一致
|
|
||||||
|
|
||||||
这说明在上述测试路径下:
|
|
||||||
|
|
||||||
- 配置确实被写入 Flash
|
|
||||||
- reset 后加载流程正常
|
|
||||||
- 参数在 `设置 -> 保存 -> 复位 -> 查询` 这条路径下可以保持一致
|
|
||||||
|
|
||||||
## 11. 故障排查建议
|
|
||||||
|
|
||||||
### 11.1 发送 `AT` 没有返回
|
|
||||||
|
|
||||||
优先检查以下几项:
|
|
||||||
|
|
||||||
1. 是否连接到了 `USART1`
|
|
||||||
2. 串口参数是否为 `115200 8N1`
|
2. 串口参数是否为 `115200 8N1`
|
||||||
3. 是否优先使用 `\n` 作为命令结尾
|
3. 是否严格使用 `\r\n` 作为命令结尾
|
||||||
4. USB 转串口模块接线是否正确
|
4. 接线是否正确
|
||||||
5. 设备是否已经正常上电运行
|
5. 设备是否正常上电运行
|
||||||
|
|
||||||
### 11.2 设置成功但重启后参数丢失
|
### 12.2 设置成功但重启后参数丢失
|
||||||
|
|
||||||
检查是否漏掉了以下步骤:
|
检查是否漏掉以下步骤:
|
||||||
|
|
||||||
1. `AT+SAVE`
|
1. `AT+SAVE\r\n`
|
||||||
2. `AT+RESET`
|
2. `AT+RESET\r\n`
|
||||||
|
|
||||||
如果只执行设置命令但没有保存,参数只会停留在当前 RAM 中。
|
|
||||||
|
|
||||||
### 11.3 `AT+DHCP=1` 失败
|
|
||||||
|
|
||||||
这是当前固件设计行为,不是故障。
|
|
||||||
|
|
||||||
当前构建不支持 DHCP,因此:
|
|
||||||
|
|
||||||
```text
|
|
||||||
AT+DHCP=1\n
|
|
||||||
```
|
|
||||||
|
|
||||||
返回:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ERROR: DHCP disabled in this build
|
|
||||||
```
|
|
||||||
|
|
||||||
## 12. 已实测通过的命令行为
|
|
||||||
|
|
||||||
本手册中的以下命令行为已经在实板上验证通过:
|
|
||||||
|
|
||||||
- `AT`
|
|
||||||
- `AT+?`
|
|
||||||
- `AT+QUERY`
|
|
||||||
- `AT+IP=...`
|
|
||||||
- `AT+MASK=...`
|
|
||||||
- `AT+GW=...`
|
|
||||||
- `AT+RIP=...`
|
|
||||||
- `AT+MAC=...`
|
|
||||||
- `AT+PORT=...`
|
|
||||||
- `AT+RPORT=...`
|
|
||||||
- `AT+BAUD1=...`
|
|
||||||
- `AT+BAUD2=...`
|
|
||||||
- `AT+DHCP=0`
|
|
||||||
- `AT+SAVE`
|
|
||||||
- `AT+RESET`
|
|
||||||
- `AT+DEFAULT`
|
|
||||||
|
|
||||||
已实测通过的错误路径包括:
|
|
||||||
|
|
||||||
- `AT+UNKNOWN`
|
|
||||||
- `AT+PORT=0`
|
|
||||||
- `AT+PORT=65536`
|
|
||||||
- `AT+BAUD1=1199`
|
|
||||||
- `AT+BAUD1=921601`
|
|
||||||
- `AT+DHCP=1`
|
|
||||||
- `AT+IP=999.1.1.1`
|
|
||||||
- `AT+MAC=GG:11:22:33:44:55`
|
|
||||||
|
|
||||||
## 13. 相关文件
|
## 13. 相关文件
|
||||||
|
|
||||||
|
|||||||
@@ -1,234 +1,192 @@
|
|||||||
# TCP2UART 项目技术实现
|
# TCP2UART 项目技术实现
|
||||||
|
|
||||||
## 一、当前实现结论
|
## 一、文档目的
|
||||||
|
|
||||||
当前工程已经从原先的 `FreeRTOS + lwIP socket/netconn` 方向,重构为适配 `STM32F103R8T6` 的裸机实现。
|
本文档描述 `TCP2UART` 项目的最终内部实现口径。
|
||||||
|
|
||||||
当前基线特征如下:
|
本文档只围绕最终协议模型展开:
|
||||||
|
|
||||||
1. MCU 目标固定为 `STM32F103R8T6 / STM32F103xB`
|
- `MUX`:串口承载层
|
||||||
2. 软件架构改为 `bare-metal main loop + DMA/IDLE + EXTI`
|
- `NET`:全局网络配置层
|
||||||
3. 网络栈采用 `lwIP RAW API + NO_SYS=1`
|
- `LINK[idx]`:实例配置与连接管理层
|
||||||
4. 调试输出采用 `SEGGER RTT`
|
|
||||||
5. `CH390` 运行时访问已收敛为单一拥有者 `ch390_runtime`
|
|
||||||
6. 构建目标已通过 `MDK-ARM` 编译,适配 `64KB Flash / 20KB SRAM`
|
|
||||||
|
|
||||||
## 二、硬件与资源约束
|
不再保留历史 `S1... / C1...` 外部字段模型。
|
||||||
|
|
||||||
### 2.1 MCU
|
## 二、当前工程基础
|
||||||
|
|
||||||
- 型号:`STM32F103R8T6`
|
当前工程基础约束如下:
|
||||||
- Flash:`64 KB`
|
|
||||||
- SRAM:`20 KB`
|
|
||||||
- 主频:`72 MHz`
|
|
||||||
|
|
||||||
### 2.2 主要外设
|
1. MCU:`STM32F103R8T6`
|
||||||
|
2. 网络芯片:`CH390D`
|
||||||
|
3. 软件架构:`bare-metal main loop`
|
||||||
|
4. 协议栈:`lwIP RAW API + NO_SYS=1`
|
||||||
|
5. 调试输出:`SEGGER RTT`
|
||||||
|
6. 不使用 `FreeRTOS`
|
||||||
|
7. 不实现 DHCP
|
||||||
|
|
||||||
- `SPI1`:连接 `CH390D`
|
## 三、总体架构
|
||||||
- `USART1`:配置串口
|
|
||||||
- `USART2`:Server 透传串口
|
|
||||||
- `USART3`:Client 透传串口
|
|
||||||
- `DMA1`:UART 收发 DMA
|
|
||||||
- `EXTI0`:CH390 中断输入
|
|
||||||
- `IWDG`:独立看门狗
|
|
||||||
- `TIM4`:LED 心跳定时器
|
|
||||||
|
|
||||||
当前说明:
|
|
||||||
|
|
||||||
1. `IWDG` 外设仍保留在工程中,但当前调试基线默认不在 `main()` 中启用 `MX_IWDG_Init()`
|
|
||||||
2. `App_Poll()` 已对 `HAL_IWDG_Refresh(&hiwdg)` 做句柄保护,避免未初始化句柄导致 `HardFault`
|
|
||||||
|
|
||||||
### 2.3 当前引脚分配
|
|
||||||
|
|
||||||
| 引脚 | 功能 | 用途 |
|
|
||||||
|------|------|------|
|
|
||||||
| PA2 | USART2_TX | Server 透传串口 |
|
|
||||||
| PA3 | USART2_RX | Server 透传串口 |
|
|
||||||
| PA4 | GPIO_Output | CH390D 片选 |
|
|
||||||
| PA5 | SPI1_SCK | CH390D SPI 时钟 |
|
|
||||||
| PA6 | SPI1_MISO | CH390D SPI 数据输入 |
|
|
||||||
| PA7 | SPI1_MOSI | CH390D SPI 数据输出 |
|
|
||||||
| PA9 | USART1_TX | 配置串口 |
|
|
||||||
| PA10 | USART1_RX | 配置串口 |
|
|
||||||
| PB0 | EXTI0 | CH390D INT |
|
|
||||||
| PB1 | GPIO_Output | CH390D RESET |
|
|
||||||
| PB10 | USART3_TX | Client 透传串口 |
|
|
||||||
| PB11 | USART3_RX | Client 透传串口 |
|
|
||||||
| PC13 | GPIO_Output | 状态 LED |
|
|
||||||
| PD0/PD1 | HSE | 8MHz 外部晶振 |
|
|
||||||
|
|
||||||
## 三、架构选择原因
|
|
||||||
|
|
||||||
`STM32F103R8T6` 的资源上限不足以稳定承载原方案中的以下组合:
|
|
||||||
|
|
||||||
1. `FreeRTOS`
|
|
||||||
2. `CMSIS-RTOS V2`
|
|
||||||
3. 多任务栈
|
|
||||||
4. `lwIP socket/netconn/tcpip` OS 路线
|
|
||||||
5. `StreamBuffer / Semaphore / Mutex`
|
|
||||||
|
|
||||||
因此当前实现采用如下组合:
|
|
||||||
|
|
||||||
1. 去掉 `FreeRTOS`
|
|
||||||
2. 去掉 `CMSIS-RTOS V2`
|
|
||||||
3. 去掉 `lwIP socket/netconn`
|
|
||||||
4. 改为 `lwIP RAW API + NO_SYS=1`
|
|
||||||
5. 串口与网口统一由主循环推进
|
|
||||||
|
|
||||||
## 四、当前软件架构
|
|
||||||
|
|
||||||
### 4.1 分层
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
+--------------------------------------------------+
|
+--------------------------------------------------+
|
||||||
| Application Logic |
|
| AT / Control Plane |
|
||||||
| config / tcp_server / tcp_client / uart bridge |
|
| USART1 AT parser + MUX control frame parser |
|
||||||
+--------------------------------------------------+
|
+--------------------------------------------------+
|
||||||
| Main Poll Loop |
|
| Configuration Model |
|
||||||
| ethernetif_poll / sys_check_timeouts / watchdog |
|
| MUX / NET / LINK[idx] |
|
||||||
+--------------------------------------------------+
|
+--------------------------------------------------+
|
||||||
| CH390 Runtime Owner |
|
| Routing & Session Layer |
|
||||||
| ch390_runtime (single runtime SPI owner) |
|
| TCP instance scheduling + UART dispatch |
|
||||||
+--------------------------------------------------+
|
+--------------------------------------------------+
|
||||||
| Peripheral/Event Layer |
|
| Transport Poll Loop |
|
||||||
| UART DMA+IDLE / DMA IRQ / EXTI / SysTick |
|
| ethernetif_poll / sys_check_timeouts / uart poll |
|
||||||
+--------------------------------------------------+
|
+--------------------------------------------------+
|
||||||
| Drivers |
|
| Driver Layer |
|
||||||
| CH390 / lwIP netif / HAL |
|
| CH390 / lwIP netif / UART DMA+IDLE / HAL |
|
||||||
+--------------------------------------------------+
|
+--------------------------------------------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.2 执行模型
|
## 四、最终协议实现模型
|
||||||
|
|
||||||
当前执行模型为:
|
### 4.1 MUX 帧承载层
|
||||||
|
|
||||||
1. `SysTick` 提供全局毫秒时基
|
数据口启用 MUX 后,统一处理如下帧:
|
||||||
2. `EXTI0` 只置位 CH390 待处理标志,不直接做 SPI/CH390 访问
|
|
||||||
3. `DMA IRQ` 和 `UART IRQ` 只完成回调分发与 IDLE 采样
|
|
||||||
4. `ch390_runtime` 成为唯一的 CH390 运行时访问源
|
|
||||||
5. 主循环统一执行网络轮询、超时推进、串口桥接和看门狗喂狗
|
|
||||||
|
|
||||||
## 五、当前模块实现状态
|
```text
|
||||||
|
SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL
|
||||||
|
```
|
||||||
|
|
||||||
### 5.1 配置模块
|
实现职责:
|
||||||
|
|
||||||
文件:`App/config.c/.h`
|
1. 识别帧边界
|
||||||
|
2. 解析长度字段
|
||||||
|
3. 提取 `SRCID`
|
||||||
|
4. 解析 `DSTMASK`
|
||||||
|
5. 按控制帧或数据帧分流
|
||||||
|
|
||||||
已实现:
|
### 4.2 控制帧与数据帧分离
|
||||||
|
|
||||||
1. 从 Flash 加载配置
|
控制规则固定如下:
|
||||||
2. UART1 命令口接收
|
|
||||||
3. 常用网络与串口参数解析
|
|
||||||
4. 参数保存与软复位请求
|
|
||||||
|
|
||||||
当前约束:
|
- `DSTMASK = 0x00`:系统控制帧
|
||||||
|
- `DSTMASK != 0x00`:业务数据帧
|
||||||
|
|
||||||
1. 构建已关闭 `DHCP`,因此 `AT+DHCP=1` 会明确返回错误
|
系统控制帧处理要求:
|
||||||
2. 配置损坏时会回退默认值,但默认值不会自动写回 Flash,仍需手动 `AT+SAVE`
|
|
||||||
|
|
||||||
### 5.2 UART 透传模块
|
1. `PAYLOAD` 解释为 AT 文本
|
||||||
|
2. AT 文本必须以 `\r\n` 结束
|
||||||
|
3. 控制帧进入 AT 命令处理链路
|
||||||
|
|
||||||
文件:`App/uart_trans.c/.h`
|
业务数据帧处理要求:
|
||||||
|
|
||||||
已实现:
|
1. `SRCID` 表示单一源端点
|
||||||
|
2. `DSTMASK` 表示目标端点集合
|
||||||
|
3. 路由层根据 `DSTMASK` 做多目标分发
|
||||||
|
|
||||||
1. `USART2/USART3` 使用 `DMA + IDLE`
|
### 4.3 统一端点编码
|
||||||
2. RX 使用 DMA 缓冲转环形缓冲
|
|
||||||
3. TX 使用 DMA 发送
|
|
||||||
4. TX/RX 完成由 `HAL_UART_*Callback` 驱动
|
|
||||||
|
|
||||||
### 5.3 TCP Server 模块
|
内部与外部文档统一使用以下端点编码:
|
||||||
|
|
||||||
文件:`App/tcp_server.c/.h`
|
| 端点 | 编码 |
|
||||||
|
|------|------|
|
||||||
|
| `C1` | `0x01` |
|
||||||
|
| `C2` | `0x02` |
|
||||||
|
| `UART2` | `0x04` |
|
||||||
|
| `UART3` | `0x08` |
|
||||||
|
| `S1` | `0x10` |
|
||||||
|
| `S2` | `0x20` |
|
||||||
|
|
||||||
已实现:
|
实现要求:
|
||||||
|
|
||||||
1. `lwIP RAW API` 监听指定端口
|
- `SRCID` 为单值
|
||||||
2. 单连接接入
|
- `DSTMASK` 为位图
|
||||||
3. 网络数据写入本地环形缓冲
|
- `DSTMASK=0x00` 仅保留为控制帧
|
||||||
4. 主循环中与 UART2 做双向桥接
|
|
||||||
|
|
||||||
### 5.4 TCP Client 模块
|
## 五、配置层设计
|
||||||
|
|
||||||
文件:`App/tcp_client.c/.h`
|
### 5.1 MUX 记录
|
||||||
|
|
||||||
已实现:
|
`MUX` 为全局记录,仅控制设备数据口是否进入 MUX 承载模式。
|
||||||
|
|
||||||
1. `lwIP RAW API` 主动连接远端地址
|
取值:
|
||||||
2. 断链后按周期重连
|
|
||||||
3. 网络数据写入本地环形缓冲
|
|
||||||
4. 主循环中与 UART3 做双向桥接
|
|
||||||
|
|
||||||
### 5.5 CH390 与 netif 模块
|
- `0`:普通透传
|
||||||
|
- `1`:MUX 透传
|
||||||
|
|
||||||
文件:`Drivers/CH390/*`、`Drivers/LwIP/src/netif/*`
|
### 5.2 NET 记录
|
||||||
|
|
||||||
已实现:
|
`NET` 为全局静态网络记录:
|
||||||
|
|
||||||
1. `SPI1 + GPIO CS + EXTI0` 驱动 CH390
|
```text
|
||||||
2. `ethernetif.c` 采用 `NO_SYS=1` 路线
|
IP,MASK,GW,MAC
|
||||||
3. 新增 `Drivers/CH390/ch390_runtime.c`,统一负责 CH390 初始化、链路查询、IRQ pending 消费、RX/TX 服务与启动诊断快照
|
```
|
||||||
4. `main.c` 不再直接读取 CH390 原始寄存器,启动诊断通过 `ch390_runtime_get_diag()` 获取快照
|
|
||||||
5. `EXTI0_IRQHandler()` 只投递 IRQ pending,不再直接混入 CH390 访问
|
|
||||||
6. 配置中的 MAC 地址会在初始化时写入 CH390
|
|
||||||
|
|
||||||
当前状态:
|
说明:
|
||||||
|
|
||||||
1. 运行时架构层面的 `SPI/LwIP/CH390` 多源访问问题已经消除
|
- 设备只有一张网卡,因此不为每个实例单独配置本地 IP
|
||||||
2. `HardFault` 与“运行一会儿卡死”问题已修复
|
- 当前实现目标中不包含 DHCP
|
||||||
3. CH390D 当前已恢复基础寄存器读写,调试重点已从“SPI 是否完全不通”转入初始化完整性、链路、中断与收发功能验证
|
|
||||||
4. 最终实板定位表明,一颗 CH390D 供电滤波电容虚焊会直接导致供电不稳,并放大为网络收发异常
|
|
||||||
|
|
||||||
### 5.6 RTT 调试输出
|
### 5.3 LINK 记录
|
||||||
|
|
||||||
文件:`Middlewares/Third_Party/SEGGER_RTT/*`
|
`LINK[idx]` 为统一实例记录:
|
||||||
|
|
||||||
已实现:
|
```text
|
||||||
|
EN,LPORT,RIP,RPORT,UART
|
||||||
|
```
|
||||||
|
|
||||||
1. 工程内置最小 `SEGGER RTT` 源文件
|
固定索引映射:
|
||||||
2. `main.c` 中 `printf/fputc` 已重定向到 RTT
|
|
||||||
|
|
||||||
### 5.7 TIM4 心跳闪烁
|
- `0 = S1`
|
||||||
|
- `1 = S2`
|
||||||
|
- `2 = C1`
|
||||||
|
- `3 = C2`
|
||||||
|
|
||||||
文件:`Core/Src/tim.c`、`Core/Src/main.c`、`Core/Src/stm32f1xx_it.c`
|
字段职责:
|
||||||
|
|
||||||
已实现:
|
- `EN`:实例启用状态
|
||||||
|
- `LPORT`:本地端口
|
||||||
|
- `RIP / RPORT`:对端地址与端口
|
||||||
|
- `UART`:对应业务数据口
|
||||||
|
|
||||||
1. 使用 `TIM4` 作为 LED 心跳定时器
|
说明:
|
||||||
2. `TIM4` 时钟来自 `APB1 Timer Clock = 72 MHz`
|
|
||||||
3. 通过 `Prescaler = 7199` 和 `Period = 9` 生成 `1 ms` 更新中断
|
|
||||||
4. 在 `HAL_TIM_PeriodElapsedCallback()` 中进行 1ms 计数
|
|
||||||
5. 累计 `1000` 次后翻转一次 `PC13`,形成 `1 s` 闪烁节拍
|
|
||||||
|
|
||||||
当前实现说明:
|
- `Server` 与 `Client` 共享同一记录结构
|
||||||
|
- `Server` 的 `RIP / RPORT` 可作为对端约束或预设
|
||||||
|
- `Client` 的 `RIP / RPORT` 表示远端目标
|
||||||
|
|
||||||
1. `PC13` 为低电平点亮、高电平熄灭
|
## 六、模块职责调整
|
||||||
2. 当前逻辑为每 `1 s` 翻转一次 LED 状态,即完整亮灭周期为 `2 s`
|
|
||||||
3. 若后续需要“每 1 秒完整闪烁一次”,可改为 `500 ms` 翻转一次
|
|
||||||
|
|
||||||
## 六、lwIP 配置策略
|
### 6.1 配置模块 `config.c/.h`
|
||||||
|
|
||||||
当前 `lwIP` 配置以适配 `R8T6` 资源为原则,核心策略如下:
|
最终职责:
|
||||||
|
|
||||||
1. `NO_SYS = 1`
|
1. 解析 `AT+MUX`
|
||||||
2. `LWIP_SOCKET = 0`
|
2. 解析 `AT+NET`
|
||||||
3. `LWIP_NETCONN = 0`
|
3. 解析 `AT+LINK`
|
||||||
4. `LWIP_NETIF_API = 0`
|
4. 加载与保存配置
|
||||||
5. `LWIP_DHCP = 0`
|
5. 处理 `SAVE / RESET / DEFAULT`
|
||||||
6. `LWIP_UDP = 0`
|
|
||||||
7. `LWIP_DNS = 0`
|
|
||||||
8. `LWIP_IGMP = 0`
|
|
||||||
9. 关闭 `lwIP` 平台诊断 `printf`
|
|
||||||
|
|
||||||
同时从 `MDK` 工程中移除了:
|
不再以历史展开式字段作为外部接口模型。
|
||||||
|
|
||||||
1. `FreeRTOS` 相关源码
|
### 6.2 UART 透传模块 `uart_trans.c/.h`
|
||||||
2. `lwIP api/socket/netconn/tcpip` 路线源码
|
|
||||||
3. `altcp / autoip / acd / dhcp / dns / igmp` 等当前不需要模块
|
|
||||||
|
|
||||||
## 七、主循环实际骨架
|
最终职责:
|
||||||
|
|
||||||
当前主循环逻辑可概括为:
|
1. 保持 `USART2 / USART3` 的 `DMA + IDLE` 接收发送基线
|
||||||
|
2. 在 `MUX=0` 时执行普通透传
|
||||||
|
3. 在 `MUX=1` 时执行 MUX 帧收发
|
||||||
|
4. 将控制帧与业务数据帧分流
|
||||||
|
|
||||||
|
### 6.3 TCP Server / Client 模块
|
||||||
|
|
||||||
|
最终职责:
|
||||||
|
|
||||||
|
1. 不再从外部协议角度区分不同字段模型
|
||||||
|
2. 统一受 `LINK[idx]` 配置驱动
|
||||||
|
3. 由调度层决定实例与 UART 的数据交换路径
|
||||||
|
|
||||||
|
## 七、主循环实现方向
|
||||||
|
|
||||||
|
主循环仍保持裸机轮询风格:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
while (1)
|
while (1)
|
||||||
@@ -236,81 +194,37 @@ while (1)
|
|||||||
ethernetif_poll();
|
ethernetif_poll();
|
||||||
ethernetif_check_link();
|
ethernetif_check_link();
|
||||||
sys_check_timeouts();
|
sys_check_timeouts();
|
||||||
tcp_client_poll();
|
tcp_link_poll();
|
||||||
uart_trans_poll();
|
uart_mux_poll();
|
||||||
config_poll();
|
config_poll();
|
||||||
|
|
||||||
tcp_server <-> UART2;
|
route_dispatch();
|
||||||
tcp_client <-> UART3;
|
|
||||||
|
|
||||||
if (reset_requested) {
|
if (reset_requested) {
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hiwdg.Instance == IWDG) {
|
|
||||||
HAL_IWDG_Refresh(&hiwdg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 八、当前构建状态
|
下一阶段实现要求:
|
||||||
|
|
||||||
### 8.1 MDK 构建命令
|
1. 统一由 `LINK[idx]` 驱动实例状态
|
||||||
|
2. 统一由 `MUX` 决定数据口承载模式
|
||||||
|
3. 统一由 `route_dispatch()` 按 `SRCID / DSTMASK` 分发
|
||||||
|
|
||||||
```bat
|
## 八、实现边界
|
||||||
"C:\Keil_v5\UV4\UV4.exe" -b "D:\code\STM32Project\TCP2UART\MDK-ARM\TCP2UART.uvprojx" -j0
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8.2 当前结果
|
1. 保持单网卡静态网络模型
|
||||||
|
2. 不实现 DHCP
|
||||||
|
3. 不实现旧 `S1... / C1...` 外部协议字段
|
||||||
|
4. 不在文档中保留兼容层描述
|
||||||
|
5. 所有 AT 文本控制统一要求 `\r\n` 结束
|
||||||
|
|
||||||
当前构建结果:
|
## 九、文档一致性要求
|
||||||
|
|
||||||
1. `0 Error(s)`
|
后续实现、联调、测试与代码注释必须遵守以下统一口径:
|
||||||
2. `0 Warning(s)`
|
|
||||||
3. 代码体积仍满足 `STM32F103R8T6` 资源约束
|
|
||||||
4. `MDK-ARM` 工程可直接编译并下载验证
|
|
||||||
|
|
||||||
说明当前版本已经满足:
|
1. 对外协议只使用 `MUX / NET / LINK`
|
||||||
|
2. 控制帧只使用 `DSTMASK=0x00`
|
||||||
1. `STM32F103R8T6 64KB Flash` 约束
|
3. MUX 帧格式固定为 `SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL`
|
||||||
2. `20KB SRAM` 约束
|
4. AT 手册、需求说明、技术实现三份文档不得再出现历史展开式字段
|
||||||
3. `MDK-ARM` 可直接编译
|
|
||||||
|
|
||||||
## 九、当前已知限制与待验证项
|
|
||||||
|
|
||||||
### 9.1 功能限制
|
|
||||||
|
|
||||||
1. 当前使用静态 IP,不支持 DHCP
|
|
||||||
2. 当前已验证 CH390 基础寄存器读写、PHY 管理寄存器访问与 lwIP `netif` 链路置位路径;RX/TX 实际业务流量仍需继续做板上验证
|
|
||||||
3. 目前未提供完整的上板网络吞吐、丢包率与长时间稳定性报告
|
|
||||||
4. `config` 模块仍保留较重的字符串解析逻辑,但当前体积已可接受
|
|
||||||
|
|
||||||
### 9.2 上板验证重点
|
|
||||||
|
|
||||||
1. 验证 CH390 `RST/CS/SCK/MOSI/MISO/INT` 在芯片脚侧的实际波形与当前软件假设一致
|
|
||||||
2. 验证 `VID/PID/REV`、MAC 写回、`RCR/IMR/INTCR`、PHY 寄存器与 `LINK`/`netif` 链路状态在多次上电下稳定一致
|
|
||||||
3. 验证 `TIM4` 1ms 中断稳定性与 `PC13` 1秒翻转节拍
|
|
||||||
4. 验证 `UART2/UART3 DMA + IDLE` 在长连续流量下的行为
|
|
||||||
5. 验证 TCP Server 与 TCP Client 双链路同时工作时的稳定性
|
|
||||||
6. 验证配置保存、复位、MAC 生效路径
|
|
||||||
7. 验证 CH390 收发路径、链路变化中断与 RX/TX 数据通路
|
|
||||||
|
|
||||||
## 十、后续建议
|
|
||||||
|
|
||||||
下一阶段建议按以下顺序推进:
|
|
||||||
|
|
||||||
1. 在当前可读写基线下,优先验证 `default_config`、MAC、PHY 协商/链路、IRQ、RX/TX 是否完整生效
|
|
||||||
2. 同步用芯片脚侧波形与电源域量测验证 `RST/CS/SCK/MOSI/MISO/INT` 和 `VDDK/AVDD33/VDDIO/AVDD33`
|
|
||||||
3. 若链路与寄存器状态可信,再推进 TCP Server / TCP Client 与 UART2 / UART3 的双向联调
|
|
||||||
4. 完成后补充吞吐、丢包、长稳与异常恢复测试
|
|
||||||
|
|
||||||
## 十一、当前结论
|
|
||||||
|
|
||||||
截至本轮调试:
|
|
||||||
|
|
||||||
1. 系统主循环、RTT、定时器心跳、UART 配置路径均可正常工作
|
|
||||||
2. 已修复并验证多个真实软件问题,且相关中间里程碑已提交版本库
|
|
||||||
3. CH390D 当前已恢复基础寄存器读写,且已在实机上验证 `VID=0x1C00`、`PID=0x9151`、`REV=0x2B`、PHY ID 可读
|
|
||||||
4. 运行时 `lwIP netif` 已观察到 `LINK_UP` 置位,说明当前阶段已不再是“完全无响应”或“链路始终未起”
|
|
||||||
5. 当前硬件修复后,ARP/Ping 基础链路已验证通过,后续重点转为业务流量与长稳验证
|
|
||||||
6. 板级供电完整性应作为 CH390D 调试前置检查项,而不是放到软件排查后期才介入
|
|
||||||
|
|||||||
@@ -1,95 +1,161 @@
|
|||||||
# TCP2UART 项目需求说明
|
# TCP2UART 项目需求说明
|
||||||
|
|
||||||
## 一、项目概述
|
## 一、项目目标
|
||||||
|
|
||||||
基于 `STM32F103R8T6` 和 `CH390D` 实现双链路 TCP 串口透传设备。设备提供一条 TCP Server 链路和一条 TCP Client 链路,分别与两路 UART 做双向透明传输,并通过 UART1 进行参数配置。
|
本项目基于 `STM32F103R8T6` 与 `CH390D` 实现一台多实例 TCP 与双串口数据透传设备。
|
||||||
|
|
||||||
当前项目实现路线已经固定为:
|
最终对外协议模型固定为:
|
||||||
|
|
||||||
1. `STM32CubeMX + HAL`
|
1. `MUX`:控制串口侧是否采用 MUX 承载
|
||||||
2. `bare-metal`
|
2. `NET`:全局静态网络配置
|
||||||
3. `lwIP RAW API + NO_SYS=1`
|
3. `LINK[idx]`:按实例索引组织的链路配置
|
||||||
4. `SEGGER RTT` 调试输出
|
|
||||||
|
|
||||||
不再采用 `FreeRTOS` 作为正式交付架构。
|
系统必须支持:
|
||||||
|
|
||||||
## 二、硬件平台
|
- `2` 路 TCP Server 实例
|
||||||
|
- `2` 路 TCP Client 实例
|
||||||
|
- `UART1` 作为 AT 配置口
|
||||||
|
- `UART2 / UART3` 作为业务数据口
|
||||||
|
|
||||||
| 项目 | 说明 |
|
## 二、硬件与软件边界
|
||||||
|
|
||||||
|
### 2.1 硬件边界
|
||||||
|
|
||||||
|
- 主控:`STM32F103R8T6`
|
||||||
|
- 以太网芯片:`CH390D`
|
||||||
|
- 网卡数量:`1`
|
||||||
|
- 配置口:`UART1`
|
||||||
|
- 数据口:`UART2`、`UART3`
|
||||||
|
|
||||||
|
### 2.2 软件边界
|
||||||
|
|
||||||
|
- 执行模型:`bare-metal`
|
||||||
|
- 网络协议栈:`lwIP RAW API + NO_SYS=1`
|
||||||
|
- 调试输出:`SEGGER RTT`
|
||||||
|
- 不采用 `FreeRTOS`
|
||||||
|
- 不采用 `socket/netconn`
|
||||||
|
- 不包含 DHCP 协议支持
|
||||||
|
|
||||||
|
## 三、最终协议需求
|
||||||
|
|
||||||
|
### 3.1 MUX 帧格式
|
||||||
|
|
||||||
|
所有 MUX 数据承载必须使用如下格式:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL
|
||||||
|
```
|
||||||
|
|
||||||
|
要求:
|
||||||
|
|
||||||
|
- `DSTMASK != 0x00`:业务数据帧
|
||||||
|
- `DSTMASK = 0x00`:系统控制帧
|
||||||
|
- 系统控制帧承载 AT 文本命令
|
||||||
|
- AT 文本命令必须以 `\r\n` 结尾
|
||||||
|
|
||||||
|
### 3.2 统一端点编码
|
||||||
|
|
||||||
|
系统必须使用统一端点编码,同时覆盖 UART 与 TCP 逻辑实例:
|
||||||
|
|
||||||
|
| 端点 | 编码 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 主控芯片 | `STM32F103R8T6` |
|
| `C1` | `0x01` |
|
||||||
| 以太网芯片 | `CH390D` |
|
| `C2` | `0x02` |
|
||||||
| PCB 设计工具 | 立创 EDA |
|
| `UART2` | `0x04` |
|
||||||
| 串口通道 | `UART1 + UART2 + UART3` |
|
| `UART3` | `0x08` |
|
||||||
|
| `S1` | `0x10` |
|
||||||
|
| `S2` | `0x20` |
|
||||||
|
|
||||||
|
要求:
|
||||||
|
|
||||||
|
- `SRCID` 为单值
|
||||||
|
- `DSTMASK` 为位图
|
||||||
|
- `DSTMASK=0x00` 仅保留给系统控制帧
|
||||||
|
|
||||||
|
## 四、AT 接口需求
|
||||||
|
|
||||||
|
### 4.1 命令分类
|
||||||
|
|
||||||
|
AT 协议必须收敛为以下三类命令:
|
||||||
|
|
||||||
|
1. `AT+MUX`
|
||||||
|
2. `AT+NET`
|
||||||
|
3. `AT+LINK`
|
||||||
|
|
||||||
|
不再保留历史展开式实例字段命令。
|
||||||
|
|
||||||
|
### 4.2 MUX 命令需求
|
||||||
|
|
||||||
|
- `AT+MUX=0/1`:设置全局 MUX 模式
|
||||||
|
- `AT+MUX?`:查询当前 MUX 模式
|
||||||
|
|
||||||
|
### 4.3 NET 命令需求
|
||||||
|
|
||||||
|
`NET` 必须统一表达以下静态网络参数:
|
||||||
|
|
||||||
|
```text
|
||||||
|
IP,MASK,GW,MAC
|
||||||
|
```
|
||||||
|
|
||||||
说明:
|
说明:
|
||||||
|
|
||||||
1. `UART1` 用于配置口
|
- 设备只有一张网卡,因此本地 IP 不按实例拆分
|
||||||
2. `UART2` 对应 TCP Server 透传链路
|
- DHCP 不属于协议需求范围
|
||||||
3. `UART3` 对应 TCP Client 透传链路
|
|
||||||
|
|
||||||
## 三、软件平台
|
### 4.4 LINK 命令需求
|
||||||
|
|
||||||
| 项目 | 说明 |
|
`LINK[idx]` 必须统一表达如下字段:
|
||||||
|------|------|
|
|
||||||
| 开发环境 | `STM32CubeMX + HAL + MDK-ARM` |
|
|
||||||
| 执行模型 | 裸机主循环 + 中断驱动 |
|
|
||||||
| 协议栈 | `lwIP RAW API` |
|
|
||||||
| 调试输出 | `SEGGER RTT` |
|
|
||||||
|
|
||||||
## 四、核心功能需求
|
```text
|
||||||
|
EN,LPORT,RIP,RPORT,UART
|
||||||
|
```
|
||||||
|
|
||||||
### 4.1 双链路 TCP 通信
|
要求:
|
||||||
|
|
||||||
- `Server` 链路:设备作为 TCP Server,监听指定端口
|
- `idx` 固定映射四个实例:`0=S1`、`1=S2`、`2=C1`、`3=C2`
|
||||||
- `Client` 链路:设备作为 TCP Client,主动连接远程服务器
|
- `Server` 与 `Client` 共用同一条 `LINK` 配置模型
|
||||||
- 两条链路共享同一个设备 IP 地址
|
- `LPORT` 必须可配置
|
||||||
|
- `RIP / RPORT` 必须可配置
|
||||||
|
- `UART` 必须可配置
|
||||||
|
|
||||||
### 4.2 串口透传
|
## 五、功能需求
|
||||||
|
|
||||||
- `Server` 链路数据 <=> `UART2` 双向透传
|
### 5.1 TCP 功能
|
||||||
- `Client` 链路数据 <=> `UART3` 双向透传
|
|
||||||
- 仅透传 TCP Payload,不解析业务层协议
|
|
||||||
|
|
||||||
### 4.3 参数配置
|
- 支持 `2` 路 Server
|
||||||
|
- 支持 `2` 路 Client
|
||||||
|
- 每个实例通过 `LINK[idx]` 配置其本地端口、对端地址、对端端口和串口路由
|
||||||
|
|
||||||
- 通过 `UART1` 配置网络与串口参数
|
### 5.2 串口透传功能
|
||||||
- 配置参数掉电保存
|
|
||||||
- 支持设备复位后按保存配置生效
|
|
||||||
|
|
||||||
### 4.4 调试与维护
|
- `UART2 / UART3` 支持普通透传模式与 MUX 透传模式
|
||||||
|
- 当需要多实例共享数据口时,必须启用 MUX 模式
|
||||||
|
- 业务数据流向由 `SRCID / DSTMASK` 决定
|
||||||
|
|
||||||
- 调试输出统一走 `SEGGER RTT`
|
### 5.3 系统控制功能
|
||||||
- 工程需可在 `MDK-ARM` 下直接构建
|
|
||||||
|
|
||||||
## 五、当前实现边界
|
- 系统控制帧由 `DSTMASK=0x00` 表示
|
||||||
|
- 系统控制帧进入 AT 解析路径
|
||||||
|
- 控制文本必须以 `\r\n` 结束
|
||||||
|
|
||||||
基于 `STM32F103R8T6` 的 `64KB Flash / 20KB SRAM` 约束,当前交付版本约束如下:
|
### 5.4 参数保存功能
|
||||||
|
|
||||||
1. 使用静态 IP
|
- 参数修改后支持 `SAVE`
|
||||||
2. 当前构建不支持 DHCP
|
- 支持 `RESET` 后按保存配置启动
|
||||||
3. 不使用 `lwIP socket/netconn`
|
- 支持恢复默认配置
|
||||||
4. 不使用 `FreeRTOS`
|
|
||||||
|
|
||||||
这不是降级,而是基于资源约束后的正式实现路线。
|
## 六、非功能需求
|
||||||
|
|
||||||
## 六、数据可靠性要求
|
1. 满足 `STM32F103R8T6` 的 `64KB Flash / 20KB SRAM` 约束
|
||||||
|
2. 工程可在 `MDK-ARM` 下构建
|
||||||
|
3. 调试输出统一使用 `SEGGER RTT`
|
||||||
|
4. 不引入 DHCP、DNS、UDP 等当前非目标协议
|
||||||
|
|
||||||
- 目标是保证 TCP 数据与串口数据双向透传稳定工作
|
## 七、验收口径
|
||||||
- 需要后续补充上板联调后的丢包率测试方案与结果
|
|
||||||
- 需要验证双链路同时工作时的稳定性
|
|
||||||
|
|
||||||
## 七、交付物
|
验收时以下几点必须同时成立:
|
||||||
|
|
||||||
1. 原理图及 PCB 设计文件
|
1. 文档只使用 `MUX / NET / LINK` 作为最终协议模型
|
||||||
2. STM32 固件源码
|
2. 文档不再出现历史 `S1... / C1...` 外部字段
|
||||||
3. `CubeMX` 工程与 `MDK-ARM` 工程
|
3. 串口控制文本统一规定为 `\r\n` 结束
|
||||||
4. 使用说明文档
|
4. MUX 帧格式与端点编码在需求、手册、技术实现三份文档中表述一致
|
||||||
5. 后续补充的透传与丢包测试结果
|
|
||||||
|
|
||||||
## 八、约束条件
|
|
||||||
|
|
||||||
1. 通信协议为标准 TCP/IP
|
|
||||||
2. 串口透传为纯数据透传,不解析上层协议
|
|
||||||
3. 当前正式目标器件为 `STM32F103R8T6`
|
|
||||||
4. 所有正式实现应服从 `64KB Flash / 20KB SRAM` 约束
|
|
||||||
|
|||||||
Reference in New Issue
Block a user