zhoujie b69717b964 📝 docs(design): 新增系统设计文档集
 feat(system-overview): 创建系统总览文档
- 描述项目背景与硬件平台配置
- 提供 FreeRTOS 任务拓扑表(任务优先级、栈大小、职责)
- 详细说明系统启动序列和初始化依赖关系
- 绘制 2D/1D 状态机完整流程图
- 解释 TEMP_REQ 辅助通道工作机制
- 说明任务间同步机制(Frame_Ready_Flag、双缓冲 TX)

 feat(dvp-module-design): 创建 DVP 模块设计文档
- 提供 DVP 硬件连接引脚映射表
- 描述 DVP 时序配置(信号极性、工作模式)
- 解释 DMA ping-pong 行缓冲机制和切换逻辑
- 说明 DVP IRQ 帧组装流程(STR_FRM/ROW_DONE)
- 定义 FrameBuffer 数据格式和像素访问方式
- 说明 TMP 模式温度换算公式和字节序要求

 feat(qdx-protocol-design): 创建 QDX 协议设计文档
- 描述完整 TLV 帧结构(FrameHeader + TLV + CRC)
- 列出所有 Class/Type 映射表和用途说明
- 解释零拷贝 TX 缓冲区架构(HeadOffset 机制)
- 说明分片机制和最大载荷限制
- 定义 Flags 字段各位含义和使用场景

 feat(tcp-module-design): 创建 TCP 通信模块设计文档
- 描述双流连接架构(控制流 5511 / 数据流 5512)
- 说明握手流程和连接建立时序
- 解释心跳机制和 TCP Keepalive 配置
- 描述配置下发与缓存机制
- 说明数据发送队列和背压处理策略
- 解释 WCHNET 网络栈驱动任务工作机制

 feat(integration-guide): 创建对接集成指南
- 提供网络接入参数表(IP、端口、协议)
- 详细说明握手流程和配置下发格式
- 提供 2D/1D 温度帧解析方法和示例代码
- 说明检测结果上报和 NG 响应机制
- 解释 TEMP_REQ 按需截图工作方式
- 列出错误码表和对接故障排查步骤
2026-03-15 19:17:41 +08:00

234 lines
10 KiB
Markdown
Raw Permalink 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.

