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专项)
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
# 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`
|
||||
Reference in New Issue
Block a user