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

13 KiB
Raw Blame History

TCP2UART 项目技术实现

一、文档目的

本文档描述 TCP2UART 项目基于 STM32F103RCT6 + FreeRTOS 的最终内部实现口径。

本文档只围绕最终协议模型展开:

  • MUX:串口承载层
  • NET:全局网络配置层
  • LINK[idx]:实例配置与连接管理层

不再保留历史 S1... / C1... 外部字段模型。

二、当前工程基础

当前工程基础约束如下:

  1. MCUSTM32F103RCT6256KB Flash / 48KB SRAM
  2. 网络芯片:CH390D
  3. 软件架构:FreeRTOS + lwIP NO_SYS=0
  4. 协议栈:lwIP socket/netconn API
  5. 调试输出:SEGGER RTT
  6. 使用 FreeRTOS 任务调度
  7. 不实现 DHCP

三、总体架构

+--------------------------------------------------+
| AT / Control Plane                               |
| USART1 AT parser + MUX control frame parser      |
+--------------------------------------------------+
| Configuration Model                              |
| MUX / NET / LINK[idx]                            |
+--------------------------------------------------+
| FreeRTOS Tasks                                   |
| NetworkTask / UartTask / ConfigTask / RouteTask  |
+--------------------------------------------------+
| Inter-Task Communication                         |
| Queue / Semaphore / Mutex / StreamBuffer         |
+--------------------------------------------------+
| lwIP TCP/IP Stack (NO_SYS=0)                     |
| tcpip_thread + socket/netconn + sys_arch         |
+--------------------------------------------------+
| Driver Layer                                     |
| CH390 / lwIP netif / UART DMA+IDLE / HAL         |
+--------------------------------------------------+

四、FreeRTOS 任务设计

4.1 任务列表

任务名 优先级 栈大小 周期 职责
NetworkTask osPriorityHigh (4) 512 words 事件驱动 CH390 事件消费 + lwIP 超时处理
UartTask osPriorityHigh (4) 512 words 事件驱动 UART DMA/IDLE 接收 + MUX 帧提取
ConfigTask osPriorityNormal (3) 256 words 事件驱动 AT 命令解析与响应
RouteTask osPriorityNormal (3) 512 words 事件驱动 SRCID/DSTMASK 数据路由分发
DefaultTask osPriorityLow (1) 128 words 1000ms 周期 LED 心跳 + IWDG 喂狗

4.2 任务间通信机制

UART ISR --[Semaphore]--> UartTask --[Queue]--> RouteTask --[Queue]--> NetworkTask
                                                                   |
ConfigTask <--[Queue]-- RouteTask <--[Queue]-- NetworkTask <--------+
                    |
                    +--> UART TX (Direct DMA send)

具体通信对象:

对象 类型 生产者 消费者 用途
xUartRxQueue Queue (64 items) UartTask RouteTask UART 接收帧传递
xTcpRxQueue Queue (32 items) NetworkTask RouteTask TCP 接收数据传递
xConfigQueue Queue (16 items) RouteTask ConfigTask AT 命令文本传递
xCh390Semaphore Binary Semaphore EXTI0 ISR NetworkTask CH390 中断通知
xSpiMutex Mutex NetworkTask 多任务 SPI/CH390 访问保护
xUart2TxStream StreamBuffer (1024) RouteTask UartTask UART2 发送数据
xUart3TxStream StreamBuffer (1024) RouteTask UartTask UART3 发送数据

4.3 NetworkTask 实现方向

void NetworkTask(void *argument)
{
    /* 初始化 CH390 + lwIP netif */
    /* 创建 TCP Server/Client 实例 */
    for (;;) {
        /* 等待 CH390 中断信号量 */
        xSemaphoreTake(xCh390Semaphore, pdMS_TO_TICKS(10));
        /* 处理 CH390 事件 */
        ethernetif_poll();
        ethernetif_check_link();
        /* lwIP 超时处理由 tcpip_thread 自动完成 */
        /* TCP 数据收发 */
        tcp_link_process();
    }
}

4.4 UartTask 实现方向

void UartTask(void *argument)
{
    for (;;) {
        /* 等待 UART IDLE 中断通知 */
        ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(10));
        /* 处理 UART2/UART3 DMA 接收数据 */
        /* MUX=0: 直接投递到路由队列 */
        /* MUX=1: 提取 MUX 帧,分流控制帧与数据帧 */
        /* 检查 StreamBuffer,发送 UART TX 数据 */
    }
}

4.5 ConfigTask 实现方向

void ConfigTask(void *argument)
{
    for (;;) {
        /* 从配置队列接收 AT 命令文本 */
        xQueueReceive(xConfigQueue, &cmd, portMAX_DELAY);
        /* 解析并执行 AT 命令 */
        config_process_at_cmd(cmd);
        /* 通过 UART1 发送响应 */
    }
}