# CH32V307 固件系统总览
> 文档版本1.0 · 日期2026-03-15 · 状态:已发布
---
## 1. 项目背景与硬件平台
### 1.1 项目概述
本固件运行于 CH32V307WCU6 微控制器,连接 Mini212G2256×192红外热像传感器通过 1000M RGMII 以太网实时向上位机ConfigServer上报温度数据。
系统支持两种主要工作模式,均在 FreeRTOS 多任务框架下运行:
- **2D 模式**:矩阵温度帧触发采集(外部 GPIO 触发或内部温度阈值触发)
- **1D 模式**:时间轴温度序列采集(外部 GPIO 触发或内部连续热帧检测)
### 1.2 硬件配置
| 项目 | 规格 |
|------|------|
| MCU | CH32V307WCU6RISC-V144 MHz |
| FLASH | 128 KBOption Bytes 配置 `FLASH_128_SRAM_192` |
| SRAM | 192 KB |
| FreeRTOS Heap | 16 KBHeap_4 |
| 传感器 | Mini212G2256×192TMP 模式0.1°C/LSB |
| 传感器接口 | DVP 8-bit CMOS硬件 DMA ping-pong |
| 以太网 | 1000M RGMII |
| 调试串口 | USART3PB10 TX / PB11 RX921600 baud |
| 外部触发输入 | PA15 / EXTI15上升沿内部下拉 |
| NG 输出 | PA8推挽高电平有效 |
> **TMP 模式说明**:传感器必须预配置为 TMP 模式(非 Y16 原始 ADC输出值为 0.1°C/LSB 的绝对温度,无需 MCU 换算。配置方法见 `Doc/Mini212G2预配置指南.md`。
---
## 2. FreeRTOS 任务拓扑
### 2.1 任务列表
| 任务名 | 优先级 | 栈words | 条件 | 职责 |
|--------|--------|-------------|------|------|
| `task_wchnet_entry` | 6最高 | 512 | 始终创建 | WCHNET 协议栈驱动,每 5 ms 轮询 |
| `task_business_entry` | 5 | 512 | 始终创建 | DVP 帧消费、2D/1D 状态机、TCP 发送 |
| `task_test_pattern_entry` | 4 | 256 | `TEST_PATTERN_MODE=1` 时 | 仿真传感器数据不含真实DVP |
| `task_heartbeat_entry` | 3最低 | 256 | 始终创建 | 调试心跳打印,每 2 s 一次 |
### 2.2 任务间数据流
```
传感器DVP 硬件)
│ 每行 512 BDMA ping-pong
DVP_IRQHandlerWCH-Interrupt-fast
│ ① STR_FRM → current_line_idx = 0
│ ② ROW_DONE → memcpy → FrameBuffer[idx]
│ ③ idx == 191 → Frame_Ready_Flag = 1
task_business_entry优先级 5
│ 轮询 Frame_Ready_Flag
│ 读取 FrameBuffer共享内存
│ 执行 Preprocess_Execute / get_1d_sample
TcpLogic_BuildAndSendTemperatureFrame
│ 零拷贝写入帧头HeadOffset 空间复用)
task_wchnet_entry优先级 6
│ WCHNET_MainTask / WCHNET_HandleGlobalInt
以太网 → ConfigServer
```
**关键同步机制**
- `Frame_Ready_Flag``volatile uint8_t`IRQ 置 1业务任务读取后清 0
- `FrameBuffer``uint8_t[192][512]`IRQ 写入,业务任务只读
- 双缓冲 TX`g_TxNetBuffer_A` / `g_TxNetBuffer_B``use_buffer_A` 标志交替,保证一帧发送未完时下一帧可立即写入
- `qdx_port_net_lock/unlock`:互斥量保护 WCHNET API防止业务任务和网络任务并发
---
## 3. 系统启动序列
`main()` 按以下顺序执行初始化,各步骤依赖前序完成:
```
SystemCoreClockUpdate() → 更新 SystemCoreClock144 MHz
Delay_Init() → SysTick 初始化,提供 sys_tick_ms 计时
USART_Printf_Init(921600) → USART3 调试串口PB10/PB11
Config_Flash_SRAM(FLASH_128_SRAM_192) → Option BytesFLASH=128KSRAM=192K
(若已配置跳过;否则写入后系统复位)
DVP_Init() → GPIO 配置、DMA ping-pong 缓冲、IRQ 使能
TIM2_Init() → WCHNET 定时器1 ms 周期)
ExtTrigger_GPIO_Init() → PA15 EXTI15上升沿中断
NG_GPIO_Init() → PA8 推挽输出,默认低
ETH_LibInit(IP, GW, Mask, MAC) → WCHNET 协议栈初始化1000M RGMII
WCHNET_ConfigKeepLive(20000,15000,9) → TCP Keepalive
qdx_port_init() → QDX 网络层 socket/互斥量初始化
Preprocess_Init(256, 192) → 图像预处理模块
TcpLogic_Init(MACAddr, NULL) → TCP 逻辑层,注册 DeviceUUID=MAC
TcpLogic_Register*Callback() → 注册 OnConfigUpdate / OnDetectionResult / OnTempFrameRequest
TcpLogic_Start() → 启动后台连接状态机(控制流 → 握手 → 数据流)
xTaskCreate(×3 或 ×4) → 创建 RTOS 任务
vTaskStartScheduler() → 启动调度器(不返回)
```
> **Option Bytes 说明**:首次上电若 Flash/SRAM 分配不符,`Config_Flash_SRAM` 会写入 Option Bytes 并触发 `NVIC_SystemReset()`,复位后以新分配重新启动。正常运行时该函数直接返回。
---
## 4. 2D 状态机
2D 模式在 `task_business_entry` 中,每帧调用 `handle_2d_trigger()`,由 4 个状态变量组成隐式状态机:
### 4.1 状态转换图
```
┌─────────────────── IDLE ──────────────────────────┐
│ │
│ TriggerMode=1外部 │ TriggerMode=0内部
│ PA15 上升沿 → g_ext_trigger_flag=1 │ Preprocess_CheckInternalTrigger2D()==1
↓ ↓
DEBOUNCE (直接)
等待 DebounceIntervalMs │
│ │
└──────────────────────────────────────────────────→┤
DELAY
等待 TriggerDelayMs
BURST循环
发送第 1 帧(立即)
+ 剩余 BurstCount-1 帧
@ TriggerInternalIntervalMs 间隔
burst_remaining == 0
→ IDLE
```
### 4.2 状态参数
| 配置字段 | 默认值 | 说明 |
|----------|--------|------|
| `TriggerMode` | 0 | 0=内部温度阈值1=外部 GPIO |
| `TriggerDebounceIntervalMs` | 0 | 外部触发防抖等待时间ms |
| `TriggerDelayMs` | 0 | 触发确认到第一帧采集的延迟ms |
| `TriggerBurstCount` | 3 | 每次触发发送帧数DEFAULT_BURST_COUNT=3 |
| `TriggerInternalIntervalMs` | 200 | 连拍帧间隔DEFAULT_BURST_INTERVAL_MS=200 ms |
| `TriggerCondition` | 0 | 内部触发判据0=Avg1=Max |
| `TriggerTemperatureThreshold` | — | 内部触发温度阈值0.1°C/LSB |
| `TriggerRoiX/Y/W/H` | — | 内部触发检测 ROI 区域 |
### 4.3 双缓冲 TX 策略
每次 `do_2d_capture_send()` 交替选择 `g_TxNetBuffer_A` / `g_TxNetBuffer_B`,通过 `use_buffer_A` 标志取反实现切换。TCP 发送入队后立即切换,保证下一帧填充不覆盖正在传输的缓冲区。
---
## 5. 1D 状态机
1D 模式以每帧全帧最大温度作为一个采样点,在 `task_business_entry` 中每帧调用 `handle_1d_trigger()`
### 5.1 状态图
```
S1D_IDLE
├─ TriggerType=2外部PA15 上升沿
│ → S1D_DEBOUNCE等待 HighTimerLimit ms
│ → S1D_COLLECTING
└─ TriggerType=1内部维护 3 帧滑动窗口
连续 3 帧最大温度 ≥ TriggerTempLimit
→ S1D_COLLECTING直接含预触发 3 帧数据)
S1D_COLLECTING每帧采一个样本
├─ 记录 sample = 全帧最大温度time_offset = ms - start_time
├─ 热帧(≥ threshs1d_consec_hot++consec_cold=0
│ 满足 3 次热 → s1d_triggered=1
└─ 停止条件(任意一满足):
① s1d_count ≥ MAX_1D_POINTS512
② s1d_count ≥ BufferSize
③ s1d_triggered && s1d_consec_cold ≥ NgCountLimit
└─ 若 triggered → send_1d_collection()
否则 → 丢弃reset
→ S1D_IDLE
```
### 5.2 数据格式
每个样本 **4 字节**,小端序:
| 字节 | 字段 | 类型 | 说明 |
|------|------|------|------|
| 01 | `TimeOffset` | uint16_t LE | 相对采集开始的 ms 偏移 |
| 23 | `Temperature` | uint16_t LE | 全帧最大温度0.1°C/LSB |
### 5.3 切片参数
发送前对采集缓冲区切片:有效区间 = `[LSizeStart, count - RSizeStart)`,去除头尾噪声点。若切片越界则退化为全量发送并打印告警。
---
## 6. TEMP_REQ 辅助通道
服务器可通过控制流随时请求单帧快照,无需等待自主采集触发:
```
服务器发送 TEMP_REQ含 is2dRequest 字段)
→ OnTempFrameRequest() 回调
→ g_temp_req_pending = 1g_temp_req_is2d = is2dRequest
task_business_entry 业务循环检测到 g_temp_req_pending
→ TcpLogic_GetLatestConfig() 确认对应模式 Enabled
→ is2d=1Preprocess_Execute() + TcpLogic_BuildAndSendTemperatureFrameSocketType=0x02
is2d=0send_1d_snapshot()(中心行 30 个等间距采样点,时间偏移仿真 0~600 ms
```
**限制**:仅在对应模式(`t2.Enabled` / `t1.Enabled`)为 1 时响应;若未 Enabled打印 DBG_ERR 并忽略请求。
---
## 7. 相关文档
| 文档 | 内容 |
|------|------|
| [DVP模块设计.md](DVP模块设计.md) | DVP 硬件初始化、DMA、IRQ、FrameBuffer 格式 |
| [QDX协议设计.md](QDX协议设计.md) | TLV 帧结构、零拷贝 TX、分片机制 |
| [TCP通信模块设计.md](TCP通信模块设计.md) | 双流连接、心跳、配置缓存 |
| [对接集成指南.md](对接集成指南.md) | 外部对接方接入手册 |
| [Mini212G2预配置指南.md](../Mini212G2预配置指南.md) | 传感器 TMP 模式配置 HEX 命令 |