14 KiB
TCP2UART 调试指导
1. 适用范围
本指导面向当前 TCP2UART 工程,覆盖以下四类调试场景:
STM32F103R8T6 + CH390D的基础 bring-upSEGGER RTT、异常陷阱与主循环运行状态确认USART1配置口、USART2/USART3数据口与MUX / NET / LINK[idx]协议联调TCP Server / TCP Client / UART三层数据通路联调与问题隔离
本指导默认基线如下:
- 当前工程采用裸机主循环架构,未使用 FreeRTOS 参与主业务调度
CH390运行时访问统一由ch390_runtime持有- 调试输出统一使用
SEGGER RTT - 当前应用层协议模型已经收敛到
MUX / NET / LINK[idx] - 当前代码应以
MDK-ARM工程构建结果为准,而不是CMake + MSVC结果
2. 当前工程边界与真实状态
在进入现场调试前,先统一以下工程边界,避免沿用过时结论:
- 当前项目的主要软件路径已经切换为:
NET:网络基础参数LINK[idx]:链路配置记录MUX:数据口承载模式
- 对外 AT 配置面应只围绕以下命令展开:
ATAT+?AT+QUERYAT+MUXAT+NETAT+LINKAT+SAVEAT+RESETAT+DEFAULT
- 当前
CH390D的历史“全0xFF/ 全0x0000”结论不应再直接沿用。 - 已有结论表明:
- MCU 启动、RTT、主循环、TIM4 心跳路径可工作
CH390D基础寄存器读写与lwIP netif基本链路已经打通过一次- 真实硬件侧曾定位到
CH390D供电滤波电容虚焊问题
- 因此,当前调试重点不再是“CH390 是否完全不通”,而是:
- 启动阶段是否稳定
MUX / NET / LINK[idx]协议是否与代码一致- UART / TCP / CH390 三层通路是否协同稳定
- 参数保存、复位和恢复流程是否可靠
3. 代码入口与调试责任边界
3.1 启动与主循环入口
以下代码路径是 bring-up 的第一现场:
Core/Src/main.cmain():总启动入口SystemClock_Config():时钟初始化App_Init():应用层初始化App_Poll():主循环核心路径BootDiag_ReportCh390():启动阶段 CH390 诊断输出
Core/Src/stm32f1xx_it.c- 故障与中断入口
USART1/2/3、EXTI0、DMA 回调等联调关键入口
3.2 CH390 责任边界
当前 CH390 调试必须遵守以下责任边界:
Drivers/CH390/CH390_Interface.c- 只负责 GPIO / SPI / 寄存器与内存事务
Drivers/CH390/CH390.c- 只负责芯片级 helper,例如默认配置、PHY、MAC 读写
Drivers/CH390/ch390_runtime.c- 唯一的运行时拥有者
- 负责初始化、链路检查、IRQ 消费、RX/TX 服务与诊断快照
Drivers/LwIP/src/netif/ethernetif.c- 只承担 netif glue 与轮询桥接,不应重新下沉复杂 CH390 运行时事务
Core/Src/main.c- 启动后只通过 runtime 对外暴露的诊断与轮询接口工作
调试时不要把原始 CH390 寄存器访问重新散回 main.c、中断或多个业务层。
3.3 配置口与业务口边界
USART1- 配置口
- 负责接收
AT命令 - 当前接收逻辑在:
Core/Src/main.c的App_PollUart1ConfigRx()Core/Src/stm32f1xx_it.c的HAL_UART_RxCpltCallback()App/config.c的config_uart_rx_byte()/config_process_at_cmd()
USART2 / USART3- 数据口
- 负责普通透传或 MUX 承载
- 当前入口在
App/uart_trans.c
4. 当前硬件与调试工具基线
4.1 核心硬件对象
- MCU:
STM32F103R8T6 - 以太网芯片:
CH390D - 配置串口:
USART1 - 数据串口:
USART2 / USART3 - 调试输出:
SEGGER RTT
4.2 构建与下载基线
当前建议优先使用以下工程与产物:
MDK-ARM/TCP2UART.uvprojxMDK-ARM/TCP2UART/TCP2UART.axfMDK-ARM/TCP2UART/TCP2UART.hexMDK-ARM/TCP2UART/TCP2UART.mapMDK-ARM/TCP2UART/TCP2UART.build_log.htmbuild_keil.log
说明:
- 当前
CMake configure可以完成,但CMake + MSVC不适合作为 STM32/CMSIS 的最终构建验收依据。 - 若需要验证“当前代码是否真实可编译”,优先看
MDK-ARM构建产物与日志。
4.3 常用调试工具
Keil MDK-ARMST-Link / J-LinkSEGGER RTT ViewerPowerShelltools/start_tcp_debug_server.ps1tools/tcp_debug_server.py
5. 启动阶段调试顺序
建议按 P0 ~ P5 顺序推进,不要跳层。
5.1 P0:确认最小基础条件
每次现场调试前,先确认:
MDK-ARM可构建并产出新的axf/hex/map- 板卡可正常下载与复位
- RTT 可连接并看到启动输出
- LED 心跳可工作
App_Poll()已经进入稳定轮询
这一层若失败,不要进入网络或协议调试。
5.2 P1:确认启动日志与 trap 状态
上电或复位后,优先看 RTT 输出中是否出现:
TCP2UART boot- 若 HSE 启动失败,则会出现:
WARN: HSE start failed, fallback to HSI PLL
BootDiag_ReportCh390()输出的 CH390 诊断与网络配置快照
若发生异常,优先观察是否打印:
TRAP: Error_HandlerTRAP: HardFault_HandlerTRAP: MemManage_HandlerTRAP: BusFault_HandlerTRAP: UsageFault_Handler
当前 trap 统一收敛到:
Core/Src/main.c的Debug_TrapWithRttHint()- 它会打印 RTT、执行
__BKPT(0)并停住
因此,若 RTT 中出现 TRAP:,应立即接调试器看断点现场,而不是继续盲猜高层逻辑。
5.3 P2:确认 CH390 初始化链路
启动阶段应重点关注 Drivers/CH390/ch390_runtime.c 中初始化阶段日志,理想情况下应能依次看到:
ETH init: gpioETH init: spiETH init: resetETH init: probeETH init: defaultETH init: macETH init: getmacETH init: irqETH init: done
此阶段重点判定:
VID / PID / REV是否可信- PHY 寄存器是否稳定可读
- MAC 写入与回读是否一致
link_up是否与真实网线状态一致
若这一层失败,优先做硬件侧量测,而不是先改业务层:
RSTBCSSCKMOSIMISOINTVDDKAVDD33 / VDDIO / AVDD33XI / XO
6. USART1 配置口调试
6.1 当前命令面
根据当前代码与手册,配置口应围绕以下命令验证:
ATAT+?AT+QUERYAT+MUX=...AT+MUX?AT+NET=...AT+NET?AT+LINK=...AT+LINK?AT+SAVEAT+RESETAT+DEFAULT
6.2 现场关键规则
根据已有联调记录,配置口最关键的 bench 规则是:
- 当前现场验证时,配置命令必须保证以换行完成帧。
- 若主机侧发送方式不对,现象会很像“配置口完全无响应”。
- 因此,配置口不响应时,第一优先级不是改 parser,而是先验证主机端发送格式与接线。
6.3 最小验证步骤
建议按以下顺序验证:
- 连接
USART1 - 先发
AT - 再发
AT+QUERY - 再发
AT+NET? - 再发
AT+LINK? - 修改一个最小参数,例如:
AT+MUX=1
- 执行:
AT+SAVEAT+RESET
- 复位后再次查询,确认配置是否保留
6.4 持久化失败时怎么查
优先检查以下路径:
App/config.cconfig_save()config_load()config_set_defaults()
App/flash_param.c- Flash 解锁
- 页擦除
- 半字编程
- 写后校验
- 参数页地址:
0x0800FC00
不要在还没证明 AT+SAVE 已真正被接受之前,就直接把 Flash 全 FFFFFFFF 归因到 Flash 驱动错误。
7. MUX / NET / LINK[idx] 联调指导
7.1 协议总则
当前协议必须按以下模型理解:
MUX:全局数据承载模式开关NET:IP / Mask / GW / MACLINK[idx]:链路配置项
固定链路索引映射为:
LINK[0] = S1LINK[1] = S2LINK[2] = C1LINK[3] = C2
固定端点编码为:
C1 = 0x01C2 = 0x02UART2 = 0x04UART3 = 0x08S1 = 0x10S2 = 0x20
7.2 MUX 数据口规则
当 MUX=1 时,数据口应使用 MUX 帧。
重点规则:
DSTMASK=0x00表示系统控制帧- 控制帧中的 AT 文本必须严格按手册要求结束
- 普通数据帧走业务转发路径,不应进入配置解析器
7.3 调试时重点检查什么
若怀疑 MUX 模式不工作,优先检查:
App/uart_trans.cuart_mux_try_extract_frame()uart_mux_encode_frame()
Core/Src/main.cApp_RouteMuxUartTraffic()App_RouteRawUartTraffic()App_RouteTcpTraffic()
App/config.cconfig_build_response_frame()config_process_at_cmd()
推荐最小 MUX 联调顺序:
- 先在
MUX=0下跑通原始透传 - 再切换
MUX=1 - 先发一个控制帧,确认
DSTMASK=0x00路径可通 - 再发一个单目标数据帧,例如只打到
S1 - 最后验证多目标位图转发
8. TCP / UART / CH390 联调顺序
8.1 先做链路,再做业务
在 CH390 初始化、链路和 IRQ 未被证明稳定前,不要先调高层 TCP/UART 业务。
8.2 推荐顺序
建议按以下顺序推进:
- RTT 启动与 trap 状态正常
- CH390 启动日志完整
- 链路检测可信
TCP server/TCP client建链可信- UART 原始透传可信
- 再切入
MUX模式联调
8.3 最小 TCP 调试工具
当需要验证板子是否真的把 payload 发到主机时,优先使用仓库内置最小工具:
tools/tcp_debug_server.py- 打印连接、收包、文本视图和十六进制视图
tools/start_tcp_debug_server.ps1- 会先清理冲突监听,再启动 Python 服务端
推荐命令:
powershell -ExecutionPolicy Bypass -File ".\tools\start_tcp_debug_server.ps1" -Port 8081 -NoStdin
如需回显:
powershell -ExecutionPolicy Bypass -File ".\tools\start_tcp_debug_server.ps1" -Port 8081 -Echo
直接运行 Python 服务端也可以:
python .\tools\tcp_debug_server.py --host 0.0.0.0 --port 8081 --no-stdin
8.4 推荐验证方法
- 先关闭 VOFA、
ncat和其它可能占用8081的进程 - 启动
start_tcp_debug_server.ps1 - 让板子连接主机
TCP client目标端口 - 再从主机连接板子的
TCP server端口发送固定测试文本 - 同时观察:
- Python 工具是否收到连接与 payload
- 板子 RTT 是否出现连接或错误信息
若板子 RTT 显示已连接,但主机工具无数据,优先检查本机端口占用而不是先改板端逻辑。
9. 异常、卡死与假死排查
9.1 看到 TRAP: 时怎么做
- 先记录 RTT 中的 trap 标签
- 立刻用调试器查看当前 PC / LR / 调用栈
- 结合
Core/Src/stm32f1xx_it.c中对应 handler 定位异常类型
9.2 没有 TRAP: 但系统不工作时怎么做
若没有 TRAP:,但系统表现异常,应优先区分以下情况:
- 主循环仍在跑,只是业务路径没反应
- 中断未到或链路未更新
- 发生了阻塞式等待或超时问题
- 上层工具接错端口或被错误进程抢占
9.3 历史上已经确认过的典型软件问题
以下问题在历史排查中已经出现过,应优先复核,不要重复踩坑:
- PHY 访问无超时,导致永久卡死
- 刷新未初始化的 IWDG 句柄导致 HardFault
- 在长耗时 SPI 路径中错误扩大临界区,导致看似“系统假死”
- 在多个层次同时触达 CH390 / SPI,导致运行时边界混乱
- 配置口命令结束方式不对,导致误判为 parser 无响应
10. 常见误区
调试当前工程时,应避免以下误区:
- 不要继续沿用“CH390 恒为全
0xFF”这一过时结论 - 不要在
main.c、IRQ、netif 多处重新插入原始 CH390 访问 - 不要在没有芯片脚侧证据前,只凭 MCU 侧 GPIO 判断总线正常
- 不要在基础寄存器读写尚不可信时,直接调高层
TCP/UART/MUX业务逻辑 - 不要把一次性 bring-up 实验代码长期留在正式路径中
- 不要让多个本机进程同时监听板子要连接的 TCP 端口
- 不要在尚未证明命令已真正进入 parser 之前,直接归因到 Flash、协议或网络层
11. 推荐的现场记录模板
建议每次现场调试至少记录以下信息:
- 日期时间
- 板卡编号
- 固件产物路径
- 下载方式
- RTT 关键日志
- 串口发送内容
- TCP 调试工具输出
- 关键波形或电压量测点
- 结论
- 下一步动作
建议记录格式:
时间:
板卡:
固件:
下载方式:
操作步骤:
RTT输出:
串口/TCP现象:
硬件量测:
结论:
下一步:
12. 当前推荐的结论表达方式
若需要向项目成员同步当前状态,建议采用以下口径:
- 当前工程软件架构已稳定在
bare-metal + lwIP RAW + ch390_runtime 单一拥有者 - 当前调试重点已经从“CH390 是否完全无响应”转移到协议、链路和系统级联调
- 当前对外协议和配置模型应以
MUX / NET / LINK[idx]为准 USART1配置口、USART2/3数据口与 TCP 路由必须按最新代码路径调试,不应再参照历史IP/MASK/GW/PORT/RIP/RPORT公开接口模型- 硬件验证仍必须以 CH390 芯片脚侧波形和供电域量测为准
13. 建议配套阅读
建议与本指导配套阅读:
AT固件使用手册.md项目技术实现.md项目需求说明.mduart-ch390-debug-handoff.mdCH390_最终结论报告.mdbuild_keil.logPCB/SCH_Schematic1_2026-03-26.pdftools/tcp_debug_server.pytools/start_tcp_debug_server.ps1