4.6 RouteTask 实现方向

void RouteTask(void *argument)
{
    for (;;) {
        /* 从 UART 队列和 TCP 队列读取数据帧 */
        /* 根据 SRCID/DSTMASK 决定路由目标 */
        /* 控制帧 (DSTMASK=0x00) -> ConfigTask */
        /* 数据帧 -> TCP 实例或 UART TX */
    }
}

五、最终协议实现模型

5.1 MUX 帧承载层

数据口启用 MUX 后,统一处理如下帧:

SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL

实现职责:

  1. 识别帧边界
  2. 解析长度字段
  3. 提取 SRCID
  4. 解析 DSTMASK
  5. 按控制帧或数据帧分流

5.2 控制帧与数据帧分离

控制规则固定如下:

  • DSTMASK = 0x00:系统控制帧
  • DSTMASK != 0x00:业务数据帧

系统控制帧处理要求:

  1. PAYLOAD 解释为 AT 文本
  2. AT 文本必须以 \r\n 结束
  3. 控制帧投递到 ConfigTask

业务数据帧处理要求:

  1. SRCID 表示单一源端点
  2. DSTMASK 表示目标端点集合
  3. RouteTask 根据 DSTMASK 做多目标分发

5.3 统一端点编码

内部与外部文档统一使用以下端点编码:

端点 编码
C1 0x01
C2 0x02
UART2 0x04
UART3 0x08
S1 0x10
S2 0x20

实现要求:

  • SRCID 为单值
  • DSTMASK 为位图
  • DSTMASK=0x00 仅保留为控制帧

六、配置层设计

6.1 MUX 记录

MUX 为全局记录,仅控制设备数据口是否进入 MUX 承载模式。

取值:

  • 0:普通透传
  • 1MUX 透传

6.2 NET 记录

NET 为全局静态网络记录:

IP,MASK,GW,MAC

说明:

  • 设备只有一张网卡,因此不为每个实例单独配置本地 IP
  • 当前实现目标中不包含 DHCP

LINK[idx] 为统一实例记录:

EN,LPORT,RIP,RPORT,UART

固定索引映射:

  • 0 = S1
  • 1 = S2
  • 2 = C1
  • 3 = C2

字段职责:

  • EN:实例启用状态
  • LPORT:本地端口
  • RIP / RPORT:对端地址与端口
  • UART:对应业务数据口

说明:

  • ServerClient 共享同一记录结构
  • ServerRIP / RPORT 可作为对端约束或预设
  • ClientRIP / RPORT 表示远端目标

七、模块职责

7.1 配置模块 config.c/.h

最终职责:

  1. 解析 AT+MUX
  2. 解析 AT+NET
  3. 解析 AT+LINK
  4. 加载与保存配置
  5. 处理 SAVE / RESET / DEFAULT

7.2 UART 透传模块 uart_trans.c/.h

最终职责:

  1. 保持 USART2 / USART3DMA + IDLE 接收发送基线
  2. MUX=0 时执行普通透传
  3. MUX=1 时执行 MUX 帧收发
  4. 将控制帧与业务数据帧分流

7.3 TCP Server / Client 模块

最终职责:

  1. 不再从外部协议角度区分不同字段模型
  2. 统一受 LINK[idx] 配置驱动
  3. 由调度层决定实例与 UART 的数据交换路径

7.4 FreeRTOS 初始化 freertos.c

CubeMX 生成的 FreeRTOS 初始化文件,职责:

  1. 定义默认任务 StartDefaultTask
  2. 用户在 MX_FREERTOS_Init 中创建自定义任务

7.5 FreeRTOS 配置 FreeRTOSConfig.h

关键配置项:

