Files
STM32F4-Base/docs/CH395F_Test_Guide.md
2026-07-19 13:09:06 +08:00

265 lines
9.4 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.
# CH395F 测试使用指南
## 目录
1. [快速开始](#1-快速开始)
2. [各阶段测试](#2-各阶段测试)
- [Phase 1: 寄存器测试](#phase-1-寄存器测试)
- [Phase 2: TCP Client 收发+重连](#phase-2-tcp-client)
- [Phase 3: UDP Server Echo](#phase-3-udp-server-echo)
- [Phase 4: NET 层 TCP Echo](#phase-4-net-层-tcp-echo)
- [Phase 5: NET 层 UDP Echo](#phase-5-net-层-udp-echo)
- [Phase 6: DHCP](#phase-6-dhcp)
- [Phase 7: Select/Poll](#phase-7-selectpoll)
- [Phase 8: 多客户端并发](#phase-8-多客户端并发)
3. [Python 脚本参考](#3-python-脚本参考)
4. [常见问题](#4-常见问题)
5. [陷阱记录](#5-陷阱记录)
---
## 1. 快速开始
### 启用/禁用测试
编辑 `Drivers/BSP/CH395F/ch395f_test.h`,取消注释想要测试的阶段:
```c
//#define ENABLE_PHASE1_TESTS /* 取消注释即启用 */
//#define ENABLE_PHASE2_TESTS /* 默认关闭 */
//#define ENABLE_PHASE3_TESTS /* 默认关闭 */
#define ENABLE_PHASE4_TESTS /* 当前默认启用netTask TCP echo */
//#define ENABLE_PHASE5_TESTS /* 默认关闭 */
//#define ENABLE_PHASE6_TESTS /* 默认关闭(会改 IP */
//#define ENABLE_PHASE7_TESTS /* 默认关闭 */
```
### 测试拓扑
```
PC (192.168.1.2) ──── 交换机 ──── CH395F (192.168.1.100)
```
---
## 2. 各阶段测试
### Phase 1: 寄存器测试
| 项目 | 说明 |
|------|------|
| 类型 | 独立运行,无需 PC 配合 |
| 耗时 | ~1 秒 |
| 测试项 | 芯片版本、命令状态、IP/网关/掩码、全局中断一致性、Socket 中断、ARP、TTL |
**操作**
```
1. 只启用 ENABLE_PHASE1_TESTS
2. 编译烧录
3. 看串口输出
```
**通过标准**:串口打印 `=== Phase 1 Tests Complete ===`,中间无 ERROR。
---
### Phase 2: TCP Client
| 项目 | 说明 |
|------|------|
| 类型 | 需 PC 配合 |
| 耗时 | ~60 秒 |
| 测试项 | TCP Client 连接、收发 64 字节、关闭重连 ×3 轮 |
| 默认端口 | CH395F → PC:8081 |
**操作**
```
终端 1: python test/ch395f_socket_test.py tcp_server --port 8081 --timeout 180
终端 2: 编译烧录(只启用 ENABLE_PHASE2_TESTS
```
**通过标准**:串口显示 3 轮 `closed: sock=0x00`PC 显示 3 次连接且 PING echo 匹配。
---
### Phase 3: UDP Server Echo
| 项目 | 说明 |
|------|------|
| 类型 | 需 PC 配合 |
| 耗时 | ~30 秒 |
| 测试项 | UDP Server 模式、8 字节头解析、30 轮 echo含 HELLO + PING + 大包) |
| 默认端口 | CH395F:60000PC 发到 60000 |
**操作**
```
终端 1: 编译烧录(只启用 ENABLE_PHASE3_TESTS
终端 2: python test/ch395f_socket_test.py udp_client --ip 192.168.1.100 --port 60000 --timeout 30
```
**通过标准**PC 显示 30/30 回显匹配(含 HELLO ×1 + PING ×5 + 大包 ×20 + 其他)。
> **关键发现**CH395F UDP 分两种模式——DesIP=`255.255.255.255` 是 Server 模式(接受任意来源),否则只能收指定 IP:Port。每次 `write_send_buf` 后必须等 `SINT_STAT_SENDBUF_FREE`。
---
### Phase 4: NET 层 TCP Echo
| 项目 | 说明 |
|------|------|
| 类型 | 需 PC 配合netTask 中运行 |
| 耗时 | 按需 |
| 测试项 | `net_recv()` + `net_send()` 非阻塞 echo |
| 默认端口 | CH395F TCP Server:8080PC 连到 8080 |
> ⚠️ 该测试在 FreeRTOS netTask 中运行,需等调度器启动(`osKernelStart`)后约 2 秒。
**操作**
```
终端 1: 编译烧录(只启用 ENABLE_PHASE4_TESTS看到 "netTask: started"
终端 2: python test/ch395f_socket_test.py tcp_client --ip 192.168.1.100 --port 8080
```
**通过标准**10/10 回显匹配 + 大数据传输完整。
---
### Phase 5: NET 层 UDP Echo
| 项目 | 说明 |
|------|------|
| 类型 | 需 PC 配合netTask 中运行 |
| 耗时 | 按需 |
| 测试项 | `net_recvfrom()` + `net_sendto()` 非阻塞 echo |
| 默认端口 | CH395F UDP:60000 |
> ⚠️ 该测试在 FreeRTOS netTask 中运行,需等调度器启动后约 2 秒。
**操作**
```
终端 1: 编译烧录(只启用 ENABLE_PHASE5_TESTS看到 "netTask: started"
终端 2: python test/ch395f_socket_test.py udp_client --ip 192.168.1.100 --port 60000 --timeout 30
```
**通过标准**PING 5/5 + 大包 10/10。
---
### Phase 6: DHCP
| 项目 | 说明 |
|------|------|
| 类型 | 需 PC 配合 |
| 耗时 | ~15 秒 |
| 测试项 | DHCP 自动获取 IP、HELLO echo 验证连通性 |
> ⚠️ **DHCP 会改变 CH395F IP** 必须独立运行,不能与其他 Phase 同时启用。
PC 运行内置 DHCP Server完整 DISCOVER → OFFER → REQUEST → ACK 握手,然后发送 HELLO 验证 UDP 连通性。
```
终端 1: python test/ch395f_socket_test.py dhcp_server --dhcp-iface 192.168.1.2 --ip 192.168.1.100 --dhcp-mask 255.255.255.0 --dhcp-gw 192.168.1.1
终端 2: 编译烧录(只启用 ENABLE_PHASE6_TESTS
```
**通过标准**PC 显示 `DHCP 分配完成!` + 连通性验证通过。
> **关键:** 需管理员权限Windows 绑定端口 67。xid 偏移为 `data[4:8]`。`--dhcp-iface` 为 PC 网卡 IP用于区分网卡
**通过标准**PC 显示 `收到 CH395F 广播宣告` + 3 轮 HELLO echo 成功率 100%。
> **关键:** CH395F 每次 `write_send_buf` 后必须等 `SENDBUF_FREE` 中断,否则后续接收操作失败。
---
### Phase 7: Select/Poll
| 项目 | 说明 |
|------|------|
| 类型 | 需 PC 配合netTask 中运行 |
| 耗时 | 按需 |
| 测试项 | `net_select()` 多路复用检测可读 socket → echo |
| 默认端口 | CH395F TCP Server:8080 |
> ⚠️ 该测试在 FreeRTOS netTask 中运行,需等调度器启动后约 2 秒。
**操作**:同 Phase 4TCP Client 连 8080
**通过标准**:同 Phase 410/10 回显匹配)。
> Phase 4 和 Phase 7 功能相同但实现不同通常只启用一个。Phase 7 额外验证了 `NET_FD_SET/ISSET` 宏和 `net_select()`。
---
### Phase 8: 多客户端并发
| 项目 | 说明 |
|------|------|
| 类型 | 需 PC 配合,主循环运行 |
| 耗时 | ~2 秒 |
| 测试项 | 7 个 TCP 客户端并发,每客户端 10 轮 PING echo |
| 默认端口 | CH395F TCP Server:8080 |
**操作**
```
终端 1: 编译烧录(启用 ENABLE_PHASE4_TESTS 或 ENABLE_PHASE7_TESTS
终端 2: python test/ch395f_socket_test.py stress --ip 192.168.1.100 --port 8080 --count 10 --timeout 30
```
**通过标准**7 并发 × 10 轮 = 70/70 成功率 100%。
> **关键陷阱**`net_listen()` 中数据 Socket 1~7 的配置必须在监听 Socket 0 的 `OPEN + TCP_LISTEN` **之前**完成。CH395F 在 `TCP_LISTEN` 时刻一次性扫描可用 Socket若颠倒顺序则 Socket 4~7 不被识别,最多只接受 3 个并发连接。详见 `docs/CH395F_Trap_Records.md → Trap 01`。
---
## 3. Python 脚本参考
| 命令 | 说明 |
|------|------|
| `tcp_server --port 8081` | PC 作 TCP Server测试 CH395F TCP Client |
| `tcp_client --ip x.x.x.x --port 8080` | PC 作 TCP Client测试 CH395F TCP Server echo |
| `udp_client --ip x.x.x.x --port 60000 --timeout 30` | PC 发 UDP PING测试 CH395F UDP echo |
| `udp_server --port 8082 --timeout 60` | PC 作 UDP Server接收 CH395F 数据 |
| `stress --ip x.x.x.x --port 8080 --count 10` | 7 并发压力测试 |
| `dhcp_server --dhcp-iface IP --dhcp-mask MASK --dhcp-gw GW` | 内置 DHCP Server完整握手 + 连通性验证(需管理员权限) |
通用参数:
通用参数:
- `--ip`:目标 IP默认 192.168.1.100
- `--port`:端口(各模式默认不同)
- `--count`:测试次数(默认 10
- `--timeout`:超时秒数(默认 30
- `--size`:数据包大小(默认 1024
---
## 4. 常见问题
| 问题 | 原因 | 解决 |
|------|------|------|
| Phase 2 `open_socket: 0x20 (FAIL)` | socket 未完全关闭 | 已修复:先 closeRST不等 disconnect |
| Phase 2 收到 `\x00(\x00\x00...` 乱码 | socket 7`NET_MAX_SOCKETS-1`)默认无发送缓冲 | 在 `open_socket` 前调用 `set_send_buf(sock, 28, 2)` 分配 |
| Phase 3 UDP 收不到数据 | DesIP 设为具体 IP 而非 255.255.255.255 | 设 DesIP=`0xFFFFFFFF` 进入 Server 模式 |
| Phase 3 HELLO 收到但 PING 收不到 | 没等 `SENDBUF_FREE` 就第二次写 | 每次 `write_send_buf` 后轮询 `SINT_STAT_SENDBUF_FREE` |
| Python 报 `WinError 10054` | STM32 还没启动 | 等串口看到阶段启动信息再跑 Python |
| Phase 5 UDP 不工作 | NET 层 `net_bind()` 没打开 CH395F Socket | 已修复:`net_bind()` 对 DGRAM 类型自动打开 |
| `net_recvfrom()` 源地址错误 | UDP 头解析偏移错了 | 已修复:端口读 `header[2-3]`IP 读 `header[4-7]` |
| Phase 8 Socket 4~7 分配不到 | 数据 Socket 配置在 `TCP_LISTEN` 之后CH395F 在 listen 时扫描) | 先配数据 Socket 1~7 的缓冲/端口/协议,再配监听 Socket 0 |
---
## 5. 陷阱记录
详细陷阱记录(含根因分析、解决方案、发现时间)见 `docs/CH395F_Trap_Records.md`
| # | 陷阱 | 对应文件 |
|---|------|----------|
| 01 | Socket 4~7 自动分配不到(初始化顺序) | `net_socket.c``net_listen()` |
| 02 | 数据 Socket 缓冲区重叠 | `net_socket.c``net_listen()` |
| 03 | DHCP 包 xid 偏移错误 | `test/ch395f_socket_test.py` |
| 04 | UDP 发送未等待 SENDBUF_FREE | `ch395f.c` / `ch395f_test.c` |
| 05 | CH395F 与 RTL8305NBI 自动协商不兼容 | `ch395f.c` |
| 06 | TCP KeepAlive 参数非 500ms 倍数 | `net_socket.c``net_init()` |
| 07 | TCP 关闭误用 disconnect 导致 FIN_WAIT_2 | `ch395f.c` |
| 08 | RECV 中断电平触发无限循环 | `net_socket.c``net_poll()` |