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

10 KiB
Raw Permalink Blame History

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_Flagvolatile uint8_tIRQ 置 1业务任务读取后清 0
  • FrameBufferuint8_t[192][512]IRQ 写入,业务任务只读
  • 双缓冲 TXg_TxNetBuffer_A / g_TxNetBuffer_Buse_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 硬件初始化、DMA、IRQ、FrameBuffer 格式
QDX协议设计.md TLV 帧结构、零拷贝 TX、分片机制
TCP通信模块设计.md 双流连接、心跳、配置缓存
对接集成指南.md 外部对接方接入手册
Mini212G2预配置指南.md 传感器 TMP 模式配置 HEX 命令