配置项 说明
configUSE_PREEMPTION 1 抢占式调度
configTICK_RATE_HZ 1000 1ms tick
configMINIMAL_STACK_SIZE 128 最小栈(words
configTOTAL_HEAP_SIZE 10240 FreeRTOS 堆大小
configMAX_PRIORITIES 7 最大优先级数
configUSE_MUTEXES 1 启用互斥锁
configUSE_COUNTING_SEMAPHORES 1 启用计数信号量
configUSE_RECURSIVE_MUTEXES 1 启用递归互斥锁
configCHECK_FOR_STACK_OVERFLOW 2 栈溢出检测方式 2
configUSE_MALLOC_FAILED_HOOK 1 内存分配失败钩子
configSUPPORT_DYNAMIC_ALLOCATION 1 动态内存分配

八、lwIP 配置方向

8.1 lwIP 线程模型

由于采用 NO_SYS=0lwIP 将运行以下线程:

  1. tcpip_thread:lwIP 核心线程,处理所有协议栈内部事件
  2. 应用任务通过 netconn / socket API 与 lwIP 交互

8.2 lwIP 内存配置建议

配置项 建议值 说明
MEM_SIZE 8192 lwIP 堆大小
MEMP_NUM_NETCONN 6 netconn 连接数
MEMP_NUM_TCP_PCB 6 TCP 控制块数
PBUF_POOL_SIZE 8 pbuf 池大小
PBUF_POOL_BUFSIZE 1524 pbuf 缓冲大小
TCP_WND 2048 TCP 窗口大小
TCP_MSS 1460 TCP 最大段大小

8.3 sys_arch 移植层

Drivers/LwIP/port/sys_arch.c 提供 lwIP 到 FreeRTOS 的适配:

  1. sys_thread_new:创建 lwIP 线程
  2. sys_mbox_*:消息邮箱(基于 FreeRTOS Queue
  3. sys_sem_*:信号量(基于 FreeRTOS Semaphore
  4. sys_mutex_*:互斥锁(基于 FreeRTOS Mutex
  5. sys_arch_protect / unprotect:临界区保护

九、中断与 HAL 时间基准

9.1 HAL 时间基准

FreeRTOS 下 SysTick 被 FreeRTOS 占用,HAL 时间基准改用 TIM4

  • TIM4 配置为 1ms 中断(72MHz / (71+1) / (999+1) = 1kHz
  • HAL_InitTick 使用 TIM4 而非 SysTick
  • uwTickTIM4_IRQHandler 中递增

9.2 中断优先级规划

中断 优先级 说明
SysTick 15(最低) FreeRTOS tick
PendSV 15(最低) FreeRTOS 上下文切换
SVCall 0 FreeRTOS 服务调用
TIM4 0 HAL 时间基准
EXTI0 5 CH390 中断
DMA1_Ch2~7 5 UART DMA
USART1/2/3 5 UART 中断
SPI1 5 SPI 中断

FreeRTOS 可管理的中断优先级必须 >= configMAX_SYSCALL_INTERRUPT_PRIORITY(本工程为 5)。

十、内存预算

STM32F103RCT6 为目标(48KB SRAM):

10.1 RAM 预算

项目 建议值 说明
启动栈 (MSP) 2 KB startup_stm32f103xe.s 中定义
FreeRTOS 堆 10 KB heap_4.c 管理
任务栈合计 ~6 KB 5 个任务
lwIP 堆 8 KB MEM_SIZE
UART 缓冲 4 KB RX/TX DMA 缓冲
Queue/StreamBuffer 4 KB 任务间通信
参数/状态 2 KB 配置结构
空闲栈 1 KB 系统预留
合计 ~37 KB 预留约 11 KB 余量

10.2 Flash 预算

项目 估计值 说明
FreeRTOS 内核 ~8 KB 含 CMSIS-RTOS V2
HAL 驱动 ~20 KB GPIO/UART/SPI/DMA/IWDG/TIM
lwIP 协议栈 ~40 KB core + api + ipv4 + netif
CH390 驱动 ~4 KB
应用代码 ~20 KB config/uart_trans/tcp/route
合计 ~92 KB 预留约 164 KB 余量

十一、硬件资源

11.1 MCU

  • 型号:STM32F103RCT6
  • Flash256 KB
  • SRAM48 KB
  • 主频:72 MHz

11.2 主要外设

  • SPI1:连接 CH390D
  • USART1:配置串口
  • USART2:数据透传串口
  • USART3:数据透传串口
  • DMA13 路 UART 收发 DMA
  • EXTI0CH390 中断输入
  • IWDG:独立看门狗
  • TIM4HAL 时间基准(替代 SysTick

11.3 引脚分配

引脚 功能 用途
PA2 USART2_TX 数据透传串口
PA3 USART2_RX 数据透传串口
PA4 SPI1_NSS 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 数据透传串口
PB11 USART3_RX 数据透传串口
PC13 GPIO_Output 状态 LED
PD0/PD1 HSE 8MHz 外部晶振

十二、实现边界

  1. 保持单网卡静态网络模型
  2. 不实现 DHCP
  3. 不实现旧 S1... / C1... 外部协议字段
  4. 不在文档中保留兼容层描述
  5. 所有 AT 文本控制统一要求 \r\n 结束
  6. FreeRTOS 堆管理使用 heap_4.c
  7. HAL 时间基准使用 TIM4 而非 SysTick

十三、文档一致性要求

后续实现、联调、测试与代码注释必须遵守以下统一口径:

  1. 对外协议只使用 MUX / NET / LINK
  2. 控制帧只使用 DSTMASK=0x00
  3. MUX 帧格式固定为 SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL
  4. AT 手册、需求说明、技术实现三份文档不得再出现历史展开式字段