Files
TCP2UART/工程调试指南.md
T
gaoro-xiao c21d85a9da refactor: 适配STM32F103RCT6 + FreeRTOS工程框架,同步baremetal-r8协议手册
- IOC: MCU切换为STM32F103RCTx,添加FREERTOS+TIM4中间件,HAL时间基准改为TIM4
- Keil uvprojx: 目标器件RC,Flash 256KB/48KB SRAM,宏xE,HD Flash算法,启动文件xe.s
- EWARM ewp: 宏xE,ICF/启动文件切换为xe版本
- 启动文件: Stack_Size 0x400→0x800适配FreeRTOS
- 重写项目需求说明/技术实现文档,描述FreeRTOS 5任务架构+lwIP NO_SYS=0
- 新增AT固件使用手册(MUX/NET/LINK协议)和工程调试指南(FreeRTOS专项)
2026-04-09 20:22:48 +08:00

268 lines
7.7 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.
# TCP2UART 调试指导
## 1. 适用范围
本指导面向当前 `TCP2UART` 工程,覆盖以下四类调试场景:
1. `STM32F103RCT6 + CH390D` 的基础 bring-up
2. `SEGGER RTT`、异常陷阱与 FreeRTOS 任务运行状态确认
3. `USART1` 配置口、`USART2/USART3` 数据口与 `MUX / NET / LINK[idx]` 协议联调
4. `TCP Server / TCP Client / UART` 三层数据通路联调与问题隔离
本指导默认基线如下:
1. 当前工程采用 `FreeRTOS` 任务调度架构
2. `CH390` 运行时访问由 `xSpiMutex` 保护,`NetworkTask` 持有主要访问权
3. 调试输出统一使用 `SEGGER RTT`
4. 当前应用层协议模型已经收敛到 `MUX / NET / LINK[idx]`
5. 当前代码应以 `MDK-ARM` 工程构建结果为准
---
## 2. 当前工程边界与真实状态
在进入现场调试前,先统一以下工程边界:
1. 当前项目的主要软件路径已经切换为:
- `NET`:网络基础参数
- `LINK[idx]`:链路配置记录
- `MUX`:数据口承载模式
2. 对外 AT 配置面应只围绕以下命令展开:
- `AT` / `AT+?` / `AT+QUERY`
- `AT+MUX` / `AT+NET` / `AT+LINK`
- `AT+SAVE` / `AT+RESET` / `AT+DEFAULT`
3. 已有结论表明:
- MCU 启动、RTT、FreeRTOS 调度、TIM4 心跳路径可工作
- `CH390D` 基础寄存器读写与 `lwIP netif` 基本链路已经打通过一次
- 真实硬件侧曾定位到 `CH390D` 供电滤波电容虚焊问题
4. 当前调试重点是:
- FreeRTOS 任务是否正常创建与调度
- `MUX / NET / LINK[idx]` 协议是否与代码一致
- UART / TCP / CH390 三层通路是否协同稳定
- 参数保存、复位和恢复流程是否可靠
---
## 3. 代码入口与调试责任边界
### 3.1 启动与 FreeRTOS 入口
以下代码路径是 bring-up 的第一现场:
1. `Core/Src/main.c`
- `main()`:总启动入口
- `SystemClock_Config()`:时钟初始化
- `MX_FREERTOS_Init()`FreeRTOS 任务创建(在 `freertos.c` 中实现)
2. `Core/Src/freertos.c`
- `StartDefaultTask()`:默认任务(LED 心跳 + 看门狗)
- `MX_FREERTOS_Init()`:用户任务创建入口
3. `Core/Src/stm32f1xx_it.c`
- 故障与中断入口
- `TIM4_IRQHandler`HAL 时间基准
- `USART1/2/3``EXTI0`、DMA 回调等联调关键入口
### 3.2 CH390 责任边界
当前 CH390 调试必须遵守以下责任边界:
1. `Drivers/CH390/CH390_Interface.c`GPIO / SPI / 寄存器与内存事务
2. `Drivers/CH390/CH390.c`:芯片级 helper
3. `Drivers/CH390/ch390_runtime.c`:唯一的运行时拥有者
4. `Drivers/LwIP/src/netif/ethernetif.c`netif glue 与轮询桥接
5. SPI 访问由 `xSpiMutex` 保护,避免多任务竞争
### 3.3 配置口与业务口边界
1. `USART1`AT 配置口,接收 `AT` 命令
2. `USART2 / USART3`:数据口,普通透传或 MUX 承载
---
## 4. 当前硬件与调试工具基线
### 4.1 核心硬件对象
1. MCU`STM32F103RCT6`256KB Flash / 48KB SRAM
2. 以太网芯片:`CH390D`
3. 配置串口:`USART1`
4. 数据串口:`USART2 / USART3`
5. 调试输出:`SEGGER RTT`
### 4.2 构建与下载基线
1. `MDK-ARM/TCP2UART.uvprojx`
2. 启动文件:`startup_stm32f103xe.s`
3. 目标器件:`STM32F103RC`
4. 预处理器宏:`USE_HAL_DRIVER, STM32F103xE`
### 4.3 常用调试工具
1. `Keil MDK-ARM`
2. `ST-Link / J-Link`
3. `SEGGER RTT Viewer`
4. `PowerShell`
5. `tools/start_tcp_debug_server.ps1`
6. `tools/tcp_debug_server.py`
---
## 5. FreeRTOS 专项调试
### 5.1 任务状态检查
使用 `vTaskList` 获取所有任务运行状态:
```c
char buf[512];
vTaskList(buf);
SEGGER_RTT_WriteString(0, buf);
```
输出格式:
```text
任务名 状态 优先级 剩余栈 编号
NetworkTask R 4 120 1
UartTask B 4 200 2
ConfigTask B 3 150 3
RouteTask R 3 180 4
DefaultTask B 1 80 5
IDLE R 0 100 6
Tmr Svc B 2 90 7
```
状态码:`R`=Ready, `B`=Blocked, `S`=Suspended, `D`=Deleted, `I`=Invalid
### 5.2 栈溢出检测
已启用 `configCHECK_FOR_STACK_OVERFLOW = 2`,溢出时自动调用:
```c
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
SEGGER_RTT_printf(0, "STACK OVERFLOW: %s\n", pcTaskName);
__BKPT(0);
}
```
### 5.3 堆内存失败检测
已启用 `configUSE_MALLOC_FAILED_HOOK`,分配失败时自动调用:
```c
void vApplicationMallocFailedHook(void)
{
SEGGER_RTT_printf(0, "MALLOC FAILED: Free heap = %u\n", xPortGetFreeHeapSize());
__BKPT(0);
}
```
### 5.4 常见 FreeRTOS 调试陷阱
1. **优先级反转**:使用 Mutex(含优先级继承)而非 Binary Semaphore 保护共享资源
2. **死锁**:多 Mutex 场景确保所有任务按相同顺序获取
3. **中断优先级**FreeRTOS 可管理的 ISR 优先级必须 >= `configMAX_SYSCALL_INTERRUPT_PRIORITY`(本工程 5
4. **栈不足**:每个任务定期调用 `uxTaskGetStackHighWaterMark(NULL)` 检查剩余栈
5. **禁止在中断中调用阻塞 API**:必须使用 `FromISR` 后缀版本
---
## 6. 启动阶段调试顺序
建议按 P0 ~ P5 顺序推进,不要跳层。
### 6.1 P0:确认最小基础条件
1. `MDK-ARM` 可构建并产出新的 `axf/hex/map`
2. 板卡可正常下载与复位
3. RTT 可连接并看到启动输出
4. FreeRTOS 任务创建成功,`DefaultTask` LED 心跳可工作
5. `TIM4` 1ms tick 正常运行
### 6.2 P1:确认 FreeRTOS 调度正常
上电或复位后,优先确认:
1. `StartDefaultTask` 是否进入运行
2. `vTaskList` 输出是否显示所有预期任务
3. `xPortGetFreeHeapSize()` 返回值是否合理
4.`STACK OVERFLOW``MALLOC FAILED` 输出
### 6.3 P2:确认 CH390 初始化链路
启动阶段应重点关注 `NetworkTask` 中初始化日志:
1. `ETH init: gpio`
2. `ETH init: spi`
3. `ETH init: reset`
4. `ETH init: probe`
5. `ETH init: default`
6. `ETH init: mac`
7. `ETH init: done`
### 6.4 P3:确认 TCP 链路
1. lwIP `tcpip_thread` 是否正常运行
2. TCP Server 是否在指定端口监听
3. TCP Client 是否成功连接远端
---
## 7. MUX / NET / LINK[idx] 联调指导
### 7.1 协议总则
与裸机版本完全一致,参见 `AT固件使用手册.md`
### 7.2 推荐最小 MUX 联调顺序
1. 先在 `MUX=0` 下跑通原始透传
2. 再切换 `MUX=1`
3. 先发一个控制帧,确认 `DSTMASK=0x00` 路径可通
4. 再发一个单目标数据帧
5. 最后验证多目标位图转发
---
## 8. 异常、卡死与假死排查
### 8.1 看到 `TRAP:` 时怎么做
1. 先记录 RTT 中的 trap 标签
2. 立刻用调试器查看当前 PC / LR / 调用栈
3. 结合 `Core/Src/stm32f1xx_it.c` 中对应 handler 定位异常类型
### 8.2 FreeRTOS 任务卡死时怎么做
1. 使用 `vTaskList` 检查各任务状态
2. 如果某个任务始终 `B`(Blocked),检查其等待的队列/信号量
3. 检查是否有 Mutex 被持有但从未释放
4. 使用调试器暂停,查看各任务的调用栈
### 8.3 常见 FreeRTOS 陷阱
1. 在 ISR 中误调用阻塞 API(如 `xQueueSend` 而非 `xQueueSendFromISR`
2. 中断优先级低于 `configMAX_SYSCALL_INTERRUPT_PRIORITY` 但调用了 FreeRTOS API
3. Mutex 持有期间任务被删除导致 Mutex 永不释放
4. 栈溢出导致邻近变量被破坏
---
## 9. 常见误区
1. 不要继续沿用"CH390 恒为全 `0xFF`"过时结论
2. 不要在多个任务中直接访问 CH390 SPI(必须通过 Mutex 保护)
3. 不要在没有芯片脚侧证据前,只凭 GPIO 判断总线正常
4. 不要在基础寄存器读写尚不可信时,直接调高层业务
5. 不要在 ISR 中执行复杂 SPI 事务或调用阻塞 API
6. 不要忽视 `configCHECK_FOR_STACK_OVERFLOW` 报告
---
## 10. 推荐配套阅读
1. `AT固件使用手册.md`
2. `项目技术实现.md`
3. `项目需求说明.md`
4. `Keil工程配置说明.txt`