2 Commits

Author SHA1 Message Date
gaoro-xiao dc277b040b fix: 更新.gitignore以排除Keil构建日志和Wireshark日志文件 2026-04-13 15:50:16 +08:00
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
12 changed files with 1562 additions and 430 deletions
+4
View File
@@ -26,6 +26,7 @@ Release/
*.uvguix.* *.uvguix.*
MDK-ARM/DebugConfig/ MDK-ARM/DebugConfig/
MDK-ARM/TCP2UART/ MDK-ARM/TCP2UART/
build_keil.log
# OS # OS
Thumbs.db Thumbs.db
@@ -34,3 +35,6 @@ Desktop.ini
# 项目文档 # 项目文档
项目计划.md 项目计划.md
# Wireshark
WiresharkLog/
+390
View File
@@ -0,0 +1,390 @@
# TCP2UART AT 固件使用手册
## 1. 文档范围
本文档定义 `TCP2UART` 项目的最终 AT 外部协议。
本文档只描述最终协议模型,不保留任何历史展开式实例字段,不包含测试记录,不讨论旧版兼容命令。
适用对象:
- 上位机开发人员
- 联调与测试人员
- 固件接口实现人员
## 2. 设备与接口
- 主控:`STM32F103RCT6`256KB Flash / 48KB SRAM
- 以太网芯片:`CH390D`
- 配置口:`USART1`
- 数据口:`USART2``USART3`
职责划分:
- `USART1`AT 配置口
- `USART2 / USART3`:业务数据口,可工作于普通透传或 MUX 透传模式
## 3. 最终协议模型
本项目最终控制协议由三部分组成:
1. `MUX`:全局数据承载模式开关
2. `NET`:全局静态网络配置记录
3. `LINK[ROLE]`:按角色名组织的链路配置记录(`S1/S2/C1/C2`
约束如下:
- 设备只有一张网卡,因此本地网络参数只配置一次
- DHCP 不属于最终协议范围
- 所有 AT 文本命令必须以 `\r\n` 结尾
-`DSTMASK=0x00` 时,MUX 数据口中的系统控制帧进入 AT 解析路径,其控制文本同样必须以 `\r\n` 结尾
## 4. MUX 帧格式
`MUX=1` 时,数据口使用如下帧格式:
```text
SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL
```
字段定义:
- `SYNC`:帧起始标记,建议固定为 `0x7E`
- `LEN_H / LEN_L``PAYLOAD` 长度,高字节在前
- `SRCID`:单字节源端点 ID
- `DSTMASK`:单字节目标端点位图
- `PAYLOAD`:负载数据
- `TAIL`:帧结束标记,建议固定为 `0x7F`
规则:
- `DSTMASK != 0x00`:业务数据帧
- `DSTMASK = 0x00`:系统控制帧
- 系统控制帧的 `PAYLOAD` 为 AT 文本,必须以 `\r\n` 结束
## 5. 统一端点编码
`UART``TCP` 逻辑实例统一进入同一套编码空间:
| 端点 | 编码 |
|------|------|
| `C1` | `0x01` |
| `C2` | `0x02` |
| `U0` | `0x04` |
| `U1` | `0x08` |
| `S1` | `0x10` |
| `S2` | `0x20` |
说明:
- `SRCID` 必须为单一端点值
- `DSTMASK` 可以是一个或多个端点编码按位或的结果
- `DSTMASK=0x00` 保留给系统控制帧
## 6. AT 命令总则
### 6.1 命令结尾
所有 AT 命令均必须以 `\r\n` 结尾。
例如:
```text
AT\r\n
AT+MUX?\r\n
AT+NET=192.168.1.100,255.255.255.0,192.168.1.1,02:00:00:00:00:01\r\n
```
### 6.2 持久化规则
参数设置成功后只写入当前运行配置,不会自动写入 Flash。
若要掉电保持,必须执行:
1. `AT+SAVE\r\n`
2. `AT+RESET\r\n`
### 6.3 响应风格
- 成功:`OK`
- 需要保存后生效时,允许追加提示文本
- 失败:`ERROR: <reason>`
## 7. 默认配置
### 7.1 MUX 默认值
```text
MUX = 0
```
### 7.2 NET 默认值
```text
NET = 192.168.1.100,255.255.255.0,192.168.1.1,02:00:00:00:00:01
```
### 7.3 LINK 默认值
```text
LINK:S1 = 1,8080,0.0.0.0,0,U0
LINK:S2 = 0,8081,0.0.0.0,0,U1
LINK:C1 = 1,9001,192.168.1.200,9000,U1
LINK:C2 = 0,9002,192.168.1.201,9001,U0
```
说明:
- `S1/S2/C1/C2` 为对外可见角色名
- 内部索引映射由固件管理,不对外暴露
UART 记号约定:
- `U0 = USART2`
- `U1 = USART3`
## 8. AT 命令定义
### 8.1 测试设备在线
命令:
```text
AT\r\n
```
返回:
```text
OK
```
### 8.2 查询摘要
命令:
```text
AT+?\r\n
AT+QUERY\r\n
```
推荐返回格式:
```text
+NET:IP=192.168.1.100,MASK=255.255.255.0,GW=192.168.1.1,MAC=02:00:00:00:00:01
+LINK:S1,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0
+LINK:S2,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1
+LINK:C1,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1
+LINK:C2,EN=0,LPORT=9002,RIP=192.168.1.201,RPORT=9001,UART=U0
+MUX:0
+MAP:UART2=0x04,UART3=0x08,C1=0x01,C2=0x02,S1=0x10,S2=0x20
+BAUD:U0=115200,U1=115200
OK
```
### 8.3 MUX 类命令
#### 设置 MUX
```text
AT+MUX=1\r\n
```
参数:
- `0`:普通透传模式
- `1`MUX 透传模式
查询:
```text
AT+MUX?\r\n
```
返回示例:
```text
+MUX:1
OK
```
### 8.4 NET 类命令
#### 设置 NET
```text
AT+NET=192.168.1.100,255.255.255.0,192.168.1.1,02:00:00:00:00:01\r\n
```
字段顺序:
```text
IP,MASK,GW,MAC
```
查询:
```text
AT+NET?\r\n
```
返回示例:
```text
+NET:IP=192.168.1.100,MASK=255.255.255.0,GW=192.168.1.1,MAC=02:00:00:00:00:01
OK
```
**MAC 设置说明:**
当MAC设置为全0时,固件将使用硬件MAC地址,此时通过AT+?查询到的MAC地址即为当前生效的硬件MAC地址。
### 8.5 LINK 类命令
#### 设置单条 LINK 记录
```text
AT+LINK=S1,1,8080,0.0.0.0,0,U0\r\n
AT+LINK=C1,1,9001,192.168.1.200,9000,U1\r\n
```
字段顺序:
```text
ROLE,EN,LPORT,RIP,RPORT,UART
```
字段说明:
- `ROLE`:链路角色名,固定为 `S1/S2/C1/C2`
- `EN``0/1`
- `LPORT`:本地端口
- `RIP`:对端 IP
- `RPORT`:对端端口
- `UART``U0/U1`
说明:
- `Server``Client` 共用同一条 `LINK` 记录模型
- `Server``RIP/RPORT` 可作为允许接入的对端约束或预设对端信息
- `Client``RIP/RPORT` 表示远端目标地址与端口
#### 查询单条 LINK
```text
AT+LINK=S1\r\n
```
返回示例:
```text
+LINK:S1,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0
OK
```
#### 查询全部 LINK
```text
AT+LINK?\r\n
```
返回示例:
```text
+LINK:S1,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0
+LINK:S2,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1
+LINK:C1,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1
+LINK:C2,EN=0,LPORT=9002,RIP=192.168.1.201,RPORT=9001,UART=U0
OK
```
## 9. 保存与复位命令
### 9.1 保存配置
```text
AT+SAVE\r\n
```
成功返回:
```text
OK: Configuration saved
```
### 9.2 软件复位
```text
AT+RESET\r\n
```
返回:
```text
OK: Resetting...
```
### 9.3 恢复默认值
```text
AT+DEFAULT\r\n
```
返回:
```text
OK: Defaults restored
```
## 10. 常见错误返回
| 场景 | 返回 |
|------|------|
| 未知命令 | `ERROR: Unknown command` |
| 非法端口 | `ERROR: Invalid port` |
| 非法波特率 | `ERROR: Invalid baudrate` |
| 非法 IP 地址 | `ERROR: Invalid IP format` |
| 非法掩码 | `ERROR: Invalid mask format` |
| 非法网关 | `ERROR: Invalid gateway format` |
| 非法远端 IP | `ERROR: Invalid remote IP format` |
| 非法 MAC | `ERROR: Invalid MAC format` |
| 非法 `SRCID` / `DSTMASK` | `ERROR: Invalid route field` |
| Flash 保存失败 | `ERROR: Save failed` |
## 11. 推荐配置流程
```text
AT+NET=192.168.1.123,255.255.255.0,192.168.1.1,02:00:00:00:00:01\r\n
AT+LINK=S1,1,10001,0.0.0.0,0,U1\r\n
AT+LINK=S2,1,10003,0.0.0.0,0,U1\r\n
AT+LINK=C1,1,20001,192.168.1.201,10002,U0\r\n
AT+MUX=1\r\n
AT+SAVE\r\n
AT+RESET\r\n
```
## 12. 故障排查建议
### 12.1 发送 `AT` 没有返回
优先检查:
1. 是否连接到 `USART1`
2. 串口参数是否为 `115200 8N1`
3. 是否严格使用 `\r\n` 作为命令结尾
4. 接线是否正确
5. 设备是否正常上电运行
### 12.2 设置成功但重启后参数丢失
检查是否漏掉以下步骤:
1. `AT+SAVE\r\n`
2. `AT+RESET\r\n`
## 13. 相关文件
- AT 命令实现:`App/config.c`
- 配置结构与默认值:`App/config.h`
- FreeRTOS 任务定义:`Core/Src/freertos.c`
- 调试指导:`工程调试指南.md`
+3 -3
View File
@@ -225,7 +225,7 @@
<option> <option>
<name>CCDefines</name> <name>CCDefines</name>
<state>USE_HAL_DRIVER</state> <state>USE_HAL_DRIVER</state>
<state>STM32F103xB</state> <state>STM32F103xE</state>
<state></state> <state></state>
</option> </option>
<option> <option>
@@ -774,7 +774,7 @@
</option> </option>
<option> <option>
<name>IlinkIcfFile</name> <name>IlinkIcfFile</name>
<state>$PROJ_DIR$/stm32f103xb_flash.icf</state> <state>$PROJ_DIR$/stm32f103xe_flash.icf</state>
</option> </option>
<option> <option>
<name>IlinkIcfFileSlave</name> <name>IlinkIcfFileSlave</name>
@@ -1052,7 +1052,7 @@
<group> <group>
<name>EWARM</name> <name>EWARM</name>
<file> <file>
<name>$PROJ_DIR$/startup_stm32f103xb.s</name> <name>$PROJ_DIR$/startup_stm32f103xe.s</name>
</file> </file>
</group> </group>
<group> <group>
+4 -4
View File
@@ -97,7 +97,7 @@ TCP2UART Keil 工程配置说明
打开 Keil -> Project -> Options for Target -> C/C++ -> Define 打开 Keil -> Project -> Options for Target -> C/C++ -> Define
保持现有定义,不需要额外添加: 保持现有定义,不需要额外添加:
USE_HAL_DRIVER,STM32F103xB USE_HAL_DRIVER,STM32F103xE
======================================== ========================================
四、编译优化设置 四、编译优化设置
@@ -113,8 +113,8 @@ USE_HAL_DRIVER,STM32F103xB
======================================== ========================================
确认 ROM 和 RAM 配置正确: 确认 ROM 和 RAM 配置正确:
- IROM1: 0x08000000, Size: 0x10000 (64KB) - IROM1: 0x08000000, Size: 0x40000 (256KB)
- IRAM1: 0x20000000, Size: 0x5000 (20KB) - IRAM1: 0x20000000, Size: 0xC000 (48KB)
======================================== ========================================
六、编译验证 六、编译验证
@@ -138,7 +138,7 @@ Debug 选项卡:
Utilities 选项卡: Utilities 选项卡:
- 选择正确的 Flash 算法 - 选择正确的 Flash 算法
- STM32F10x Med-density Flash (64KB) - STM32F10x High-density Flash (256KB)
======================================== ========================================
快速添加方法(可选) 快速添加方法(可选)
+12 -12
View File
@@ -14,16 +14,16 @@
<uAC6>0</uAC6> <uAC6>0</uAC6>
<TargetOption> <TargetOption>
<TargetCommonOption> <TargetCommonOption>
<Device>STM32F103R8</Device> <Device>STM32F103RC</Device>
<Vendor>STMicroelectronics</Vendor> <Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32F1xx_DFP.2.4.1</PackID> <PackID>Keil.STM32F1xx_DFP.2.4.1</PackID>
<PackURL>https://www.keil.com/pack/</PackURL> <PackURL>https://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20000000,0x00005000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE</Cpu> <Cpu>IRAM(0x20000000,0x0000C000) IROM(0x08000000,0x00040000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec> <FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile> <StartupFile></StartupFile>
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128 -FS08000000 -FL020000 -FP0($$Device:STM32F103R8$Flash\STM32F10x_128.FLM))</FlashDriverDll> <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_HD -FS08000000 -FL040000 -FP0($$Device:STM32F103RC$Flash\STM32F10x_HD.FLM))</FlashDriverDll>
<DeviceId>0</DeviceId> <DeviceId>0</DeviceId>
<RegisterFile>$$Device:STM32F103R8$Device\Include\stm32f10x.h</RegisterFile> <RegisterFile>$$Device:STM32F103RC$Device\Include\stm32f10x.h</RegisterFile>
<MemoryEnv></MemoryEnv> <MemoryEnv></MemoryEnv>
<Cmp></Cmp> <Cmp></Cmp>
<Asm></Asm> <Asm></Asm>
@@ -33,7 +33,7 @@
<SLE66CMisc></SLE66CMisc> <SLE66CMisc></SLE66CMisc>
<SLE66AMisc></SLE66AMisc> <SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc></SLE66LinkerMisc> <SLE66LinkerMisc></SLE66LinkerMisc>
<SFDFile>$$Device:STM32F103R8$SVD\STM32F103xx.svd</SFDFile> <SFDFile>$$Device:STM32F103RC$SVD\STM32F103xx.svd</SFDFile>
<bCustSvd>0</bCustSvd> <bCustSvd>0</bCustSvd>
<UseEnv>0</UseEnv> <UseEnv>0</UseEnv>
<BinPath></BinPath> <BinPath></BinPath>
@@ -247,12 +247,12 @@
<IRAM> <IRAM>
<Type>0</Type> <Type>0</Type>
<StartAddress>0x20000000</StartAddress> <StartAddress>0x20000000</StartAddress>
<Size>0x5000</Size> <Size>0xC000</Size>
</IRAM> </IRAM>
<IROM> <IROM>
<Type>1</Type> <Type>1</Type>
<StartAddress>0x8000000</StartAddress> <StartAddress>0x8000000</StartAddress>
<Size>0x10000</Size> <Size>0x40000</Size>
</IROM> </IROM>
<XRAM> <XRAM>
<Type>0</Type> <Type>0</Type>
@@ -277,7 +277,7 @@
<OCR_RVCT4> <OCR_RVCT4>
<Type>1</Type> <Type>1</Type>
<StartAddress>0x8000000</StartAddress> <StartAddress>0x8000000</StartAddress>
<Size>0x10000</Size> <Size>0x40000</Size>
</OCR_RVCT4> </OCR_RVCT4>
<OCR_RVCT5> <OCR_RVCT5>
<Type>1</Type> <Type>1</Type>
@@ -302,7 +302,7 @@
<OCR_RVCT9> <OCR_RVCT9>
<Type>0</Type> <Type>0</Type>
<StartAddress>0x20000000</StartAddress> <StartAddress>0x20000000</StartAddress>
<Size>0x5000</Size> <Size>0xC000</Size>
</OCR_RVCT9> </OCR_RVCT9>
<OCR_RVCT10> <OCR_RVCT10>
<Type>0</Type> <Type>0</Type>
@@ -338,7 +338,7 @@
<v6Rtti>0</v6Rtti> <v6Rtti>0</v6Rtti>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>USE_HAL_DRIVER,STM32F103xB</Define> <Define>USE_HAL_DRIVER,STM32F103xE</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM3;..\Drivers\CH390;..\Drivers\LwIP\src\include;..\Drivers\LwIP\src\include\lwip;..\Drivers\LwIP\src\include\netif;..\Drivers\LwIP\src\include\arch;..\Drivers\LwIP\port;..\App</IncludePath> <IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM3;..\Drivers\CH390;..\Drivers\LwIP\src\include;..\Drivers\LwIP\src\include\lwip;..\Drivers\LwIP\src\include\netif;..\Drivers\LwIP\src\include\arch;..\Drivers\LwIP\port;..\App</IncludePath>
</VariousControls> </VariousControls>
@@ -385,9 +385,9 @@
<GroupName>Application/MDK-ARM</GroupName> <GroupName>Application/MDK-ARM</GroupName>
<Files> <Files>
<File> <File>
<FileName>startup_stm32f103xb.s</FileName> <FileName>startup_stm32f103xe.s</FileName>
<FileType>2</FileType> <FileType>2</FileType>
<FilePath>startup_stm32f103xb.s</FilePath> <FilePath>startup_stm32f103xe.s</FilePath>
</File> </File>
</Files> </Files>
</Group> </Group>
+236
View File
@@ -0,0 +1,236 @@
=================================================== keil-build-viewer v1.6 ==================================================
[Search keil project] 1 item(s)
D:\code\STM32Project\TCP2UART\MDK-ARM\TCP2UART.uvprojx
[User input]
[Current folder] D:\code\STM32Project\TCP2UART\MDK-ARM
[Encoding] 936
[Keil project path] D:\code\STM32Project\TCP2UART\MDK-ARM\TCP2UART.uvprojx
[Keil project name] TCP2UART.uvprojx
[Is keil v4] 0
[target name] TCP2UART
[final target name] TCP2UART
[Device] STM32F103R8
[Target name]
[Output name] TCP2UART
[Output path] TCP2UART\
[Listing path] .\TCP2UART\
[Is has pack] 1
[Is enbale LTO] 0
[Is has user library] 0
[Is custom scatter file] 0
[TCP2UART.uvprojx] [TCP2UART] [STM32F103R8] [LTO disable]
[memory info]
[name] IRAM [base addr] 0x20000000 [size] 0x00005000 [type] 1 [off-chip] 0 [is pack] 1 [ID] 2
[name] IROM [base addr] 0x08000000 [size] 0x00010000 [type] 2 [off-chip] 0 [is pack] 1 [ID] 3
[map file path] D:\code\STM32Project\TCP2UART\MDK-ARM\TCP2UART\TCP2UART.map
[region info]
[load region] LR_IROM1
[execution region] ER_IROM1, 0x08000000, 0x00010000, 0x0000D178 [memory type] 2 [memory ID] 3
[execution region] RW_IRAM1, 0x20000000, 0x00005000, 0x00004FF8 [memory type] 1 [memory ID] 2
[ZI block] addr: 0x2000015C, size: 0x00004E9C (20124)
[object name max length] 24
[object path max length] 60
[object in map file]
[object name] ch390.o [path] ..\Drivers\CH390\CH390.c
[object name] ch390_interface.o [path] ..\Drivers\CH390\CH390_Interface.c
[object name] ch390_runtime.o [path] ..\Drivers\CH390\ch390_runtime.c
[object name] config.o [path] ..\App\config.c
[object name] def.o [path] ..\Drivers\LwIP\src\core\def.c
[object name] dma.o [path] ../Core/Src/dma.c
[object name] etharp.o [path] ..\Drivers\LwIP\src\core\ipv4\etharp.c
[object name] ethernet.o [path] ..\Drivers\LwIP\src\netif\ethernet.c
[object name] ethernetif.o [path] ..\Drivers\LwIP\src\netif\ethernetif.c
[object name] flash_param.o [path] ..\App\flash_param.c
[object name] gpio.o [path] ../Core/Src/gpio.c
[object name] icmp.o [path] ..\Drivers\LwIP\src\core\ipv4\icmp.c
[object name] inet_chksum.o [path] ..\Drivers\LwIP\src\core\inet_chksum.c
[object name] init.o [path] ..\Drivers\LwIP\src\core\init.c
[object name] ip.o [path] ..\Drivers\LwIP\src\core\ip.c
[object name] ip4.o [path] ..\Drivers\LwIP\src\core\ipv4\ip4.c
[object name] ip4_addr.o [path] ..\Drivers\LwIP\src\core\ipv4\ip4_addr.c
[object name] iwdg.o [path] ../Core/Src/iwdg.c
[object name] main.o [path] ../Core/Src/main.c
[object name] mem.o [path] ..\Drivers\LwIP\src\core\mem.c
[object name] memp.o [path] ..\Drivers\LwIP\src\core\memp.c
[object name] netif.o [path] ..\Drivers\LwIP\src\core\netif.c
[object name] pbuf.o [path] ..\Drivers\LwIP\src\core\pbuf.c
[object name] raw.o [path] ..\Drivers\LwIP\src\core\raw.c
[object name] segger_rtt.o [path] ..\Middlewares\Third_Party\SEGGER_RTT\SEGGER_RTT.c
[object name] segger_rtt_printf.o [path] ..\Middlewares\Third_Party\SEGGER_RTT\SEGGER_RTT_printf.c
[object name] spi.o [path] ../Core/Src/spi.c
[object name] startup_stm32f103xb.o [path] startup_stm32f103xb.s
[object name] stm32f1xx_hal.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
[object name] stm32f1xx_hal_cortex.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c
[object name] stm32f1xx_hal_dma.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
[object name] stm32f1xx_hal_flash.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c
[object name] stm32f1xx_hal_flash_ex.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c
[object name] stm32f1xx_hal_gpio.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c
[object name] stm32f1xx_hal_iwdg.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_iwdg.c
[object name] stm32f1xx_hal_msp.o [path] ../Core/Src/stm32f1xx_hal_msp.c
[object name] stm32f1xx_hal_rcc.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c
[object name] stm32f1xx_hal_spi.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
[object name] stm32f1xx_hal_tim.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
[object name] stm32f1xx_hal_tim_ex.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
[object name] stm32f1xx_hal_uart.o [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
[object name] stm32f1xx_it.o [path] ../Core/Src/stm32f1xx_it.c
[object name] system_stm32f1xx.o [path] ../Core/Src/system_stm32f1xx.c
[object name] tcp.o [path] ..\Drivers\LwIP\src\core\tcp.c
[object name] tcp_client.o [path] ..\App\tcp_client.c
[object name] tcp_in.o [path] ..\Drivers\LwIP\src\core\tcp_in.c
[object name] tcp_out.o [path] ..\Drivers\LwIP\src\core\tcp_out.c
[object name] tcp_server.o [path] ..\App\tcp_server.c
[object name] tim.o [path] ../Core/Src/tim.c
[object name] timeouts.o [path] ..\Drivers\LwIP\src\core\timeouts.c
[object name] uart_trans.o [path] ..\App\uart_trans.c
[object name] usart.o [path] ../Core/Src/usart.c
[file path in keil project]
[old name] startup_stm32f103xb.s [type] 1 [path] startup_stm32f103xb.s
[old name] main.c [type] 1 [path] ../Core/Src/main.c
[old name] gpio.c [type] 1 [path] ../Core/Src/gpio.c
[old name] dma.c [type] 1 [path] ../Core/Src/dma.c
[old name] iwdg.c [type] 1 [path] ../Core/Src/iwdg.c
[old name] tim.c [type] 1 [path] ../Core/Src/tim.c
[old name] spi.c [type] 1 [path] ../Core/Src/spi.c
[old name] usart.c [type] 1 [path] ../Core/Src/usart.c
[old name] stm32f1xx_it.c [type] 1 [path] ../Core/Src/stm32f1xx_it.c
[old name] stm32f1xx_hal_msp.c [type] 1 [path] ../Core/Src/stm32f1xx_hal_msp.c
[old name] stm32f1xx_hal_gpio_ex.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c
[old name] stm32f1xx_hal_iwdg.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_iwdg.c
[old name] stm32f1xx_hal.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
[old name] stm32f1xx_hal_rcc.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c
[old name] stm32f1xx_hal_rcc_ex.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c
[old name] stm32f1xx_hal_gpio.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c
[old name] stm32f1xx_hal_dma.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
[old name] stm32f1xx_hal_cortex.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c
[old name] stm32f1xx_hal_pwr.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c
[old name] stm32f1xx_hal_flash.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c
[old name] stm32f1xx_hal_flash_ex.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c
[old name] stm32f1xx_hal_exti.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c
[old name] stm32f1xx_hal_spi.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
[old name] stm32f1xx_hal_tim.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
[old name] stm32f1xx_hal_tim_ex.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
[old name] stm32f1xx_hal_uart.c [type] 1 [path] ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
[old name] system_stm32f1xx.c [type] 1 [path] ../Core/Src/system_stm32f1xx.c
[old name] CH390.c [type] 1 [path] ..\Drivers\CH390\CH390.c
[old name] CH390_Interface.c [type] 1 [path] ..\Drivers\CH390\CH390_Interface.c
[old name] ch390_runtime.c [type] 1 [path] ..\Drivers\CH390\ch390_runtime.c
[old name] def.c [type] 1 [path] ..\Drivers\LwIP\src\core\def.c
[old name] inet_chksum.c [type] 1 [path] ..\Drivers\LwIP\src\core\inet_chksum.c
[old name] init.c [type] 1 [path] ..\Drivers\LwIP\src\core\init.c
[old name] ip.c [type] 1 [path] ..\Drivers\LwIP\src\core\ip.c
[old name] mem.c [type] 1 [path] ..\Drivers\LwIP\src\core\mem.c
[old name] memp.c [type] 1 [path] ..\Drivers\LwIP\src\core\memp.c
[old name] netif.c [type] 1 [path] ..\Drivers\LwIP\src\core\netif.c
[old name] pbuf.c [type] 1 [path] ..\Drivers\LwIP\src\core\pbuf.c
[old name] raw.c [type] 1 [path] ..\Drivers\LwIP\src\core\raw.c
[old name] stats.c [type] 1 [path] ..\Drivers\LwIP\src\core\stats.c
[old name] sys.c [type] 1 [path] ..\Drivers\LwIP\src\core\sys.c
[old name] tcp.c [type] 1 [path] ..\Drivers\LwIP\src\core\tcp.c
[old name] tcp_in.c [type] 1 [path] ..\Drivers\LwIP\src\core\tcp_in.c
[old name] tcp_out.c [type] 1 [path] ..\Drivers\LwIP\src\core\tcp_out.c
[old name] timeouts.c [type] 1 [path] ..\Drivers\LwIP\src\core\timeouts.c
[old name] udp.c [type] 1 [path] ..\Drivers\LwIP\src\core\udp.c
[old name] etharp.c [type] 1 [path] ..\Drivers\LwIP\src\core\ipv4\etharp.c
[old name] icmp.c [type] 1 [path] ..\Drivers\LwIP\src\core\ipv4\icmp.c
[old name] ip4.c [type] 1 [path] ..\Drivers\LwIP\src\core\ipv4\ip4.c
[old name] ip4_addr.c [type] 1 [path] ..\Drivers\LwIP\src\core\ipv4\ip4_addr.c
[old name] ip4_frag.c [type] 1 [path] ..\Drivers\LwIP\src\core\ipv4\ip4_frag.c
[old name] ethernet.c [type] 1 [path] ..\Drivers\LwIP\src\netif\ethernet.c
[old name] ethernetif.c [type] 1 [path] ..\Drivers\LwIP\src\netif\ethernetif.c
[old name] config.c [type] 1 [path] ..\App\config.c
[old name] flash_param.c [type] 1 [path] ..\App\flash_param.c
[old name] tcp_client.c [type] 1 [path] ..\App\tcp_client.c
[old name] tcp_server.c [type] 1 [path] ..\App\tcp_server.c
[old name] uart_trans.c [type] 1 [path] ..\App\uart_trans.c
[old name] SEGGER_RTT.c [type] 1 [path] ..\Middlewares\Third_Party\SEGGER_RTT\SEGGER_RTT.c
[old name] SEGGER_RTT_printf.c [type] 1 [path] ..\Middlewares\Third_Party\SEGGER_RTT\SEGGER_RTT_printf.c
[record region info]
[load region] LR_IROM1
[execution region] ER_IROM1, 0x08000000, 0x00010000, 0x0000D178 [type] 2 [ID] 3
[execution region] RW_IRAM1, 0x20000000, 0x00005000, 0x00004FF8 [type] 1 [ID] 2
---------------------------------------------------------------------------------
FILE(s) | RAM (byte) | FLASH (byte) |
---------------------------------------------------------------------------------
ch390.o | 0 | 590 |
ch390_interface.o | 0 | 680 |
ch390_runtime.o | 91 | 1534 |
config.o | 1248 | 4289 |
def.o | 0 | 8 |
dma.o | 0 | 124 |
etharp.o | 241 | 1773 |
ethernet.o | 0 | 250 |
ethernetif.o | 48 | 178 |
flash_param.o | 0 | 246 |
gpio.o | 0 | 240 |
icmp.o | 0 | 452 |
inet_chksum.o | 0 | 334 |
init.o | 0 | 26 |
ip.o | 24 | 0 |
ip4.o | 2 | 780 |
ip4_addr.o | 0 | 50 |
iwdg.o | 12 | 0 |
main.o | 278 | 2937 |
mem.o | 4127 | 840 |
memp.o | 6496 | 472 |
netif.o | 12 | 594 |
pbuf.o | 0 | 1118 |
raw.o | 4 | 252 |
segger_rtt.o | 440 | 391 |
segger_rtt_printf.o | 0 | 64 |
spi.o | 88 | 216 |
startup_stm32f103xb.o | 1024 | 296 |
stm32f1xx_hal.o | 12 | 140 |
stm32f1xx_hal_cortex.o | 0 | 198 |
stm32f1xx_hal_dma.o | 0 | 808 |
stm32f1xx_hal_flash.o | 32 | 392 |
stm32f1xx_hal_flash_ex.o | 0 | 240 |
stm32f1xx_hal_gpio.o | 0 | 516 |
stm32f1xx_hal_iwdg.o | 0 | 12 |
stm32f1xx_hal_msp.o | 0 | 60 |
stm32f1xx_hal_rcc.o | 0 | 1258 |
stm32f1xx_hal_spi.o | 0 | 1510 |
stm32f1xx_hal_tim.o | 0 | 936 |
stm32f1xx_hal_tim_ex.o | 0 | 108 |
stm32f1xx_hal_uart.o | 0 | 2300 |
stm32f1xx_it.o | 0 | 490 |
system_stm32f1xx.o | 4 | 30 |
tcp.o | 32 | 3699 |
tcp_client.o | 1120 | 1216 |
tcp_in.o | 56 | 3720 |
tcp_out.o | 0 | 3862 |
tcp_server.o | 1104 | 962 |
tim.o | 72 | 164 |
timeouts.o | 12 | 402 |
uart_trans.o | 2936 | 1268 |
usart.o | 624 | 816 |
---------------------------------------------------------------------------------
[memory print mode]: 0
LR_IROM1
RAM 1 [0x20000000 | 0x00005000 (20480)]
[zi start] 1 [zi end] 49
RW_IRAM1 [0x20000000]|¡ö¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ¡õ_| ( 19.9 KB / 20.0 KB ) 100.0%
FLASH 1 [0x08000000 | 0x00010000 (65536)]
ER_IROM1 [0x08000000]|¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö__________| ( 52.3 KB / 64.0 KB ) 81.8%
[htm file path] D:\code\STM32Project\TCP2UART\MDK-ARM\TCP2UART\TCP2UART.htm
Maximum Stack Usage = 968 bytes + Unknown(Functions without stacksize, Cycles, Untraceable Function Pointers)
=============================================================================================================================
run time: 0.179 s
+1 -1
View File
@@ -29,7 +29,7 @@
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> ; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h> ; </h>
Stack_Size EQU 0x400 Stack_Size EQU 0x800
AREA STACK, NOINIT, READWRITE, ALIGN=3 AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size Stack_Mem SPACE Stack_Size
+1 -1
View File
@@ -29,7 +29,7 @@
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> ; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h> ; </h>
Stack_Size EQU 0x400 Stack_Size EQU 0x800
AREA STACK, NOINIT, READWRITE, ALIGN=3 AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size Stack_Mem SPACE Stack_Size
+61 -30
View File
@@ -63,34 +63,44 @@ Dma.USART3_TX.5.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_TX.5.PeriphInc=DMA_PINC_DISABLE Dma.USART3_TX.5.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_TX.5.Priority=DMA_PRIORITY_LOW Dma.USART3_TX.5.Priority=DMA_PRIORITY_LOW
Dma.USART3_TX.5.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority Dma.USART3_TX.5.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
FREERTOS.FootprintOK=true
FREERTOS.IPParameters=Tasks01,configUSE_PREEMPTION,configTICK_RATE_HZ,configMINIMAL_STACK_SIZE,configTOTAL_HEAP_SIZE,configMAX_PRIORITIES,configUSE_IDLE_HOOK,configUSE_TICK_HOOK,configUSE_MUTEXES,configUSE_COUNTING_SEMAPHORES,configUSE_RECURSIVE_MUTEXES,configCHECK_FOR_STACK_OVERFLOW,configUSE_MALLOC_FAILED_HOOK,configSUPPORT_STATIC_ALLOCATION,configSUPPORT_DYNAMIC_ALLOCATION
FREERTOS.Tasks01=defaultTask\,0\,128\,StartDefaultTask\,Default\,NULL
FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2
FREERTOS.configMAX_PRIORITIES=7
FREERTOS.configMINIMAL_STACK_SIZE=128
FREERTOS.configSUPPORT_DYNAMIC_ALLOCATION=1
FREERTOS.configSUPPORT_STATIC_ALLOCATION=0
FREERTOS.configTICK_RATE_HZ=1000
FREERTOS.configTOTAL_HEAP_SIZE=10240
FREERTOS.configUSE_COUNTING_SEMAPHORES=1
FREERTOS.configUSE_IDLE_HOOK=0
FREERTOS.configUSE_MALLOC_FAILED_HOOK=1
FREERTOS.configUSE_MUTEXES=1
FREERTOS.configUSE_PREEMPTION=1
FREERTOS.configUSE_RECURSIVE_MUTEXES=1
FREERTOS.configUSE_TICK_HOOK=0
File.Version=6 File.Version=6
GPIO.groupedBy=Group By Peripherals GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false KeepUserPlacement=false
Mcu.CPN=STM32F103R8T6 Mcu.CPN=STM32F103RCT6
Mcu.Family=STM32F1 Mcu.Family=STM32F1
Mcu.IP0=DMA Mcu.IP0=DMA
Mcu.IP1=IWDG Mcu.IP1=FREERTOS
Mcu.IP2=NVIC Mcu.IP2=IWDG
Mcu.IP3=RCC Mcu.IP3=NVIC
Mcu.IP4=SPI1 Mcu.IP4=RCC
Mcu.IP5=SYS Mcu.IP5=SPI1
Mcu.IP6=USART1 Mcu.IP6=SYS
Mcu.IP7=USART2 Mcu.IP7=TIM4
Mcu.IP8=USART3 Mcu.IP8=USART1
Mcu.IPNb=9 Mcu.IP9=USART2
Mcu.Name=STM32F103R(8-B)Tx Mcu.IP10=USART3
Mcu.IPNb=11
Mcu.Name=STM32F103R(C-D-E)Tx
Mcu.Package=LQFP64 Mcu.Package=LQFP64
Mcu.Pin0=PC13-TAMPER-RTC Mcu.Pin0=PC13-TAMPER-RTC
Mcu.Pin1=PD0-OSC_IN Mcu.Pin1=PD0-OSC_IN
Mcu.Pin10=PB1
Mcu.Pin11=PB10
Mcu.Pin12=PB11
Mcu.Pin13=PA9
Mcu.Pin14=PA10
Mcu.Pin15=PA13
Mcu.Pin16=PA14
Mcu.Pin17=VP_IWDG_VS_IWDG
Mcu.Pin18=VP_SYS_VS_Systick
Mcu.Pin2=PD1-OSC_OUT Mcu.Pin2=PD1-OSC_OUT
Mcu.Pin3=PA2 Mcu.Pin3=PA2
Mcu.Pin4=PA3 Mcu.Pin4=PA3
@@ -99,10 +109,21 @@ Mcu.Pin6=PA5
Mcu.Pin7=PA6 Mcu.Pin7=PA6
Mcu.Pin8=PA7 Mcu.Pin8=PA7
Mcu.Pin9=PB0 Mcu.Pin9=PB0
Mcu.PinsNb=19 Mcu.Pin10=PB1
Mcu.Pin11=PB10
Mcu.Pin12=PB11
Mcu.Pin13=PA9
Mcu.Pin14=PA10
Mcu.Pin15=PA13
Mcu.Pin16=PA14
Mcu.Pin17=VP_FREERTOS_VS_ENABLE
Mcu.Pin18=VP_IWDG_VS_IWDG
Mcu.Pin19=VP_SYS_VS_TIM4
Mcu.Pin20=VP_TIM4_VS_ClockSourceINT
Mcu.PinsNb=21
Mcu.ThirdPartyNb=0 Mcu.ThirdPartyNb=0
Mcu.UserConstants= Mcu.UserConstants=
Mcu.UserName=STM32F103R8Tx Mcu.UserName=STM32F103RCTx
MxCube.Version=6.16.1 MxCube.Version=6.16.1
MxDb.Version=DB.6.0.161 MxDb.Version=DB.6.0.161
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
@@ -118,9 +139,12 @@ NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SPI1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.SPI1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:false
NVIC.TIM4_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.USART1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true
NVIC.USART2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true NVIC.USART2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true
NVIC.USART3_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.USART3_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true
@@ -157,8 +181,8 @@ PC13-TAMPER-RTC.Locked=true
PC13-TAMPER-RTC.Signal=GPIO_Output PC13-TAMPER-RTC.Signal=GPIO_Output
PCC.Checker=false PCC.Checker=false
PCC.Line=STM32F103 PCC.Line=STM32F103
PCC.MCU=STM32F103R(8-B)Tx PCC.MCU=STM32F103R(C-D-E)Tx
PCC.PartNumber=STM32F103R8Tx PCC.PartNumber=STM32F103RCTx
PCC.Series=STM32F1 PCC.Series=STM32F1
PCC.Temperature=25 PCC.Temperature=25
PCC.Vdd=3.3 PCC.Vdd=3.3
@@ -176,12 +200,12 @@ ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage= ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32F103R8Tx ProjectManager.DeviceId=STM32F103RCTx
ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.8.7 ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.8.7
ProjectManager.FreePins=false ProjectManager.FreePins=false
ProjectManager.FreePinsContext= ProjectManager.FreePinsContext=
ProjectManager.HalAssertFull=false ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x0 ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=0 ProjectManager.LibraryCopy=0
@@ -193,13 +217,13 @@ ProjectManager.ProjectFileName=TCP2UART.ioc
ProjectManager.ProjectName=TCP2UART ProjectManager.ProjectName=TCP2UART
ProjectManager.ProjectStructure= ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack= ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400 ProjectManager.StackSize=0x800
ProjectManager.TargetToolchain=MDK-ARM V5.32 ProjectManager.TargetToolchain=MDK-ARM V5.32
ProjectManager.ToolChainLocation= ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath= ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_IWDG_Init-IWDG-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_USART2_UART_Init-USART2-false-HAL-true,7-MX_USART3_UART_Init-USART3-false-HAL-true,8-MX_SPI1_Init-SPI1-false-HAL-true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_IWDG_Init-IWDG-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_USART2_UART_Init-USART2-false-HAL-true,7-MX_USART3_UART_Init-USART3-false-HAL-true,8-MX_SPI1_Init-SPI1-false-HAL-true,9-MX_FREERTOS_Init-FREERTOS-false-HAL-true,10-MX_TIM4_Init-TIM4-false-HAL-true
RCC.ADCFreqValue=36000000 RCC.ADCFreqValue=36000000
RCC.AHBFreq_Value=72000000 RCC.AHBFreq_Value=72000000
RCC.APB1CLKDivider=RCC_HCLK_DIV2 RCC.APB1CLKDivider=RCC_HCLK_DIV2
@@ -236,14 +260,21 @@ SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler
SPI1.Mode=SPI_MODE_MASTER SPI1.Mode=SPI_MODE_MASTER
SPI1.VirtualNSS=VM_NSSSOFT SPI1.VirtualNSS=VM_NSSSOFT
SPI1.VirtualType=VM_MASTER SPI1.VirtualType=VM_MASTER
TIM4.IPParameters=Prescaler,Period
TIM4.Period=999
TIM4.Prescaler=71
USART1.IPParameters=VirtualMode USART1.IPParameters=VirtualMode
USART1.VirtualMode=VM_ASYNC USART1.VirtualMode=VM_ASYNC
USART2.IPParameters=VirtualMode USART2.IPParameters=VirtualMode
USART2.VirtualMode=VM_ASYNC USART2.VirtualMode=VM_ASYNC
USART3.IPParameters=VirtualMode USART3.IPParameters=VirtualMode
USART3.VirtualMode=VM_ASYNC USART3.VirtualMode=VM_ASYNC
VP_FREERTOS_VS_ENABLE.Mode=Enabled
VP_FREERTOS_VS_ENABLE.Signal=FREERTOS_VS_ENABLE
VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Mode=IWDG_Activate
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_TIM4.Mode=TIM4
VP_SYS_VS_Systick.Signal=SYS_VS_Systick VP_SYS_VS_TIM4.Signal=SYS_VS_TIM4
VP_TIM4_VS_ClockSourceINT.Mode=Internal
VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
board=custom board=custom
+267
View File
@@ -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`
+419 -341
View File
@@ -1,42 +1,425 @@
# TCP2UART 项目技术实现(裸机迁移基线) # TCP2UART 项目技术实现
## 一、目标 ## 一、文档目的
当前分支 `baremetal-r8` 的目标不是一次性完成全部业务逻辑重写,而是先把工程基线切换到适合 `STM32F103R8T6` 的裸机方向,为后续继续开发提供统一入口 本文档描述 `TCP2UART` 项目基于 `STM32F103RCT6 + FreeRTOS` 的最终内部实现口径
阶段已经完成或约束如下 文档只围绕最终协议模型展开
1. MCU 目标统一为 `STM32F103R8T6 / STM32F103xB` - `MUX`:串口承载层
2. `CubeMX IOC` 中已移除 `FreeRTOS` 中间件声明 - `NET`:全局网络配置层
3. 工程规划转为裸机轮询 + 中断驱动模型 - `LINK[idx]`:实例配置与连接管理层
4. 暂不在本阶段重写 TCP/串口业务逻辑
5. 保留现有源码作为迁移参考,后续由其他 Agent/开发者继续接力实现
## 二、硬件与资源约束 不再保留历史 `S1... / C1...` 外部字段模型。
### 2.1 MCU ## 二、当前工程基础
- 型号:`STM32F103R8T6` 当前工程基础约束如下:
- Flash`64 KB`
- SRAM`20 KB` 1. MCU`STM32F103RCT6`256KB Flash / 48KB SRAM
2. 网络芯片:`CH390D`
3. 软件架构:`FreeRTOS + lwIP NO_SYS=0`
4. 协议栈:`lwIP socket/netconn API`
5. 调试输出:`SEGGER RTT`
6. 使用 `FreeRTOS` 任务调度
7. 不实现 DHCP
## 三、总体架构
```text
+--------------------------------------------------+
| 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 任务间通信机制
```text
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 实现方向
```c
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 实现方向
```c
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 实现方向
```c
void ConfigTask(void *argument)
{
for (;;) {
/* 从配置队列接收 AT 命令文本 */
xQueueReceive(xConfigQueue, &cmd, portMAX_DELAY);
/* 解析并执行 AT 命令 */
config_process_at_cmd(cmd);
/* 通过 UART1 发送响应 */
}
}
```
### 4.6 RouteTask 实现方向
```c
void RouteTask(void *argument)
{
for (;;) {
/* 从 UART 队列和 TCP 队列读取数据帧 */
/* 根据 SRCID/DSTMASK 决定路由目标 */
/* 控制帧 (DSTMASK=0x00) -> ConfigTask */
/* 数据帧 -> TCP 实例或 UART TX */
}
}
```
## 五、最终协议实现模型
### 5.1 MUX 帧承载层
数据口启用 MUX 后,统一处理如下帧:
```text
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`:普通透传
- `1`MUX 透传
### 6.2 NET 记录
`NET` 为全局静态网络记录:
```text
IP,MASK,GW,MAC
```
说明:
- 设备只有一张网卡,因此不为每个实例单独配置本地 IP
- 当前实现目标中不包含 DHCP
### 6.3 LINK 记录
`LINK[idx]` 为统一实例记录:
```text
EN,LPORT,RIP,RPORT,UART
```
固定索引映射:
- `0 = S1`
- `1 = S2`
- `2 = C1`
- `3 = C2`
字段职责:
- `EN`:实例启用状态
- `LPORT`:本地端口
- `RIP / RPORT`:对端地址与端口
- `UART`:对应业务数据口
说明:
- `Server``Client` 共享同一记录结构
- `Server``RIP / RPORT` 可作为对端约束或预设
- `Client``RIP / 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 / USART3``DMA + 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=0`lwIP 将运行以下线程:
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`
- `uwTick``TIM4_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`
- Flash`256 KB`
- SRAM`48 KB`
- 主频:`72 MHz` - 主频:`72 MHz`
### 2.2 主要外设 ### 11.2 主要外设
- `SPI1`:连接 `CH390D` - `SPI1`:连接 `CH390D`
- `USART1`:配置串口 - `USART1`:配置串口
- `USART2`Server 透传串口 - `USART2`数据透传串口
- `USART3`Client 透传串口 - `USART3`数据透传串口
- `DMA1`3 路 UART 收发 DMA - `DMA1`3 路 UART 收发 DMA
- `EXTI0`CH390 中断输入 - `EXTI0`CH390 中断输入
- `IWDG`:独立看门狗 - `IWDG`:独立看门狗
- `TIM4`HAL 时间基准(替代 SysTick
### 2.3 当前引脚分配 ### 11.3 引脚分配
| 引脚 | 功能 | 用途 | | 引脚 | 功能 | 用途 |
|------|------|------| |------|------|------|
| PA2 | USART2_TX | Server 透传串口 | | PA2 | USART2_TX | 数据透传串口 |
| PA3 | USART2_RX | Server 透传串口 | | PA3 | USART2_RX | 数据透传串口 |
| PA4 | SPI1_NSS | CH390D 片选 | | PA4 | SPI1_NSS | CH390D 片选 |
| PA5 | SPI1_SCK | CH390D SPI 时钟 | | PA5 | SPI1_SCK | CH390D SPI 时钟 |
| PA6 | SPI1_MISO | CH390D SPI 数据输入 | | PA6 | SPI1_MISO | CH390D SPI 数据输入 |
@@ -45,331 +428,26 @@
| PA10 | USART1_RX | 配置串口 | | PA10 | USART1_RX | 配置串口 |
| PB0 | EXTI0 | CH390D INT | | PB0 | EXTI0 | CH390D INT |
| PB1 | GPIO_Output | CH390D RESET | | PB1 | GPIO_Output | CH390D RESET |
| PB10 | USART3_TX | Client 透传串口 | | PB10 | USART3_TX | 数据透传串口 |
| PB11 | USART3_RX | Client 透传串口 | | PB11 | USART3_RX | 数据透传串口 |
| PC13 | GPIO_Output | 状态 LED | | PC13 | GPIO_Output | 状态 LED |
| PD0/PD1 | HSE | 8MHz 外部晶振 | | PD0/PD1 | HSE | 8MHz 外部晶振 |
## 三、为何从 FreeRTOS 迁移到裸机 ## 十二、实现边界
`STM32F103R8T6` 的 RAM 只有 `20KB`。当前工程在引入如下组件后,链接空间明显不足: 1. 保持单网卡静态网络模型
2. 不实现 DHCP
3. 不实现旧 `S1... / C1...` 外部协议字段
4. 不在文档中保留兼容层描述
5. 所有 AT 文本控制统一要求 `\r\n` 结束
6. FreeRTOS 堆管理使用 `heap_4.c`
7. HAL 时间基准使用 `TIM4` 而非 `SysTick`
1. `FreeRTOS` 内核 ## 十三、文档一致性要求
2. `CMSIS-RTOS V2` 包装层
3. 多任务栈
4. `lwIP + socket/netconn` OS 抽象层
5. 多路 `StreamBuffer / Semaphore / Mutex`
此前编译已经证明 后续实现、联调、测试与代码注释必须遵守以下统一口径
1. 源码层报错可修复 1. 对外协议只使用 `MUX / NET / LINK`
2. 统一 `R8` 型号后仍然在链接阶段失败 2. 控制帧只使用 `DSTMASK=0x00`
3. 主要瓶颈是 `RAM + Flash` 同时偏紧 3. MUX 帧格式固定为 `SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL`
4. AT 手册、需求说明、技术实现三份文档不得再出现历史展开式字段
因此本项目后续建议的主方向为:
1. 去掉 `FreeRTOS`
2. 去掉 `CMSIS-RTOS V2`
3. 避免依赖 `lwIP socket/netconn`
4. 采用裸机主循环 + DMA/IDLE/EXTI 中断驱动
5. 网络侧改为更贴近资源受限场景的实现模型
## 四、裸机架构目标
### 4.1 总体分层
```text
+--------------------------------------------------+
| Application State Machine |
| config / server link / client link / watchdog |
+--------------------------------------------------+
| Transport Scheduler |
| main loop polling + event flags + timeout scan |
+--------------------------------------------------+
| Network Interface |
| CH390 event polling / packet rx-tx dispatch |
+--------------------------------------------------+
| Peripheral Drivers |
| UART DMA+IDLE / SPI / GPIO / EXTI / Flash |
+--------------------------------------------------+
| STM32 HAL / CMSIS |
+--------------------------------------------------+
```
### 4.2 执行模型
不再使用任务调度器,改为以下模型:
1. `ISR` 只做最小事件置位与 DMA 状态更新
2. 主循环统一处理事件、超时、状态机推进
3. UART RX 继续依赖 `DMA + IDLE`
4. UART TX 可保留 `DMA`
5. CH390 中断只置位 `netif_pending`
6. 网络协议处理在主循环中推进
### 4.3 事件源
建议保留以下裸机事件位:
```c
typedef enum {
EVENT_NONE = 0x00000000u,
EVENT_CH390_INT = 0x00000001u,
EVENT_UART1_RX_IDLE = 0x00000002u,
EVENT_UART2_RX_IDLE = 0x00000004u,
EVENT_UART3_RX_IDLE = 0x00000008u,
EVENT_UART2_TX_DONE = 0x00000010u,
EVENT_UART3_TX_DONE = 0x00000020u,
EVENT_NET_TIMER_1MS = 0x00000040u,
EVENT_LINK_RETRY = 0x00000080u,
EVENT_CONFIG_PENDING = 0x00000100u,
} app_event_t;
```
这些事件位建议通过 `volatile uint32_t g_app_events` 或一个轻量原子位图维护。
## 五、建议的软件模块拆分
### 5.1 保留模块
以下模块可继续保留,但需要去除 RTOS 依赖:
1. `App/config.c`
2. `App/flash_param.c`
3. `App/tcp_server.*`
4. `App/tcp_client.*`
5. `App/uart_trans.*`
6. `Drivers/CH390/*`
7. `Drivers/LwIP/*` 或后续替代网络栈
### 5.2 需要改造的核心模块
1. `Core/Src/main.c`
2. `Core/Src/stm32f1xx_it.c`
3. `Core/Src/usart.c`
4. `Core/Src/dma.c`
5. `Core/Src/freertos.c`:后续应移除出构建或清空为兼容壳
6. `Core/Inc/FreeRTOSConfig.h`:后续可移除出工程
7. `Drivers/LwIP/port/sys_arch.c`:若完全去 OS,应停止使用该移植层
8. `Drivers/LwIP/src/include/arch/sys_arch.h`
### 5.3 建议新增的裸机模块
建议后续新增:
1. `App/app_scheduler.c/.h`
- 统一处理事件位
- 驱动周期任务
- 执行状态机推进
2. `App/app_net.c/.h`
- 网络初始化
- CH390 事件分发
- 链路保活/重连
3. `App/app_uart.c/.h`
- UART DMA/IDLE 收发整合
- 与网络方向的缓冲协调
4. `App/app_time.c/.h`
- 基于 `SysTick` 的毫秒计时
- 软件超时管理
## 六、裸机下的关键技术决策
### 6.1 延时与时间基准
建议统一使用:
1. `SysTick 1ms` 全局时基
2. 禁止在主业务路径使用长阻塞 `HAL_Delay`
3. 超时逻辑统一基于 `tick_now - tick_start`
示例:
```c
uint32_t app_now_ms(void);
bool app_is_timeout(uint32_t start, uint32_t timeout_ms);
```
### 6.2 UART 接收模型
保持 `DMA + IDLE` 是合理的,原因:
1. 可降低 CPU 占用
2. 适合串口透传场景
3. 便于在裸机下维持较高吞吐
建议 UART RX 流程:
1. DMA 持续接收至环形或双缓冲
2. IDLE 中断触发“本帧结束”
3. ISR 只记录长度与事件位
4. 主循环消费数据并决定转发方向
### 6.3 UART 发送模型
建议继续使用 `DMA TX`
1. 发送启动在主循环中执行
2. DMA 完成中断只清 busy 标志并置 `TX_DONE` 事件
3. 发送缓冲统一由应用层管理
### 6.4 CH390 访问模型
裸机下不再需要 `mutex`,但仍需保证上下文一致性:
1. ISR 内不要执行复杂 SPI 事务
2. EXTI 仅置位 `EVENT_CH390_INT`
3. 所有 CH390 SPI 读写都在主循环中完成
4. 若必须与 DMA 回调共享状态,使用短临界区保护
### 6.5 网络栈路线
这里需要后续 Agent 决定最终实现路线,建议二选一:
1. `lwIP RAW API + NO_SYS=1`
- 优点:仍保留成熟 TCP/IP 栈
- 缺点:迁移复杂度较高,需要重写当前 `socket/netconn` 依赖
2. 基于现有 CH390 资料,评估是否存在更轻的直接 socket/简化协议接口
- 优点:可能进一步减小资源占用
- 缺点:功能边界和维护成本需重新评估
当前更推荐的长期路线是:
`lwIP RAW API + NO_SYS=1`
因为这条路线与现有 CH390 + 以太网驱动结构更连续。
## 七、主循环设计建议
建议采用固定骨架:
```c
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_IWDG_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_USART3_UART_Init();
MX_SPI1_Init();
app_time_init();
app_uart_init();
app_net_init();
app_config_init();
while (1)
{
app_poll_events();
app_process_config();
app_process_uart_links();
app_process_network();
app_process_timeouts();
app_feed_watchdog();
}
}
```
设计原则:
1. 所有步骤可重入或幂等
2. 每轮主循环不可长时间阻塞
3. 网络与串口处理都要支持“分段推进”
## 八、建议的状态机拆分
### 8.1 TCP Server 链路
```text
IDLE -> LISTEN -> CONNECTED -> CLOSING -> LISTEN
```
### 8.2 TCP Client 链路
```text
IDLE -> RESOLVE/CONFIG -> CONNECTING -> CONNECTED -> RETRY_WAIT -> CONNECTING
```
### 8.3 配置口
```text
IDLE -> RX_FRAME_READY -> PARSE -> EXECUTE -> RESPOND -> IDLE
```
### 8.4 CH390 网口
```text
RESET -> INIT -> LINK_CHECK -> RUNNING -> ERROR_RECOVER -> INIT
```
## 九、内存预算建议
`STM32F103R8T6` 为目标,后续实现应尽量遵循:
### 9.1 推荐 RAM 预算
| 项目 | 建议值 | 说明 |
|------|--------|------|
| 启动栈 | 1 KB | `startup` 保留 |
| C Heap | 0 | 默认关闭 |
| UART1 RX/TX | 384 B | 配置口 |
| UART2 RX/TX | 1 KB | 透传链路 |
| UART3 RX/TX | 1 KB | 透传链路 |
| 网络收发缓存 | 2-4 KB | 视协议栈路线而定 |
| 参数/状态结构 | < 2 KB | 控制状态 |
### 9.2 原则
1. 避免动态分配
2. 优先静态缓冲 + 明确大小
3. 单向链路缓冲优先复用
4. 所有大缓冲区要在文档中登记
## 十、当前已完成的工程侧修改
本分支当前已经完成:
1. `R8/xB` 型号统一
2. MDK 启动文件切换到 `startup_stm32f103xb.s`
3. `IOC` 中移除 `FREERTOS` 中间件声明
4. `PendSV/SVCall` 不再作为 RTOS 中断入口保留
5. `Heap/Stack` 的工程默认值收缩到更适合 `R8`
## 十一、后续 Agent 接手时应优先处理的事项
### 11.1 工程配置层
1.`MDK-ARM/TCP2UART.uvprojx` 中移除 `FreeRTOS` 源文件组
2. 从包含路径中移除 `CMSIS_RTOS_V2``FreeRTOS` 路径
3. 视需要移除 `Core/Src/freertos.c`
4. 视需要移除 `Core/Inc/FreeRTOSConfig.h`
### 11.2 代码层
1. 将所有 `osThreadNew``vTaskDelay``xStreamBuffer*``xSemaphore*``xMutex*` 调用替换为裸机实现
2.`lwIP``NO_SYS=0` 路线迁移到裸机可用路线
3. 重写 `CH390` 事件处理为主循环驱动
4. 重写 UART 透传调度逻辑为状态机
### 11.3 风险点
1. 当前 `socket/netconn` 方案不能直接脱离 OS 使用
2. `sys_arch` 相关移植层最终应被清退
3. 原来依赖任务切换“自然解耦”的路径,迁移到裸机后必须明确状态和时序边界
## 十二、交接说明
当前分支适合作为“裸机迁移起点”,但不是最终可编译成品。它的价值在于:
1. 目标器件与工程元数据已经统一
2. `CubeMX` 方向已经从 `FreeRTOS` 转向裸机
3. 技术实现文档已明确后续重构路线
接下来的工作重点应由后续 Agent 在此基线上继续完成逻辑代码迁移。
+164 -38
View File
@@ -1,59 +1,185 @@
# TCP2UART 项目需求说明 # TCP2UART 项目需求说明
## 一、项目概述 ## 一、项目目标
基于 STM32F103 单片机和 FreeRTOS 开发一款具有双网口通信功能的 TCP 串口透传设备,实现网络数据与串口数据之间的双向透明传输 本项目基于 `STM32F103RCT6``CH390D` 实现一台多实例 TCP 与双串口数据透传设备
## 二、硬件平台 最终对外协议模型固定为:
| 项目 | 说明 | 1. `MUX`:控制串口侧是否采用 MUX 承载
2. `NET`:全局静态网络配置
3. `LINK[idx]`:按实例索引组织的链路配置
系统必须支持:
- `2` 路 TCP Server 实例
- `2` 路 TCP Client 实例
- `UART1` 作为 AT 配置口
- `UART2 / UART3` 作为业务数据口
## 二、硬件与软件边界
### 2.1 硬件边界
- 主控:`STM32F103RCT6`256KB Flash / 48KB SRAM
- 以太网芯片:`CH390D`
- 网卡数量:`1`
- 配置口:`UART1`
- 数据口:`UART2``UART3`
### 2.2 软件边界
- 执行模型:`FreeRTOS`
- 网络协议栈:`lwIP + NO_SYS=0`(支持 socket/netconn 线程安全 API
- 调试输出:`SEGGER RTT`
- 采用 `FreeRTOS` 任务调度
- 采用 `lwIP socket/netconn``RAW API` 实现多路 TCP 并发
- 不包含 DHCP 协议支持
## 三、最终协议需求
### 3.1 MUX 帧格式
所有 MUX 数据承载必须使用如下格式:
```text
SYNC | LEN_H | LEN_L | SRCID | DSTMASK | PAYLOAD | TAIL
```
要求:
- `DSTMASK != 0x00`:业务数据帧
- `DSTMASK = 0x00`:系统控制帧
- 系统控制帧承载 AT 文本命令
- AT 文本命令必须以 `\r\n` 结尾
### 3.2 统一端点编码
系统必须使用统一端点编码,同时覆盖 UART 与 TCP 逻辑实例:
| 端点 | 编码 |
|------|------| |------|------|
| 主控芯片 | STM32F103R8T6(后续大批量生产可用 GD32 替代) | | `C1` | `0x01` |
| 以太网芯片 | CH390D | | `C2` | `0x02` |
| PCB 设计工具 | 立创 EDA(避免 AD 版权纠纷) | | `UART2` | `0x04` |
| 串口通道 | 2 路 UART | | `UART3` | `0x08` |
| `S1` | `0x10` |
| `S2` | `0x20` |
## 三、软件平台 要求:
| 项目 | 说明 | - `SRCID` 为单值
|------|------| - `DSTMASK` 为位图
| 开发环境 | STM32CubeMX + HAL 库 | - `DSTMASK=0x00` 仅保留给系统控制帧
| 操作系统 | FreeRTOS |
| 协议栈 | 标准 TCP/IP 协议 |
## 四、核心功能需求 ## 四、AT 接口需求
### 4.1 双链路 TCP 通信 ### 4.1 命令分类
- **Server 链路**:设备作为 TCP Server,监听指定端口,等待外部客户端连接 AT 协议必须收敛为以下三类命令:
- **Client 链路**:设备作为 TCP Client,主动连接远程服务器
- 两条链路共享**同一个对外 IP 地址**
### 4.2 串口透传 1. `AT+MUX`
2. `AT+NET`
3. `AT+LINK`
- **Server 链路数据** <==> **UART2** 双向透传 不再保留历史展开式实例字段命令。
- **Client 链路数据** <==> **UART3** 双向透传
- 仅透传 TCP 数据区(Payload),无需解析串口协议
### 4.3 参数配置 ### 4.2 MUX 命令需求
- 支持通过 **UART1** 串口命令修改设备 IP 地址等网络参数 - `AT+MUX=0/1`:设置全局 MUX 模式
- 配置参数需掉电保存 - `AT+MUX?`:查询当前 MUX 模式
### 4.4 数据可靠性 ### 4.3 NET 命令需求
- 确保 TCP 数据与串口数据双向传输不丢包 `NET` 必须统一表达以下静态网络参数:
- 提供丢包率测试方案及测试数据
## 五、交付物 ```text
IP,MASK,GW,MAC
```
1. 原理图及 PCB 设计文件(立创 EDA 格式) 说明:
2. STM32 固件源码(CubeMX 工程 + HAL 库 + FreeRTOS
3. 丢包测试方案及测试工具/数据
4. 使用说明文档
## 六、约束条件 - 设备只有一张网卡,因此本地 IP 不按实例拆分
- DHCP 不属于协议需求范围
- 通信协议:标准 TCP/IP ### 4.4 LINK 命令需求
- 串口透传:纯数据透传,不解析上层协议
- 硬件尺寸及供电参数由甲方提供 `LINK[idx]` 必须统一表达如下字段:
```text
EN,LPORT,RIP,RPORT,UART
```
要求:
- `idx` 固定映射四个实例:`0=S1``1=S2``2=C1``3=C2`
- `Server``Client` 共用同一条 `LINK` 配置模型
- `LPORT` 必须可配置
- `RIP / RPORT` 必须可配置
- `UART` 必须可配置
## 五、功能需求
### 5.1 TCP 功能
- 支持 `2` 路 Server
- 支持 `2` 路 Client
- 每个实例通过 `LINK[idx]` 配置其本地端口、对端地址、对端端口和串口路由
### 5.2 串口透传功能
- `UART2 / UART3` 支持普通透传模式与 MUX 透传模式
- 当需要多实例共享数据口时,必须启用 MUX 模式
- 业务数据流向由 `SRCID / DSTMASK` 决定
### 5.3 系统控制功能
- 系统控制帧由 `DSTMASK=0x00` 表示
- 系统控制帧进入 AT 解析路径
- 控制文本必须以 `\r\n` 结束
### 5.4 参数保存功能
- 参数修改后支持 `SAVE`
- 支持 `RESET` 后按保存配置启动
- 支持恢复默认配置
## 六、FreeRTOS 任务架构需求
### 6.1 任务划分
系统至少应包含以下 FreeRTOS 任务:
| 任务 | 优先级 | 职责 |
|------|--------|------|
| NetworkTask | 高 | CH390 事件轮询 + lwIP tcpip 处理 |
| UartTask | 高 | UART DMA/IDLE 接收 + MUX 帧处理 |
| ConfigTask | 中 | AT 命令解析与响应 |
| RouteTask | 中 | SRCID/DSTMASK 数据路由 |
| DefaultTask | 低 | LED 心跳 + 看门狗 |
### 6.2 任务间通信
- 使用 `Queue` 传递 UART 接收数据帧
- 使用 `Semaphore` 同步 CH390 中断事件
- 使用 `Mutex` 保护 SPI/CH390 共享访问
- 使用 `StreamBuffer` 传递 TCP 数据到 UART 方向
## 七、非功能需求
1. 满足 `STM32F103RCT6``256KB Flash / 48KB SRAM` 约束
2. 工程可在 `MDK-ARM` 下构建
3. 调试输出统一使用 `SEGGER RTT`
4. 不引入 DHCP、DNS、UDP 等当前非目标协议
5. FreeRTOS 堆使用 `heap_4.c`,总堆大小建议 `10KB`
6. 所有任务栈通过 `uxTaskGetStackHighWaterMark` 监控
## 八、验收口径
验收时以下几点必须同时成立:
1. 文档只使用 `MUX / NET / LINK` 作为最终协议模型
2. 文档不再出现历史 `S1... / C1...` 外部字段
3. 串口控制文本统一规定为 `\r\n` 结束
4. MUX 帧格式与端点编码在需求、手册、技术实现三份文档中表述一致
5. FreeRTOS 任务无死锁、无栈溢出、无优先级反转