9.8 KiB
9.8 KiB
TCP2UART 项目技术实现
一、当前实现结论
当前工程已经从原先的 FreeRTOS + lwIP socket/netconn 方向,重构为适配 STM32F103R8T6 的裸机实现。
当前基线特征如下:
- MCU 目标固定为
STM32F103R8T6 / STM32F103xB - 软件架构改为
bare-metal main loop + DMA/IDLE + EXTI - 网络栈采用
lwIP RAW API + NO_SYS=1 - 调试输出采用
SEGGER RTT CH390运行时访问已收敛为单一拥有者ch390_runtime- 构建目标已通过
MDK-ARM编译,适配64KB Flash / 20KB SRAM
二、硬件与资源约束
2.1 MCU
- 型号:
STM32F103R8T6 - Flash:
64 KB - SRAM:
20 KB - 主频:
72 MHz
2.2 主要外设
SPI1:连接CH390DUSART1:配置串口USART2:Server 透传串口USART3:Client 透传串口DMA1:UART 收发 DMAEXTI0:CH390 中断输入IWDG:独立看门狗TIM4:LED 心跳定时器
当前说明:
IWDG外设仍保留在工程中,但当前调试基线默认不在main()中启用MX_IWDG_Init()App_Poll()已对HAL_IWDG_Refresh(&hiwdg)做句柄保护,避免未初始化句柄导致HardFault
2.3 当前引脚分配
| 引脚 | 功能 | 用途 |
|---|---|---|
| PA2 | USART2_TX | Server 透传串口 |
| PA3 | USART2_RX | Server 透传串口 |
| PA4 | GPIO_Output | CH390D 片选 |
| PA5 | SPI1_SCK | CH390D SPI 时钟 |
| PA6 | SPI1_MISO | CH390D SPI 数据输入 |
| PA7 | SPI1_MOSI | CH390D SPI 数据输出 |
| PA9 | USART1_TX | 配置串口 |
| PA10 | USART1_RX | 配置串口 |
| PB0 | EXTI0 | CH390D INT |
| PB1 | GPIO_Output | CH390D RESET |
| PB10 | USART3_TX | Client 透传串口 |
| PB11 | USART3_RX | Client 透传串口 |
| PC13 | GPIO_Output | 状态 LED |
| PD0/PD1 | HSE | 8MHz 外部晶振 |
三、架构选择原因
STM32F103R8T6 的资源上限不足以稳定承载原方案中的以下组合:
FreeRTOSCMSIS-RTOS V2- 多任务栈
lwIP socket/netconn/tcpipOS 路线StreamBuffer / Semaphore / Mutex
因此当前实现采用如下组合:
- 去掉
FreeRTOS - 去掉
CMSIS-RTOS V2 - 去掉
lwIP socket/netconn - 改为
lwIP RAW API + NO_SYS=1 - 串口与网口统一由主循环推进
四、当前软件架构
4.1 分层
+--------------------------------------------------+
| Application Logic |
| config / tcp_server / tcp_client / uart bridge |
+--------------------------------------------------+
| Main Poll Loop |
| ethernetif_poll / sys_check_timeouts / watchdog |
+--------------------------------------------------+
| CH390 Runtime Owner |
| ch390_runtime (single runtime SPI owner) |
+--------------------------------------------------+
| Peripheral/Event Layer |
| UART DMA+IDLE / DMA IRQ / EXTI / SysTick |
+--------------------------------------------------+
| Drivers |
| CH390 / lwIP netif / HAL |
+--------------------------------------------------+
4.2 执行模型
当前执行模型为:
SysTick提供全局毫秒时基EXTI0只置位 CH390 待处理标志,不直接做 SPI/CH390 访问DMA IRQ和UART IRQ只完成回调分发与 IDLE 采样ch390_runtime成为唯一的 CH390 运行时访问源- 主循环统一执行网络轮询、超时推进、串口桥接和看门狗喂狗
五、当前模块实现状态
5.1 配置模块
文件:App/config.c/.h
已实现:
- 从 Flash 加载配置
- UART1 命令口接收
- 常用网络与串口参数解析
- 参数保存与软复位请求
当前约束:
- 构建已关闭
DHCP,因此AT+DHCP=1会明确返回错误 - 配置损坏时会回退默认值,但默认值不会自动写回 Flash,仍需手动
AT+SAVE
5.2 UART 透传模块
文件:App/uart_trans.c/.h
已实现:
USART2/USART3使用DMA + IDLE- RX 使用 DMA 缓冲转环形缓冲
- TX 使用 DMA 发送
- TX/RX 完成由
HAL_UART_*Callback驱动
5.3 TCP Server 模块
文件:App/tcp_server.c/.h
已实现:
lwIP RAW API监听指定端口- 单连接接入
- 网络数据写入本地环形缓冲
- 主循环中与 UART2 做双向桥接
5.4 TCP Client 模块
文件:App/tcp_client.c/.h
已实现:
lwIP RAW API主动连接远端地址- 断链后按周期重连
- 网络数据写入本地环形缓冲
- 主循环中与 UART3 做双向桥接
5.5 CH390 与 netif 模块
文件:Drivers/CH390/*、Drivers/LwIP/src/netif/*
已实现:
SPI1 + GPIO CS + EXTI0驱动 CH390ethernetif.c采用NO_SYS=1路线- 新增
Drivers/CH390/ch390_runtime.c,统一负责 CH390 初始化、链路查询、IRQ pending 消费、RX/TX 服务与启动诊断快照 main.c不再直接读取 CH390 原始寄存器,启动诊断通过ch390_runtime_get_diag()获取快照EXTI0_IRQHandler()只投递 IRQ pending,不再直接混入 CH390 访问- 配置中的 MAC 地址会在初始化时写入 CH390
当前状态:
- 运行时架构层面的
SPI/LwIP/CH390多源访问问题已经消除 HardFault与“运行一会儿卡死”问题已修复- CH390D 当前已恢复基础寄存器读写,调试重点已从“SPI 是否完全不通”转入初始化完整性、链路、中断与收发功能验证
- 最终实板定位表明,一颗 CH390D 供电滤波电容虚焊会直接导致供电不稳,并放大为网络收发异常
5.6 RTT 调试输出
文件:Middlewares/Third_Party/SEGGER_RTT/*
已实现:
- 工程内置最小
SEGGER RTT源文件 main.c中printf/fputc已重定向到 RTT
5.7 TIM4 心跳闪烁
文件:Core/Src/tim.c、Core/Src/main.c、Core/Src/stm32f1xx_it.c
已实现:
- 使用
TIM4作为 LED 心跳定时器 TIM4时钟来自APB1 Timer Clock = 72 MHz- 通过
Prescaler = 7199和Period = 9生成1 ms更新中断 - 在
HAL_TIM_PeriodElapsedCallback()中进行 1ms 计数 - 累计
1000次后翻转一次PC13,形成1 s闪烁节拍
当前实现说明:
PC13为低电平点亮、高电平熄灭- 当前逻辑为每
1 s翻转一次 LED 状态,即完整亮灭周期为2 s - 若后续需要“每 1 秒完整闪烁一次”,可改为
500 ms翻转一次
六、lwIP 配置策略
当前 lwIP 配置以适配 R8T6 资源为原则,核心策略如下:
NO_SYS = 1LWIP_SOCKET = 0LWIP_NETCONN = 0LWIP_NETIF_API = 0LWIP_DHCP = 0LWIP_UDP = 0LWIP_DNS = 0LWIP_IGMP = 0- 关闭
lwIP平台诊断printf
同时从 MDK 工程中移除了:
FreeRTOS相关源码lwIP api/socket/netconn/tcpip路线源码altcp / autoip / acd / dhcp / dns / igmp等当前不需要模块
七、主循环实际骨架
当前主循环逻辑可概括为:
while (1)
{
ethernetif_poll();
ethernetif_check_link();
sys_check_timeouts();
tcp_client_poll();
uart_trans_poll();
config_poll();
tcp_server <-> UART2;
tcp_client <-> UART3;
if (reset_requested) {
NVIC_SystemReset();
}
if (hiwdg.Instance == IWDG) {
HAL_IWDG_Refresh(&hiwdg);
}
}
八、当前构建状态
8.1 MDK 构建命令
"C:\Keil_v5\UV4\UV4.exe" -b "D:\code\STM32Project\TCP2UART\MDK-ARM\TCP2UART.uvprojx" -j0
8.2 当前结果
当前构建结果:
0 Error(s)0 Warning(s)- 代码体积仍满足
STM32F103R8T6资源约束 MDK-ARM工程可直接编译并下载验证
说明当前版本已经满足:
STM32F103R8T6 64KB Flash约束20KB SRAM约束MDK-ARM可直接编译
九、当前已知限制与待验证项
9.1 功能限制
- 当前使用静态 IP,不支持 DHCP
- 当前已验证 CH390 基础寄存器读写、PHY 管理寄存器访问与 lwIP
netif链路置位路径;RX/TX 实际业务流量仍需继续做板上验证 - 目前未提供完整的上板网络吞吐、丢包率与长时间稳定性报告
config模块仍保留较重的字符串解析逻辑,但当前体积已可接受
9.2 上板验证重点
- 验证 CH390
RST/CS/SCK/MOSI/MISO/INT在芯片脚侧的实际波形与当前软件假设一致 - 验证
VID/PID/REV、MAC 写回、RCR/IMR/INTCR、PHY 寄存器与LINK/netif链路状态在多次上电下稳定一致 - 验证
TIM41ms 中断稳定性与PC131秒翻转节拍 - 验证
UART2/UART3 DMA + IDLE在长连续流量下的行为 - 验证 TCP Server 与 TCP Client 双链路同时工作时的稳定性
- 验证配置保存、复位、MAC 生效路径
- 验证 CH390 收发路径、链路变化中断与 RX/TX 数据通路
十、后续建议
下一阶段建议按以下顺序推进:
- 在当前可读写基线下,优先验证
default_config、MAC、PHY 协商/链路、IRQ、RX/TX 是否完整生效 - 同步用芯片脚侧波形与电源域量测验证
RST/CS/SCK/MOSI/MISO/INT和VDDK/AVDD33/VDDIO/AVDD33 - 若链路与寄存器状态可信,再推进 TCP Server / TCP Client 与 UART2 / UART3 的双向联调
- 完成后补充吞吐、丢包、长稳与异常恢复测试
十一、当前结论
截至本轮调试:
- 系统主循环、RTT、定时器心跳、UART 配置路径均可正常工作
- 已修复并验证多个真实软件问题,且相关中间里程碑已提交版本库
- CH390D 当前已恢复基础寄存器读写,且已在实机上验证
VID=0x1C00、PID=0x9151、REV=0x2B、PHY ID 可读 - 运行时
lwIP netif已观察到LINK_UP置位,说明当前阶段已不再是“完全无响应”或“链路始终未起” - 当前硬件修复后,ARP/Ping 基础链路已验证通过,后续重点转为业务流量与长稳验证
- 板级供电完整性应作为 CH390D 调试前置检查项,而不是放到软件排查后期才介入