9.4 KiB
CH395F 测试使用指南
目录
1. 快速开始
启用/禁用测试
编辑 Drivers/BSP/CH395F/ch395f_test.h,取消注释想要测试的阶段:
//#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:60000,PC 发到 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:8080,PC 连到 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 4(TCP Client 连 8080)。
通过标准:同 Phase 4(10/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 17 的配置必须在监听 Socket 0 的7 不被识别,最多只接受 3 个并发连接。详见OPEN + TCP_LISTEN之前完成。CH395F 在TCP_LISTEN时刻一次性扫描可用 Socket,若颠倒顺序则 Socket 4docs/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 未完全关闭 | 已修复:先 close(RST)不等 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() |