# TCP2UART 调试交接清单 ## 1. 文档目的 本清单用于把当前 `TCP2UART` 工程的调试状态、已验证结论、后续动作建议一次性交接给下一位 agent 或开发者。 这份文档本身就可以当作下一位 agent 的工作 prompt 使用。 --- ## 2. 先读哪些文档 接手本工程后,推荐按以下顺序阅读: 1. `交接清单.md` —— 当前状态、下一步、禁止回退到哪些旧假设 2. `工程调试指南.md` —— 已固化的调试经验与真实工程边界 3. `项目技术实现.md` —— 架构、任务模型、协议模型 4. `项目需求说明.md` —— 用户需求与协议要求 5. `AT固件使用手册.md` —— AT 命令与配置面 --- ## 3. 当前工程状态(交接时刻) ### 3.1 当前平台与构建状态 1. 当前 Keil 工程目标仍是 `STM32F103RC` 2. 当前代码可以真实构建通过 3. 当前 FreeRTOS + lwIP 固件版本线从 `V2.0.0` 开始,裸机固件版本线从 `V1.0.0` 开始 4. 当前 RTOS 基线 release:`https://git.furtherverse.com/gaoro-xiao/TCP2UART/releases/tag/V2.0.0` 5. Release 附件: - `TCP2UART-RTOS-V2.0.0.hex` - `TCP2UART-RTOS-V2.0.0.elf` 6. 当前构建真值应查看: - `MDK-ARM/build_capture.txt` - `MDK-ARM/TCP2UART/TCP2UART.build_log.htm` - `MDK-ARM/TCP2UART/TCP2UART.map` 7. `V2.0.0` release 构建验证: - `"TCP2UART\TCP2UART.axf" - 0 Error(s), 0 Warning(s).` - `TCP2UART-RTOS-V2.0.0.hex` 用于烧录 - `TCP2UART-RTOS-V2.0.0.elf` 用于符号/调试 ### 3.2 当前调试结论摘要 1. `DIAG_TASK_ISOLATION=1` 稳定 2. `DIAG_TASK_ISOLATION=0` 仍会卡死 3. 卡死边界已经从更早的启动阶段被推进到更靠后的 enabled `netconn_*` 路径 4. 在 `RCT6` 上,四个 TCP task 创建后 `FreeRTOS heap` 仅剩约 `944 bytes` 5. 这说明当前 `RCT6` 上的资源余量已经严重干扰调试判断 6. 因此当前推荐策略是:**先换到 pin2pin 的 `STM32F103RDT6`,再继续 full-task 调试** ### 3.3 已做过并有信息量的改动/观察 以下工作已经做过,不要在没有新理由的情况下重复一遍: 1. 清理与恢复 `DIAG_TASK_ISOLATION=0` 2. 用真实 Keil 日志替代 viewer 作为构建真值 3. staged creation:将四个 TCP task 延后到 `netif-ready` 后创建 4. `lwIP netif` 初始化、post-init、post-ready 关键 RTT 日志 5. CH390 TX bounded wait / timeout 观察 6. TCP task 栈从 `256` 提高到 `384 words` 7. TCP task 入口 `hwm` 日志 8. 对 `C1` 增加 one-shot first-connect defer discriminator 这些动作都让故障边界后移了,但仍未在 `RCT6` 上把问题彻底消灭。 --- ## 4. 当前最可信的判断 当前最可信的判断不是“某一行代码单点必错”,而是: 1. `RCT6` 上的静态 RAM 占用与 FreeRTOS heap 余量都已经接近极限 2. disabled 的 task 可以持续打印,说明调度器与基础日志路径未整体死亡 3. enabled 的 `S1 / C1` 一旦进入真实 `netconn_*` 路径,就更容易触发新的运行期问题 4. 因此如果继续在 `RCT6` 上做更多 discriminator,很容易一直被资源边界噪声带偏 换句话说,**先把“内存极限平台”这个干扰项拿掉,再看逻辑问题还剩多少,是当前性价比最高的路线。** --- ## 5. 下一位 agent 现在应该做什么 ### 5.1 第一目标 先完成 `STM32F103RCT6 -> STM32F103RDT6` 的工程切换,然后在**尽量不再改业务逻辑**的前提下复现当前版本。 ### 5.2 为什么先这样做 因为下一位 agent 最先需要回答的,不是“立刻怎么修”,而是: 1. 换片后 full-task 模式是否还挂 2. 如果还挂,挂点是否后移 3. 换片后 `free/min heap` 是否显著改善 4. enabled `S1 / C1` 是否能进入更深的 `netconn_*` 路径 --- ## 6. 下一位 agent 的推荐工作步骤 ### Step 1:切换目标器件到 `STM32F103RDT6` 建议动作: 1. 更新 Keil target 里的 device 选择 2. 对齐 Flash / RAM 容量描述 3. 确认 linker / scatter / startup 相关目标描述与新器件一致 4. 再次真实构建,确认 `0 Error(s), 0 Warning(s)` ### Step 2:保持当前代码基线,直接上板复测 要求: 1. 不要一换片就继续改业务逻辑 2. 使用当前代码基线直接验证 3. 仍以 `build_capture.txt` 和 RTT 为主证据 ### Step 3:收集第一轮换片后的关键证据 至少记录: 1. `netif-ready` 后是否仍卡死 2. `free/min heap` 变化 3. enabled `S1 / C1` 的新 RTT 行为 4. `C1 first-connect defer` 是否仍然影响故障边界 5. LED 心跳和 IWDG 表现是否变化 ### Step 4:根据换片结果分流 #### 情况 A:换片后明显稳定 / 不再挂 说明: 1. RAM 压力是主要阻碍项之一 2. 后续需要回头做“资源预算收敛”,而不是继续把当前临时参数直接当最终方案 #### 情况 B:换片后仍挂,但更晚 / 更深 说明: 1. 当前逻辑问题仍在 2. 但已经去掉了最主要的资源噪声 3. 这时再围绕 `S1 / C1` 的真实 `netconn_new / bind / connect / listen / accept` 做最小日志/判别,会更有信息量 #### 情况 C:换片后几乎同点位仍挂 说明: 1. 主问题不再是单纯 RAM 2. 应优先检查 enabled 路径的 API 使用、阻塞行为、线程间交互与资源释放 --- ## 7. 不要重复的方向 下一位 agent 接手后,除非有新证据,否则不要优先回到以下旧方向: 1. 单纯怀疑 startup/init 早期 bring-up 2. 把 viewer 当构建真值 3. 继续只靠加大 TCP task 栈来解释所有现象 4. 默认把 CH390 TX timeout 当成当前一号嫌疑 5. 在 `RCT6` 上继续大量增加日志、队列、栈或临时 buffer --- ## 8. 关键文件 ### 构建/目标 1. `MDK-ARM/TCP2UART.uvprojx` 2. `MDK-ARM/build_capture.txt` 3. `MDK-ARM/TCP2UART/TCP2UART.build_log.htm` 4. `MDK-ARM/TCP2UART/TCP2UART.map` ### 任务与运行期 1. `Core/Inc/FreeRTOSConfig.h` 2. `Core/Src/freertos.c` 3. `App/task_net_poll.c` 4. `App/tcp_server.c` 5. `App/tcp_client.c` ### 网络与驱动 1. `Drivers/LwIP/src/netif/ethernetif.c` 2. `Drivers/CH390/CH390.c` 3. `Drivers/CH390/CH390.h` ### 文档 1. `工程调试指南.md` 2. `项目技术实现.md` 3. `交接清单.md` 4. `CODING_PROMPT.md` --- ## 9. 可直接给下一位 agent 的 Prompt 下面这段文字可以直接作为下一位 agent 的起始 prompt: ```text 请先阅读:`交接清单.md`、`工程调试指南.md`、`项目技术实现.md`。 当前项目是 STM32F103 + FreeRTOS + lwIP + CH390 的 TCP↔UART 透传工程。此前在 `STM32F103RCT6` 上调试时,`DIAG_TASK_ISOLATION=1` 稳定,`DIAG_TASK_ISOLATION=0` 仍会卡死,但故障边界已被多轮 discriminator 推进到 enabled 的 `netconn_*` 路径。当前最关键的资源事实是:在 `RCT6` 上 full-task 创建完四个 TCP 任务后,FreeRTOS heap 只剩约 944 bytes,静态 RAM 也已逼近物理上限,因此当前推荐先切换到 pin2pin 的 `STM32F103RDT6`,保持现有代码基线基本不变,先完成第一轮换片复测,再根据新器件上的 RTT、free/min heap 和 enabled `S1/C1` 行为决定下一步。 你的当前目标不是立刻修完所有问题,而是: 1. 完成 `RCT6 -> RDT6` 目标切换; 2. 用真实 Keil 日志确认构建通过; 3. 在新器件上复测当前代码,判断故障是否消失、后移或保持原状; 4. 仅在拿到新器件上的第一轮 RTT 后,再继续做最小化的下一步判别。 ```