📝 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 按需截图工作方式
- 列出错误码表和对接故障排查步骤
This commit is contained in:
2026-03-15 19:17:41 +08:00
parent c347c988f2
commit b69717b964
19 changed files with 1818 additions and 0 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-03-15
@@ -0,0 +1,50 @@
## Context
**项目背景**:CH32V307WCU6 红外热像采集端固件,连接 Mini212G2 (256×192) 传感器,通过 1000M RGMII 以太网上报温度数据。核心功能已稳定运行,但缺少系统性设计文档。
**当前状态**:代码实现完整,包含 FreeRTOS 多任务、DVP+DMA 采集、QDX TLV 协议、双流 TCP 通信、2D/1D 双状态机。现有文档仅覆盖配置参数和协议接口,未形成模块级设计视图。
**读者**:内部开发工程师(理解实现逻辑、维护代码);外部对接方(ConfigServer/上位机开发团队,需接入协议)。
## Goals / Non-Goals
**Goals:**
- 为 5 个能力模块分别建立规范化的设计文档
- 通过 openspec specs 机制使文档可版本追踪和演进
- 提供外部对接方可直接使用的集成指南(无需阅读源码)
**Non-Goals:**
- 不修改任何代码
- 不覆盖硬件电气原理图(属于硬件文档)
- 不重复协议 HEX 命令表(已在 `Doc/Mini212G2预配置指南.md`)
## Decisions
### 决策 1:每个能力模块生成独立的 spec 文件,Doc/ 目录存放最终可交付文档
**理由**:openspec 的 `specs/<capability>/spec.md` 是规范锚点,实际可读性文档放在 `Doc/设计文档/` 下,分工清晰。每个 spec 描述 WHAT(需求),Doc 中文件描述 HOW(实现细节)。
**备选方案**:一个大 spec 文件 → 拒绝,spec 文件过大时 apply 阶段难以跟踪单个需求。
### 决策 2:集成指南(integration-guide)作为独立能力,单独维护
**理由**:外部对接方只需集成指南,不需要理解内部模块设计。独立文件避免外部文档被内部修改污染,版本可单独管控。
### 决策 3:文档覆盖既有代码的实际行为,不做超前设计
**理由**:这是文档补全变更,不是功能变更。spec 反映的是代码已实现的行为(SHALL = 当前实现保证),不引入新约束。
### 决策 4:2D 状态机和 1D 状态机各自独立描述,不合并
**理由**:两者触发逻辑、收集方式、发送格式完全不同(2D 矩阵 vs 1D 时间序列)。合并描述会造成混淆。两者通过 `Config2D.Enabled` / `Config1D.Enabled` 互斥使能。
## Risks / Trade-offs
- **风险**:文档编写时代码继续演进,导致文档过时 → **缓解**:在 spec 中使用 SHALL 约束当前行为,代码变更时触发 spec 更新 PR 流程。
- **风险**:integration-guide 中的协议字段描述与实际结构体不一致 → **缓解**:所有字段描述直接从 `qdx_protocol.h` 提取,source of truth 为代码。
- **权衡**:文档详细程度 vs 维护成本 → 选择"关键路径详细,边缘情况参考注释"策略,避免过度文档导致维护负担。
## Open Questions
- Doc/ 下设计文档是否需要中英双语(供外部团队使用)?当前按中文优先。
- integration-guide 是否需要提供 Python/C# 示例解析代码片段?后续可作为独立变更补充。
@@ -0,0 +1,32 @@
# Proposal: CH32V307 固件系统软件设计文档
## Why
项目已完成核心功能开发,但缺乏系统级软件设计文档:内部无法快速理解任务拓扑和状态机逻辑,外部对接方缺乏集成参考。当前文档仅覆盖配置和协议层面,未形成完整的设计视图。
## What Changes
- 新增 **系统总览文档**:FreeRTOS 任务拓扑(任务职责、优先级、通信方式)、2D/1D 双状态机完整流程图、网络栈初始化与运行流程
- 新增 **DVP 采集模块设计文档**:DVP 硬件配置原理、DMA ping-pong 机制、IRQ 帧组装逻辑、FrameBuffer 数据格式
- 新增 **QDX 协议模块设计文档**:TLV 帧结构、所有 Type 定义与用途、零拷贝 TX 缓冲区架构、分片机制
- 新增 **TCP 通信模块设计文档**:双流(5511 控制 / 5512 数据)连接管理、心跳机制、配置下发与缓存、数据发送队列
- 新增 **对接集成文档**:供上位机/ConfigServer 开发方参考的接入指南(握手流程、配置下发、数据帧解析、错误码)
## Capabilities
### New Capabilities
- `system-overview`: FreeRTOS 任务拓扑、2D 状态机、1D 状态机、系统启动序列
- `dvp-module-design`: DVP 硬件初始化、DMA ping-pong 行采集、帧组装、FrameBuffer 格式
- `qdx-protocol-design`: TLV 帧格式、Class/Type 定义、零拷贝 TX 架构、CRC、分片
- `tcp-module-design`: 双流连接管理、心跳、配置缓存、发送队列
- `integration-guide`: 外部对接方集成手册(握手、配置、数据解析、错误处理)
### Modified Capabilities
(无,本变更仅新增文档,不修改现有规范)
## Impact
- **新增文档目录**:`Doc/设计文档/` 或各模块独立文件
- **不涉及**任何代码修改
- 影响范围:内部开发参考、外部对接方(ConfigServer 开发团队)
@@ -0,0 +1,49 @@
## ADDED Requirements
### Requirement: DVP 硬件初始化配置描述
文档 SHALL 描述 DVP 外设的完整初始化配置,包含 GPIO 引脚映射、工作模式和信号极性。
#### Scenario: 开发者核查 DVP GPIO 引脚分配
- **WHEN** 开发者进行硬件调试时
- **THEN** 文档 SHALL 提供引脚映射表:PA4/5/6/9/10(数据线 D0-D4)、PC8/9/11(D5-D7 + PCLK)、PB3/8/9(VSYNC/HSYNC/PIXCLK),所有引脚配置为浮空输入
#### Scenario: 开发者理解 DVP 信号极性配置
- **WHEN** 开发者对接不同传感器时
- **THEN** 文档 SHALL 说明:VSYNC 高有效(RB_DVP_V_POLAR=1,对应 DIGITAL_FIELD_VALID 高电平有效帧)、HSYNC 高有效(RB_DVP_H_POLAR=0)、PCLK 上升沿采样(RB_DVP_P_POLAR=0),与 Mini212G2 手册时序图一致
### Requirement: DMA ping-pong 行缓冲机制描述
文档 SHALL 描述 DVP DMA 双缓冲的工作原理,包含缓冲切换逻辑和 IRQ 中的正确读取方式。
#### Scenario: 开发者理解 DMA 缓冲切换逻辑
- **WHEN** 开发者排查行数据乱序问题时
- **THEN** 文档 SHALL 说明:DVP 硬件在 DMA_BUF0/BUF1 间自动切换,ROW_DONE 中断触发时硬件已切换到下一个缓冲;BUF_TOG=1 表示 DMA 正在写 BUF0,此时应读 BUF1(公式:`src = (CR1 & BUF_TOG) ? DMA_LineBuf0 : DMA_LineBuf1`)
#### Scenario: 开发者理解行缓冲大小约束
- **WHEN** 开发者修改传感器分辨率时
- **THEN** 文档 SHALL 说明:DMA_LineBuf0/1 各 512 字节(256 像素 × 2 字节),COL_NUM=512,ROW_NUM=1(每行触发一次 IRQ),修改分辨率需同时更新 `BYTES_PER_LINE`、`SENSOR_WIDTH`、`SENSOR_HEIGHT`
### Requirement: DVP IRQ 帧组装逻辑描述
文档 SHALL 描述 `DVP_IRQHandler` 的完整逻辑,包含帧同步机制和 FrameBuffer 组装方式。
#### Scenario: 开发者理解帧同步锚点
- **WHEN** 开发者排查帧错位问题时
- **THEN** 文档 SHALL 说明:STR_FRM 中断(VSYNC 上升沿)将 `current_line_idx` 清零,此为帧同步唯一锚点;ROW_DONE 中断依次将行数据 memcpy 至 `FrameBuffer[current_line_idx]` 并递增
#### Scenario: 开发者理解帧完成标志
- **WHEN** 开发者需要知道何时帧数据可用时
- **THEN** 文档 SHALL 说明:当 `idx == SENSOR_HEIGHT - 1`(即第 191 行完成)时,`Frame_Ready_Flag` 置 1,`Ready_Frame_Count` 更新为当前帧号;业务任务轮询此标志,读取后将其清零
#### Scenario: 开发者理解 IRQ 使用 fast interrupt 属性的原因
- **WHEN** 开发者修改 IRQ 属性时
- **THEN** 文档 SHALL 说明:`__attribute__((interrupt("WCH-Interrupt-fast")))` 使中断处理跳过寄存器入栈,减少中断延迟,确保在下一行像素时钟到来前完成 memcpy(每行约 42.67µs @ 25Hz)
### Requirement: FrameBuffer 数据格式描述
文档 SHALL 描述 FrameBuffer 的内存布局和像素值含义。
#### Scenario: 开发者访问特定像素的温度值
- **WHEN** 开发者需要读取第 row 行第 col 列的温度时
- **THEN** 文档 SHALL 说明:`FrameBuffer` 声明为 `uint8_t[192][512]`,通过 `(uint16_t*)FrameBuffer` 访问,像素值 = `((uint16_t*)FrameBuffer)[row * 256 + col]`,单位 0.1°C/LSB(TMP 模式,需传感器预配置为 TMP)
#### Scenario: 开发者理解字节序要求
- **WHEN** 开发者移植到大端序平台时
- **THEN** 文档 SHALL 说明:CH32V307 为小端序,`uint8_t[0]` = 低字节,`uint8_t[1]` = 高字节;传感器必须配置为 CMOS8(LSB)(低字节先发),否则温度值字节反序
@@ -0,0 +1,58 @@
## ADDED Requirements
### Requirement: 对接方网络接入参数说明
文档 SHALL 提供上位机(ConfigServer)与采集端建立 TCP 连接所需的全部参数。
#### Scenario: 对接方配置 TCP Server 监听端口
- **WHEN** 对接方开发服务端程序时
- **THEN** 文档 SHALL 提供:MCU 默认 IP=192.168.7.10,Subnet=255.255.255.0,Gateway=192.168.7.1;Server 需在 192.168.7.50 监听两个端口:5511(控制流,MCU 主动连入)和 5512(数据流,MCU 主动连入);以太网接口为 1000M RGMII
### Requirement: 握手流程说明
文档 SHALL 描述 MCU 上电后的握手过程,使对接方能正确识别采集端设备。
#### Scenario: 对接方接收第一个数据包并识别设备
- **WHEN** MCU 连接后发送握手帧时
- **THEN** 文档 SHALL 说明:MCU 在控制流连接成功后发送 TYPE_HANDSHAKE(Class=CLASS_SYSTEM,含 ProtocolVersion=0x0200、DeviceUUID=MAC 地址、AuthToken=全零);服务器 SHALL 回复握手响应以完成握手;握手完成后 MCU 才开始正常数据上报
### Requirement: 配置下发格式说明
文档 SHALL 描述服务器向 MCU 下发配置的帧格式和所有配置字段含义。
#### Scenario: 对接方配置 2D 触发模式
- **WHEN** 对接方发送 Config2D 配置帧时
- **THEN** 文档 SHALL 提供 Config2D_t 所有字段:Enabled(uint8_t)、TriggerMode(uint8_t, 0=内部温度/1=外部GPIO)、TriggerDebounceIntervalMs(uint16_t)、TriggerDelayMs(uint16_t)、TriggerBurstCount(uint8_t)、TriggerInternalIntervalMs(uint16_t)、TriggerTemperatureThreshold(int16_t, 0.1°C/LSB)、TriggerCondition(uint8_t, 0=Avg/1=Max)、TriggerRoiX/Y/W/H(uint16_t)、TargetWidth/Height(uint16_t)、NGioDelay(uint16_t, ms)
#### Scenario: 对接方配置 1D 采集模式
- **WHEN** 对接方发送 Config1D 配置帧时
- **THEN** 文档 SHALL 提供 Config1D_t 所有字段:Enabled(uint8_t)、RunMode(uint8_t, 0=STOP/1=RUN)、TriggerType(uint8_t, 1=内部/2=外部)、TriggerTempLimit(int16_t)、HighTimerLimit(uint16_t, ms)、NgCountLimit(uint16_t, 帧数)、BufferSize(uint16_t)、LSizeStart/RSizeStart(uint16_t, 切片参数)
### Requirement: 温度帧数据包格式说明
文档 SHALL 描述 MCU 上报的温度帧数据包的完整格式,使对接方能正确解析。
#### Scenario: 对接方解析收到的 2D 温度帧
- **WHEN** 数据流收到 TYPE_TEMP_FRAME 包时
- **THEN** 文档 SHALL 说明:Value 区域含 PreprocessResult 元数据(ValidWidth × ValidHeight 像素数组);像素为 uint16_t little-endian,单位 0.1°C/LSB;元数据含 MaxTemp/MinTemp/AvgTemp/RoiTemp(均 int16_t, 0.1°C/LSB)、ValidWidth/ValidHeight(实际 ROI 尺寸)、FrameNumber
#### Scenario: 对接方解析收到的 1D 温度帧
- **WHEN** 数据流收到 1D TYPE_TEMP_FRAME 包时
- **THEN** 文档 SHALL 说明:is2D=0,每个样本 4 字节:[time_off_lo, time_off_hi, temp_lo, temp_hi],time_offset 为相对采集开始的 ms 偏移(uint16_t),temp 为 uint16_t 0.1°C/LSB
### Requirement: 触发结果上报和 NG 响应机制说明
文档 SHALL 描述采集端如何响应服务器的 DetectionResult 决策和触发 NG 输出。
#### Scenario: 对接方下发检测结果
- **WHEN** 服务器完成图像分析后回传结果时
- **THEN** 文档 SHALL 说明:服务器发送 TYPE_DETECTION_RESULT(含 frameNumber、resultStatus,0=NG/1=OK);MCU 收到 resultStatus=0 时触发 PA8 高电平 NGioDelay ms(默认 200ms);对接方可通过 NGioDelay 配置 NG 输出脉宽
### Requirement: TEMP_REQ 按需截图说明
文档 SHALL 描述服务器如何向 MCU 请求即时截图。
#### Scenario: 对接方请求单帧截图
- **WHEN** 服务器需要调试或核查当前热场时
- **THEN** 文档 SHALL 说明:控制流发送 TYPE_CONFIG_COMMON 或专用 TEMP_REQ 命令(含 is2dRequest 字段);MCU 将在下一个业务循环发送当前最新帧,2D 返回 ROI 裁切后温度矩阵,1D 返回中心行 30 个等间距采样点;仅在对应模式已 Enabled 时响应
### Requirement: 错误码和异常处理说明
文档 SHALL 列出协议层所有错误码含义及对接方应采取的处理措施。
#### Scenario: 对接方收到 ERR 响应帧
- **WHEN** 服务器发送格式错误的配置帧时
- **THEN** 文档 SHALL 列出错误码含义:ERR_CRC(0x1001)=CRC 校验失败、ERR_VERSION(0x1002)=协议版本不匹配、ERR_LENGTH(0x1003)=帧长度异常、ERR_AUTH(0x2001)=认证失败、ERR_BUSY(0x2002)=设备忙、ERR_PARAM(0x3001)=参数非法;收到错误码后对接方 SHALL 检查发送的帧格式后重试
@@ -0,0 +1,37 @@
## ADDED Requirements
### Requirement: TLV 帧结构完整描述
文档 SHALL 描述 QDX 协议的完整帧结构,包含帧头各字段含义、TLV 格式和帧尾 CRC。
#### Scenario: 开发者手动构造一个协议帧
- **WHEN** 开发者需要调试发送内容时
- **THEN** 文档 SHALL 提供帧结构:[FrameHeader 16B] + [TLV_Header 3B] + [Value NB] + [CRC16 2B],其中 FrameHeader = {Magic(2)=0x55AA, Version(1)=0x20, Length(2), Sequence(2), Timestamp(4), Source(1), DevID(2), Class(1), Flags(1)}
#### Scenario: 开发者理解 Class 和 TLV Type 的对应关系
- **WHEN** 开发者解析收到的帧时
- **THEN** 文档 SHALL 列出完整的 Class/Type 映射表:CLASS_CONTROL(0x01)、CLASS_DATA(0x02)、CLASS_RESPONSE(0x03)、CLASS_SYSTEM(0x04);Type 包含 TYPE_HANDSHAKE(0x01)、TYPE_HEARTBEAT(0x02)、TYPE_TEMP_FRAME(0x10)、TYPE_CONFIG_COMMON(0x20)、TYPE_CONFIG_2D(0x22)、TYPE_CONFIG_1D(0x23)、TYPE_ACK_PAYLOAD(0x30)、TYPE_DETECTION_RESULT(0x40) 等
### Requirement: 零拷贝 TX 缓冲区架构描述
文档 SHALL 描述 TcpTxBuffer_t 的双缓冲零拷贝发送架构和 HeadOffset 的使用方式。
#### Scenario: 开发者理解零拷贝的实现方式
- **WHEN** 开发者需要在减少内存拷贝的前提下添加新的帧类型时
- **THEN** 文档 SHALL 说明:`TcpTxBuffer_t` 包含 pBuffer(9216B)、HeadOffset(64B)、ValidPayloadLen;图像数据由预处理模块写入 `pBuffer + HeadOffset` 开始的位置;`TcpLogic_BuildAndSendTemperatureFrame` 在 HeadOffset 前的 64 字节内直接写入帧头(FrameHeader + TLV),**无需额外 memcpy**
#### Scenario: 开发者计算单次可发送的最大像素数
- **WHEN** 开发者调整 ROI 大小时
- **THEN** 文档 SHALL 说明:有效载荷容量 = TotalCapacity(9216) - HeadOffset(64) - CRC(2) - TLV_Header(3) - FrameHeader(16) = 9131 字节,每像素 2 字节,最多 4565 个像素(约 67×67 ROI)
### Requirement: 分片机制描述
文档 SHALL 描述协议层的分片上限和分片标志用法。
#### Scenario: 开发者发送超大载荷时
- **WHEN** 开发者发送超过 MAX_FRAGMENT_PAYLOAD(1400B) 的数据时
- **THEN** 文档 SHALL 说明分片最大载荷为 1400B(受 TCP MSS=1460 限制),大帧通过 FLAG_LAST_FRAGMENT(0x20) 标志标识末片;当前 TX 缓冲区为 9216B,单次发送通常不超过此限制
### Requirement: Flags 字段用法描述
文档 SHALL 描述 FrameHeader.Flags 各位的含义和当前固件的使用情况。
#### Scenario: 开发者解析收到的 Flags 字段
- **WHEN** 上位机解析帧时
- **THEN** 文档 SHALL 说明:FLAG_PRIORITY_MASK(0x03)=优先级(0-3)、FLAG_COMPRESSED(0x04)=压缩(当前未使用)、FLAG_ENCRYPTED(0x08)=加密(当前未使用)、FLAG_ACK_REQ(0x10)=需要 ACK、FLAG_LAST_FRAGMENT(0x20)=末片标志
@@ -0,0 +1,56 @@
## ADDED Requirements
### Requirement: FreeRTOS 任务拓扑描述
文档 SHALL 列出所有 RTOS 任务的名称、优先级、栈大小、职责及任务间通信方式。
#### Scenario: 开发者查阅任务优先级
- **WHEN** 开发者需要了解任务调度顺序时
- **THEN** 文档 SHALL 提供任务优先级表,包含:task_wchnet(优先级 6,512 字)、task_business(优先级 5,512 字)、task_heartbeat(优先级 3,256 字)、task_test_pattern(优先级 4,256 字,仅 TEST_PATTERN_MODE=1 时存在)
#### Scenario: 开发者理解任务间数据流
- **WHEN** 开发者需要理解 DVP → 业务任务的数据传递时
- **THEN** 文档 SHALL 说明通过 `Frame_Ready_Flag`(volatile 标志)和 `FrameBuffer`(共享内存)传递帧数据,IRQ 置位,业务任务轮询消费
### Requirement: 系统启动序列描述
文档 SHALL 描述 `main()` 的初始化顺序,涵盖所有外设和模块的初始化步骤及其依赖关系。
#### Scenario: 开发者定位初始化顺序问题
- **WHEN** 开发者遇到启动相关 bug 时
- **THEN** 文档 SHALL 提供启动序列:SystemClock → USART3/debug → Flash/SRAM 配置(128K+192K)→ DVP_Init → TIM2_Init → ExtTrigger_GPIO → NG_GPIO → ETH_LibInit → qdx_port_init → Preprocess_Init → TcpLogic_Init → 注册回调 → TcpLogic_Start → 创建 RTOS 任务 → vTaskStartScheduler
### Requirement: 2D 状态机完整描述
文档 SHALL 描述 2D 触发状态机的所有状态、转换条件和行为,包含外部触发和内部触发两种模式。
#### Scenario: 开发者理解 2D 外部触发流程
- **WHEN** 开发者排查外部触发抖动问题时
- **THEN** 文档 SHALL 描述:IDLE → [PA15 上升沿] → DEBOUNCE(等待 DebounceIntervalMs) → DELAY(等待 TriggerDelayMs) → BURST(发 BurstCount 帧,间隔 TriggerInternalIntervalMs) → IDLE
#### Scenario: 开发者理解 2D 内部触发流程
- **WHEN** 开发者配置温度阈值触发时
- **THEN** 文档 SHALL 描述:每帧调用 `Preprocess_CheckInternalTrigger2D`,在 TriggerRoi 区域内 Max/Avg 超过 TriggerTemperatureThreshold 时触发,跳过 DEBOUNCE 直接进入 DELAY → BURST
#### Scenario: 开发者理解双缓冲 TX 逻辑
- **WHEN** 开发者排查发送顺序问题时
- **THEN** 文档 SHALL 说明 `use_buffer_A` 标志在每次发送时取反,g_TxNetBuffer_A / g_TxNetBuffer_B 交替使用,避免前一帧发送未完成时被覆盖
### Requirement: 1D 状态机完整描述
文档 SHALL 描述 1D 采集状态机的所有状态、转换条件、采集逻辑和发送条件。
#### Scenario: 开发者理解 1D 外部触发流程
- **WHEN** 开发者配置 TriggerType=2 时
- **THEN** 文档 SHALL 描述:S1D_IDLE → [PA15 上升沿] → S1D_DEBOUNCE(等待 HighTimerLimit ms) → S1D_COLLECTING(采集 temp+time 样本直到停止条件)→ 发送 → S1D_IDLE
#### Scenario: 开发者理解 1D 内部触发流程
- **WHEN** 开发者配置 TriggerType=1 时
- **THEN** 文档 SHALL 描述:S1D_IDLE 中维护 3 帧滑动窗口,连续 3 帧帧最大温度 ≥ TriggerTempLimit 时进入 S1D_COLLECTING;停止条件:样本数达 BufferSize 或触发后连续 NgCountLimit 帧低温
#### Scenario: 开发者理解 1D 数据格式
- **WHEN** 开发者解析 1D 数据时
- **THEN** 文档 SHALL 说明每个样本 4 字节:[time_offset_lo, time_offset_hi, temp_lo, temp_hi],time_offset 为相对采集开始的 ms 偏移,temp 为 0.1°C/LSB 的 uint16_t
### Requirement: TEMP_REQ 辅助通道描述
文档 SHALL 描述服务器按需截图(TEMP_REQ)的触发流程和限制条件。
#### Scenario: 开发者理解 TEMP_REQ 工作方式
- **WHEN** 服务器发送 TEMP_REQ 命令时
- **THEN** 文档 SHALL 说明:`g_temp_req_pending` 置位,业务任务在下次循环读取当前 FrameBuffer 发送,is2D=1 走 Preprocess_Execute + 2D 封包,is2D=0 走 send_1d_snapshot(30 个等间距采样点);仅在对应模式 Enabled 时响应
@@ -0,0 +1,44 @@
## ADDED Requirements
### Requirement: 双流连接架构描述
文档 SHALL 描述控制流(5511)和数据流(5512)的职责分工、连接方式和状态管理。
#### Scenario: 开发者理解双流设计意图
- **WHEN** 开发者排查连接问题时
- **THEN** 文档 SHALL 说明:控制流 srcport=5511(MCU 主动连接 Server),用于握手、配置下发、心跳、TEMP_REQ、DetectionResult 上报;数据流 desport=5512(MCU 主动连接 Server),用于温度帧数据上报;两流独立管理,数据流断开不影响控制流
#### Scenario: 开发者理解 TCP 连接建立时序
- **WHEN** 开发者排查首次握手失败时
- **THEN** 文档 SHALL 说明:`TcpLogic_Start` 派生后台连接状态机,先尝试控制流连接 → 连接成功后发送 TYPE_HANDSHAKE(含 DeviceUUID=MAC地址、AuthToken=NULL)→ 收到服务器握手响应后标记连接就绪 → 同步尝试数据流连接
### Requirement: 心跳机制描述
文档 SHALL 描述心跳帧的发送周期、TCP Keepalive 配置和连接保活策略。
#### Scenario: 开发者调整心跳参数
- **WHEN** 网络中间件(NAT/防火墙)超时断连时
- **THEN** 文档 SHALL 说明:应用层心跳 TYPE_HEARTBEAT 由 TcpLogic 内部定时发送;TCP Keepalive 配置:空闲 20 秒(`idle=20000ms`)后开始探测,每次间隔 15 秒(`interval=15000ms`),最多 9 次(`count=9`)探测无响应则断链重连
### Requirement: 配置下发与缓存机制描述
文档 SHALL 描述服务器配置的接收、缓存和通知流程。
#### Scenario: 开发者追踪配置更新流程
- **WHEN** 服务器下发配置后行为未按预期改变时
- **THEN** 文档 SHALL 描述:服务器发送 TYPE_CONFIG_COMMON + TYPE_CONFIG_2D + TYPE_CONFIG_1D → TcpLogic 解析并缓存至内部 shadow 寄存器 → 触发 ConfigUpdateCallback(`OnConfigUpdate`)→ 回调内调用 `Preprocess_Settings_Change` 更新预处理参数;`TcpLogic_GetLatestConfig` 可随时读取最新配置副本
#### Scenario: 开发者理解无配置时的默认行为
- **WHEN** 设备启动后服务器尚未下发配置时
- **THEN** 文档 SHALL 说明:`TcpLogic_GetLatestConfig` 返回 -1,业务任务跳过 2D/1D 处理,仅响应 TEMP_REQ(若有);默认 burst 参数 DEFAULT_BURST_COUNT=3、DEFAULT_BURST_INTERVAL_MS=200ms 作为 fallback
### Requirement: 数据发送队列和背压处理描述
文档 SHALL 描述温度帧发送的队列机制和发送失败时的处理策略。
#### Scenario: 开发者排查数据帧丢失问题
- **WHEN** 网络繁忙时出现帧丢失时
- **THEN** 文档 SHALL 说明:`TcpLogic_BuildAndSendTemperatureFrame` 返回 0 表示成功入队,返回 <0 表示发送失败(队列满或连接断开);当前固件对发送失败仅打印 DBG_ERR,不重试;双缓冲 TX 保证当前帧被入队时,下一帧可立即写入另一个缓冲
### Requirement: WCHNET 网络栈驱动任务描述
文档 SHALL 描述 task_wchnet 的职责和与 WCHNET 库的交互方式。
#### Scenario: 开发者理解网络栈如何被驱动
- **WHEN** 开发者排查网络响应迟缓问题时
- **THEN** 文档 SHALL 说明:`task_wchnet_entry` 每 5ms 轮询一次,调用 `WCHNET_MainTask`(协议栈心跳)和 `WCHNET_HandleGlobalInt`(socket 事件分发);socket 接收/连接/断开事件通过 `qdx_port_sock_*_notify` 转发给 QDX 网络层;`qdx_port_net_lock/unlock` 用互斥量保护 WCHNET 调用,防止业务任务和网络任务并发访问
@@ -0,0 +1,48 @@
## 1. 系统总览文档
- [x] 1.1 创建 `Doc/设计文档/系统总览.md`,包含项目背景和硬件平台(MCU、传感器、网络)概述
- [x] 1.2 编写 FreeRTOS 任务拓扑表:四个任务的名称、优先级、栈大小、职责
- [x] 1.3 编写系统启动序列说明,覆盖外设初始化到 vTaskStartScheduler 的完整步骤
- [x] 1.4 编写 2D 状态机流程:IDLE → DEBOUNCE → DELAY → BURST,含触发条件和参数
- [x] 1.5 编写 1D 状态机流程:S1D_IDLE → S1D_DEBOUNCE → S1D_COLLECTING,含停止条件
- [x] 1.6 编写 TEMP_REQ 实时温度请求处理流程(按需单帧下发逻辑)
- [x] 1.7 补充任务间同步机制说明(Frame_Ready_Flag、信号量、帧缓冲双 Buffer 策略)
## 2. DVP 模块设计文档
- [x] 2.1 创建 `Doc/设计文档/DVP模块设计.md`,包含 DVP 硬件连接引脚说明
- [x] 2.2 描述 DVP 时序配置:VSYNC 极性、PCLK 极性、CMOS-8bit 模式
- [x] 2.3 描述 DMA ping-pong 机制:两个 DMA 通道交替接收行数据(512 B/行)
- [x] 2.4 描述 DVP IRQ 处理逻辑:STR_FRM 重置行计数、ROW_DONE 累积行、第 191 行置就绪标志
- [x] 2.5 描述帧缓冲格式:`uint8_t[192][512]` = 256 列 × 2 字节/像素,小端序 uint16_t,单位 0.1°C
- [x] 2.6 描述 TMP 模式像素换算公式(uint16_t × 0.1 = 摄氏度)
## 3. QDX 协议设计文档
- [x] 3.1 创建 `Doc/设计文档/QDX协议设计.md`,描述帧头 FrameHeader_t 各字段含义和长度
- [x] 3.2 描述 TLV 结构:Type(1 B) + Length(2 B, LE) + Value(N B) 及嵌套帧 = FrameHeader + TLV
- [x] 3.3 列出所有帧类型(Class × Type):HANDSHAKE、HEARTBEAT、TEMP_FRAME、CONFIG_COMMON 等
- [x] 3.4 描述零拷贝 TX 方案:TcpTxBuffer 容量 9216 B,HeadOffset=64,帧头在发送前向前写入
- [x] 3.5 描述 TX 分片规则:单 TLV Value 超过 9131 B 时触发分片,Flags.FRAGMENT 置位
- [x] 3.6 描述 Sequence 字段单调递增规则和接收端顺序验证要求
## 4. TCP 通信模块设计文档
- [x] 4.1 创建 `Doc/设计文档/TCP通信模块设计.md`,说明双流架构:控制流(5511)+ 数据流(5512)
- [x] 4.2 描述各套接字专属职责:控制流负责握手/配置/心跳,数据流负责温度帧推送
- [x] 4.3 描述 TCP Keepalive 参数:idle=20000 ms,interval=15000 ms,count=9
- [x] 4.4 描述服务端断线重连机制和连接状态的管理方式
- [x] 4.5 描述配置缓存机制:配置通过控制流接收后缓存,重连后自动恢复
- [x] 4.6 描述 WCHNET 驱动任务(task_wchnet_entry)的轮询周期和优先级要求
## 5. 对接集成指南
- [x] 5.1 创建 `Doc/设计文档/对接集成指南.md`,包含网络接入参数表(IP、端口、协议)
- [x] 5.2 编写握手流程章节:双流连接顺序、HANDSHAKE 帧格式、DevID 验证
- [x] 5.3 编写配置下发章节:Config2D_t 全字段说明和推荐初始值表
- [x] 5.4 编写 1D 配置下发章节:Config1D_t 全字段说明、TriggerType 枚举值
- [x] 5.5 编写温度帧接收章节:2D 矩阵帧解析步骤(像素排列、单位换算)
- [x] 5.6 编写 1D 时序帧接收章节:Sample 结构(4 B:time_lo/hi + temp_lo/hi)解析步骤
- [x] 5.7 编写 DetectionResult 和 NG 输出说明:DetectionResult TLV 字段、NG GPIO(PA8)电平含义
- [x] 5.8 编写 TEMP_REQ 请求方法:主动下发 TEMP_REQ 帧触发单帧返回
- [x] 5.9 编写常见错误码表和对接故障排查步骤
+53
View File
@@ -0,0 +1,53 @@
# dvp-module-design Specification
## Purpose
TBD - created by archiving change software-design-doc. Update Purpose after archive.
## Requirements
### Requirement: DVP 硬件初始化配置描述
文档 SHALL 描述 DVP 外设的完整初始化配置,包含 GPIO 引脚映射、工作模式和信号极性。
#### Scenario: 开发者核查 DVP GPIO 引脚分配
- **WHEN** 开发者进行硬件调试时
- **THEN** 文档 SHALL 提供引脚映射表:PA4/5/6/9/10(数据线 D0-D4)、PC8/9/11(D5-D7 + PCLK)、PB3/8/9(VSYNC/HSYNC/PIXCLK),所有引脚配置为浮空输入
#### Scenario: 开发者理解 DVP 信号极性配置
- **WHEN** 开发者对接不同传感器时
- **THEN** 文档 SHALL 说明:VSYNC 高有效(RB_DVP_V_POLAR=1,对应 DIGITAL_FIELD_VALID 高电平有效帧)、HSYNC 高有效(RB_DVP_H_POLAR=0)、PCLK 上升沿采样(RB_DVP_P_POLAR=0),与 Mini212G2 手册时序图一致
### Requirement: DMA ping-pong 行缓冲机制描述
文档 SHALL 描述 DVP DMA 双缓冲的工作原理,包含缓冲切换逻辑和 IRQ 中的正确读取方式。
#### Scenario: 开发者理解 DMA 缓冲切换逻辑
- **WHEN** 开发者排查行数据乱序问题时
- **THEN** 文档 SHALL 说明:DVP 硬件在 DMA_BUF0/BUF1 间自动切换,ROW_DONE 中断触发时硬件已切换到下一个缓冲;BUF_TOG=1 表示 DMA 正在写 BUF0,此时应读 BUF1(公式:`src = (CR1 & BUF_TOG) ? DMA_LineBuf0 : DMA_LineBuf1`)
#### Scenario: 开发者理解行缓冲大小约束
- **WHEN** 开发者修改传感器分辨率时
- **THEN** 文档 SHALL 说明:DMA_LineBuf0/1 各 512 字节(256 像素 × 2 字节),COL_NUM=512,ROW_NUM=1(每行触发一次 IRQ),修改分辨率需同时更新 `BYTES_PER_LINE`、`SENSOR_WIDTH`、`SENSOR_HEIGHT`
### Requirement: DVP IRQ 帧组装逻辑描述
文档 SHALL 描述 `DVP_IRQHandler` 的完整逻辑,包含帧同步机制和 FrameBuffer 组装方式。
#### Scenario: 开发者理解帧同步锚点
- **WHEN** 开发者排查帧错位问题时
- **THEN** 文档 SHALL 说明:STR_FRM 中断(VSYNC 上升沿)将 `current_line_idx` 清零,此为帧同步唯一锚点;ROW_DONE 中断依次将行数据 memcpy 至 `FrameBuffer[current_line_idx]` 并递增
#### Scenario: 开发者理解帧完成标志
- **WHEN** 开发者需要知道何时帧数据可用时
- **THEN** 文档 SHALL 说明:当 `idx == SENSOR_HEIGHT - 1`(即第 191 行完成)时,`Frame_Ready_Flag` 置 1,`Ready_Frame_Count` 更新为当前帧号;业务任务轮询此标志,读取后将其清零
#### Scenario: 开发者理解 IRQ 使用 fast interrupt 属性的原因
- **WHEN** 开发者修改 IRQ 属性时
- **THEN** 文档 SHALL 说明:`__attribute__((interrupt("WCH-Interrupt-fast")))` 使中断处理跳过寄存器入栈,减少中断延迟,确保在下一行像素时钟到来前完成 memcpy(每行约 42.67µs @ 25Hz)
### Requirement: FrameBuffer 数据格式描述
文档 SHALL 描述 FrameBuffer 的内存布局和像素值含义。
#### Scenario: 开发者访问特定像素的温度值
- **WHEN** 开发者需要读取第 row 行第 col 列的温度时
- **THEN** 文档 SHALL 说明:`FrameBuffer` 声明为 `uint8_t[192][512]`,通过 `(uint16_t*)FrameBuffer` 访问,像素值 = `((uint16_t*)FrameBuffer)[row * 256 + col]`,单位 0.1°C/LSB(TMP 模式,需传感器预配置为 TMP)
#### Scenario: 开发者理解字节序要求
- **WHEN** 开发者移植到大端序平台时
- **THEN** 文档 SHALL 说明:CH32V307 为小端序,`uint8_t[0]` = 低字节,`uint8_t[1]` = 高字节;传感器必须配置为 CMOS8(LSB)(低字节先发),否则温度值字节反序
+62
View File
@@ -0,0 +1,62 @@
# integration-guide Specification
## Purpose
TBD - created by archiving change software-design-doc. Update Purpose after archive.
## Requirements
### Requirement: 对接方网络接入参数说明
文档 SHALL 提供上位机(ConfigServer)与采集端建立 TCP 连接所需的全部参数。
#### Scenario: 对接方配置 TCP Server 监听端口
- **WHEN** 对接方开发服务端程序时
- **THEN** 文档 SHALL 提供:MCU 默认 IP=192.168.7.10,Subnet=255.255.255.0,Gateway=192.168.7.1;Server 需在 192.168.7.50 监听两个端口:5511(控制流,MCU 主动连入)和 5512(数据流,MCU 主动连入);以太网接口为 1000M RGMII
### Requirement: 握手流程说明
文档 SHALL 描述 MCU 上电后的握手过程,使对接方能正确识别采集端设备。
#### Scenario: 对接方接收第一个数据包并识别设备
- **WHEN** MCU 连接后发送握手帧时
- **THEN** 文档 SHALL 说明:MCU 在控制流连接成功后发送 TYPE_HANDSHAKE(Class=CLASS_SYSTEM,含 ProtocolVersion=0x0200、DeviceUUID=MAC 地址、AuthToken=全零);服务器 SHALL 回复握手响应以完成握手;握手完成后 MCU 才开始正常数据上报
### Requirement: 配置下发格式说明
文档 SHALL 描述服务器向 MCU 下发配置的帧格式和所有配置字段含义。
#### Scenario: 对接方配置 2D 触发模式
- **WHEN** 对接方发送 Config2D 配置帧时
- **THEN** 文档 SHALL 提供 Config2D_t 所有字段:Enabled(uint8_t)、TriggerMode(uint8_t, 0=内部温度/1=外部GPIO)、TriggerDebounceIntervalMs(uint16_t)、TriggerDelayMs(uint16_t)、TriggerBurstCount(uint8_t)、TriggerInternalIntervalMs(uint16_t)、TriggerTemperatureThreshold(int16_t, 0.1°C/LSB)、TriggerCondition(uint8_t, 0=Avg/1=Max)、TriggerRoiX/Y/W/H(uint16_t)、TargetWidth/Height(uint16_t)、NGioDelay(uint16_t, ms)
#### Scenario: 对接方配置 1D 采集模式
- **WHEN** 对接方发送 Config1D 配置帧时
- **THEN** 文档 SHALL 提供 Config1D_t 所有字段:Enabled(uint8_t)、RunMode(uint8_t, 0=STOP/1=RUN)、TriggerType(uint8_t, 1=内部/2=外部)、TriggerTempLimit(int16_t)、HighTimerLimit(uint16_t, ms)、NgCountLimit(uint16_t, 帧数)、BufferSize(uint16_t)、LSizeStart/RSizeStart(uint16_t, 切片参数)
### Requirement: 温度帧数据包格式说明
文档 SHALL 描述 MCU 上报的温度帧数据包的完整格式,使对接方能正确解析。
#### Scenario: 对接方解析收到的 2D 温度帧
- **WHEN** 数据流收到 TYPE_TEMP_FRAME 包时
- **THEN** 文档 SHALL 说明:Value 区域含 PreprocessResult 元数据(ValidWidth × ValidHeight 像素数组);像素为 uint16_t little-endian,单位 0.1°C/LSB;元数据含 MaxTemp/MinTemp/AvgTemp/RoiTemp(均 int16_t, 0.1°C/LSB)、ValidWidth/ValidHeight(实际 ROI 尺寸)、FrameNumber
#### Scenario: 对接方解析收到的 1D 温度帧
- **WHEN** 数据流收到 1D TYPE_TEMP_FRAME 包时
- **THEN** 文档 SHALL 说明:is2D=0,每个样本 4 字节:[time_off_lo, time_off_hi, temp_lo, temp_hi],time_offset 为相对采集开始的 ms 偏移(uint16_t),temp 为 uint16_t 0.1°C/LSB
### Requirement: 触发结果上报和 NG 响应机制说明
文档 SHALL 描述采集端如何响应服务器的 DetectionResult 决策和触发 NG 输出。
#### Scenario: 对接方下发检测结果
- **WHEN** 服务器完成图像分析后回传结果时
- **THEN** 文档 SHALL 说明:服务器发送 TYPE_DETECTION_RESULT(含 frameNumber、resultStatus,0=NG/1=OK);MCU 收到 resultStatus=0 时触发 PA8 高电平 NGioDelay ms(默认 200ms);对接方可通过 NGioDelay 配置 NG 输出脉宽
### Requirement: TEMP_REQ 按需截图说明
文档 SHALL 描述服务器如何向 MCU 请求即时截图。
#### Scenario: 对接方请求单帧截图
- **WHEN** 服务器需要调试或核查当前热场时
- **THEN** 文档 SHALL 说明:控制流发送 TYPE_CONFIG_COMMON 或专用 TEMP_REQ 命令(含 is2dRequest 字段);MCU 将在下一个业务循环发送当前最新帧,2D 返回 ROI 裁切后温度矩阵,1D 返回中心行 30 个等间距采样点;仅在对应模式已 Enabled 时响应
### Requirement: 错误码和异常处理说明
文档 SHALL 列出协议层所有错误码含义及对接方应采取的处理措施。
#### Scenario: 对接方收到 ERR 响应帧
- **WHEN** 服务器发送格式错误的配置帧时
- **THEN** 文档 SHALL 列出错误码含义:ERR_CRC(0x1001)=CRC 校验失败、ERR_VERSION(0x1002)=协议版本不匹配、ERR_LENGTH(0x1003)=帧长度异常、ERR_AUTH(0x2001)=认证失败、ERR_BUSY(0x2002)=设备忙、ERR_PARAM(0x3001)=参数非法;收到错误码后对接方 SHALL 检查发送的帧格式后重试
@@ -0,0 +1,41 @@
# qdx-protocol-design Specification
## Purpose
TBD - created by archiving change software-design-doc. Update Purpose after archive.
## Requirements
### Requirement: TLV 帧结构完整描述
文档 SHALL 描述 QDX 协议的完整帧结构,包含帧头各字段含义、TLV 格式和帧尾 CRC。
#### Scenario: 开发者手动构造一个协议帧
- **WHEN** 开发者需要调试发送内容时
- **THEN** 文档 SHALL 提供帧结构:[FrameHeader 16B] + [TLV_Header 3B] + [Value NB] + [CRC16 2B],其中 FrameHeader = {Magic(2)=0x55AA, Version(1)=0x20, Length(2), Sequence(2), Timestamp(4), Source(1), DevID(2), Class(1), Flags(1)}
#### Scenario: 开发者理解 Class 和 TLV Type 的对应关系
- **WHEN** 开发者解析收到的帧时
- **THEN** 文档 SHALL 列出完整的 Class/Type 映射表:CLASS_CONTROL(0x01)、CLASS_DATA(0x02)、CLASS_RESPONSE(0x03)、CLASS_SYSTEM(0x04);Type 包含 TYPE_HANDSHAKE(0x01)、TYPE_HEARTBEAT(0x02)、TYPE_TEMP_FRAME(0x10)、TYPE_CONFIG_COMMON(0x20)、TYPE_CONFIG_2D(0x22)、TYPE_CONFIG_1D(0x23)、TYPE_ACK_PAYLOAD(0x30)、TYPE_DETECTION_RESULT(0x40) 等
### Requirement: 零拷贝 TX 缓冲区架构描述
文档 SHALL 描述 TcpTxBuffer_t 的双缓冲零拷贝发送架构和 HeadOffset 的使用方式。
#### Scenario: 开发者理解零拷贝的实现方式
- **WHEN** 开发者需要在减少内存拷贝的前提下添加新的帧类型时
- **THEN** 文档 SHALL 说明:`TcpTxBuffer_t` 包含 pBuffer(9216B)、HeadOffset(64B)、ValidPayloadLen;图像数据由预处理模块写入 `pBuffer + HeadOffset` 开始的位置;`TcpLogic_BuildAndSendTemperatureFrame` 在 HeadOffset 前的 64 字节内直接写入帧头(FrameHeader + TLV),**无需额外 memcpy**
#### Scenario: 开发者计算单次可发送的最大像素数
- **WHEN** 开发者调整 ROI 大小时
- **THEN** 文档 SHALL 说明:有效载荷容量 = TotalCapacity(9216) - HeadOffset(64) - CRC(2) - TLV_Header(3) - FrameHeader(16) = 9131 字节,每像素 2 字节,最多 4565 个像素(约 67×67 ROI)
### Requirement: 分片机制描述
文档 SHALL 描述协议层的分片上限和分片标志用法。
#### Scenario: 开发者发送超大载荷时
- **WHEN** 开发者发送超过 MAX_FRAGMENT_PAYLOAD(1400B) 的数据时
- **THEN** 文档 SHALL 说明分片最大载荷为 1400B(受 TCP MSS=1460 限制),大帧通过 FLAG_LAST_FRAGMENT(0x20) 标志标识末片;当前 TX 缓冲区为 9216B,单次发送通常不超过此限制
### Requirement: Flags 字段用法描述
文档 SHALL 描述 FrameHeader.Flags 各位的含义和当前固件的使用情况。
#### Scenario: 开发者解析收到的 Flags 字段
- **WHEN** 上位机解析帧时
- **THEN** 文档 SHALL 说明:FLAG_PRIORITY_MASK(0x03)=优先级(0-3)、FLAG_COMPRESSED(0x04)=压缩(当前未使用)、FLAG_ENCRYPTED(0x08)=加密(当前未使用)、FLAG_ACK_REQ(0x10)=需要 ACK、FLAG_LAST_FRAGMENT(0x20)=末片标志
+60
View File
@@ -0,0 +1,60 @@
# system-overview Specification
## Purpose
TBD - created by archiving change software-design-doc. Update Purpose after archive.
## Requirements
### Requirement: FreeRTOS 任务拓扑描述
文档 SHALL 列出所有 RTOS 任务的名称、优先级、栈大小、职责及任务间通信方式。
#### Scenario: 开发者查阅任务优先级
- **WHEN** 开发者需要了解任务调度顺序时
- **THEN** 文档 SHALL 提供任务优先级表,包含:task_wchnet(优先级 6,512 字)、task_business(优先级 5,512 字)、task_heartbeat(优先级 3,256 字)、task_test_pattern(优先级 4,256 字,仅 TEST_PATTERN_MODE=1 时存在)
#### Scenario: 开发者理解任务间数据流
- **WHEN** 开发者需要理解 DVP → 业务任务的数据传递时
- **THEN** 文档 SHALL 说明通过 `Frame_Ready_Flag`(volatile 标志)和 `FrameBuffer`(共享内存)传递帧数据,IRQ 置位,业务任务轮询消费
### Requirement: 系统启动序列描述
文档 SHALL 描述 `main()` 的初始化顺序,涵盖所有外设和模块的初始化步骤及其依赖关系。
#### Scenario: 开发者定位初始化顺序问题
- **WHEN** 开发者遇到启动相关 bug 时
- **THEN** 文档 SHALL 提供启动序列:SystemClock → USART3/debug → Flash/SRAM 配置(128K+192K)→ DVP_Init → TIM2_Init → ExtTrigger_GPIO → NG_GPIO → ETH_LibInit → qdx_port_init → Preprocess_Init → TcpLogic_Init → 注册回调 → TcpLogic_Start → 创建 RTOS 任务 → vTaskStartScheduler
### Requirement: 2D 状态机完整描述
文档 SHALL 描述 2D 触发状态机的所有状态、转换条件和行为,包含外部触发和内部触发两种模式。
#### Scenario: 开发者理解 2D 外部触发流程
- **WHEN** 开发者排查外部触发抖动问题时
- **THEN** 文档 SHALL 描述:IDLE → [PA15 上升沿] → DEBOUNCE(等待 DebounceIntervalMs) → DELAY(等待 TriggerDelayMs) → BURST(发 BurstCount 帧,间隔 TriggerInternalIntervalMs) → IDLE
#### Scenario: 开发者理解 2D 内部触发流程
- **WHEN** 开发者配置温度阈值触发时
- **THEN** 文档 SHALL 描述:每帧调用 `Preprocess_CheckInternalTrigger2D`,在 TriggerRoi 区域内 Max/Avg 超过 TriggerTemperatureThreshold 时触发,跳过 DEBOUNCE 直接进入 DELAY → BURST
#### Scenario: 开发者理解双缓冲 TX 逻辑
- **WHEN** 开发者排查发送顺序问题时
- **THEN** 文档 SHALL 说明 `use_buffer_A` 标志在每次发送时取反,g_TxNetBuffer_A / g_TxNetBuffer_B 交替使用,避免前一帧发送未完成时被覆盖
### Requirement: 1D 状态机完整描述
文档 SHALL 描述 1D 采集状态机的所有状态、转换条件、采集逻辑和发送条件。
#### Scenario: 开发者理解 1D 外部触发流程
- **WHEN** 开发者配置 TriggerType=2 时
- **THEN** 文档 SHALL 描述:S1D_IDLE → [PA15 上升沿] → S1D_DEBOUNCE(等待 HighTimerLimit ms) → S1D_COLLECTING(采集 temp+time 样本直到停止条件)→ 发送 → S1D_IDLE
#### Scenario: 开发者理解 1D 内部触发流程
- **WHEN** 开发者配置 TriggerType=1 时
- **THEN** 文档 SHALL 描述:S1D_IDLE 中维护 3 帧滑动窗口,连续 3 帧帧最大温度 ≥ TriggerTempLimit 时进入 S1D_COLLECTING;停止条件:样本数达 BufferSize 或触发后连续 NgCountLimit 帧低温
#### Scenario: 开发者理解 1D 数据格式
- **WHEN** 开发者解析 1D 数据时
- **THEN** 文档 SHALL 说明每个样本 4 字节:[time_offset_lo, time_offset_hi, temp_lo, temp_hi],time_offset 为相对采集开始的 ms 偏移,temp 为 0.1°C/LSB 的 uint16_t
### Requirement: TEMP_REQ 辅助通道描述
文档 SHALL 描述服务器按需截图(TEMP_REQ)的触发流程和限制条件。
#### Scenario: 开发者理解 TEMP_REQ 工作方式
- **WHEN** 服务器发送 TEMP_REQ 命令时
- **THEN** 文档 SHALL 说明:`g_temp_req_pending` 置位,业务任务在下次循环读取当前 FrameBuffer 发送,is2D=1 走 Preprocess_Execute + 2D 封包,is2D=0 走 send_1d_snapshot(30 个等间距采样点);仅在对应模式 Enabled 时响应
+48
View File
@@ -0,0 +1,48 @@
# tcp-module-design Specification
## Purpose
TBD - created by archiving change software-design-doc. Update Purpose after archive.
## Requirements
### Requirement: 双流连接架构描述
文档 SHALL 描述控制流(5511)和数据流(5512)的职责分工、连接方式和状态管理。
#### Scenario: 开发者理解双流设计意图
- **WHEN** 开发者排查连接问题时
- **THEN** 文档 SHALL 说明:控制流 srcport=5511(MCU 主动连接 Server),用于握手、配置下发、心跳、TEMP_REQ、DetectionResult 上报;数据流 desport=5512(MCU 主动连接 Server),用于温度帧数据上报;两流独立管理,数据流断开不影响控制流
#### Scenario: 开发者理解 TCP 连接建立时序
- **WHEN** 开发者排查首次握手失败时
- **THEN** 文档 SHALL 说明:`TcpLogic_Start` 派生后台连接状态机,先尝试控制流连接 → 连接成功后发送 TYPE_HANDSHAKE(含 DeviceUUID=MAC地址、AuthToken=NULL)→ 收到服务器握手响应后标记连接就绪 → 同步尝试数据流连接
### Requirement: 心跳机制描述
文档 SHALL 描述心跳帧的发送周期、TCP Keepalive 配置和连接保活策略。
#### Scenario: 开发者调整心跳参数
- **WHEN** 网络中间件(NAT/防火墙)超时断连时
- **THEN** 文档 SHALL 说明:应用层心跳 TYPE_HEARTBEAT 由 TcpLogic 内部定时发送;TCP Keepalive 配置:空闲 20 秒(`idle=20000ms`)后开始探测,每次间隔 15 秒(`interval=15000ms`),最多 9 次(`count=9`)探测无响应则断链重连
### Requirement: 配置下发与缓存机制描述
文档 SHALL 描述服务器配置的接收、缓存和通知流程。
#### Scenario: 开发者追踪配置更新流程
- **WHEN** 服务器下发配置后行为未按预期改变时
- **THEN** 文档 SHALL 描述:服务器发送 TYPE_CONFIG_COMMON + TYPE_CONFIG_2D + TYPE_CONFIG_1D → TcpLogic 解析并缓存至内部 shadow 寄存器 → 触发 ConfigUpdateCallback(`OnConfigUpdate`)→ 回调内调用 `Preprocess_Settings_Change` 更新预处理参数;`TcpLogic_GetLatestConfig` 可随时读取最新配置副本
#### Scenario: 开发者理解无配置时的默认行为
- **WHEN** 设备启动后服务器尚未下发配置时
- **THEN** 文档 SHALL 说明:`TcpLogic_GetLatestConfig` 返回 -1,业务任务跳过 2D/1D 处理,仅响应 TEMP_REQ(若有);默认 burst 参数 DEFAULT_BURST_COUNT=3、DEFAULT_BURST_INTERVAL_MS=200ms 作为 fallback
### Requirement: 数据发送队列和背压处理描述
文档 SHALL 描述温度帧发送的队列机制和发送失败时的处理策略。
#### Scenario: 开发者排查数据帧丢失问题
- **WHEN** 网络繁忙时出现帧丢失时
- **THEN** 文档 SHALL 说明:`TcpLogic_BuildAndSendTemperatureFrame` 返回 0 表示成功入队,返回 <0 表示发送失败(队列满或连接断开);当前固件对发送失败仅打印 DBG_ERR,不重试;双缓冲 TX 保证当前帧被入队时,下一帧可立即写入另一个缓冲
### Requirement: WCHNET 网络栈驱动任务描述
文档 SHALL 描述 task_wchnet 的职责和与 WCHNET 库的交互方式。
#### Scenario: 开发者理解网络栈如何被驱动
- **WHEN** 开发者排查网络响应迟缓问题时
- **THEN** 文档 SHALL 说明:`task_wchnet_entry` 每 5ms 轮询一次,调用 `WCHNET_MainTask`(协议栈心跳)和 `WCHNET_HandleGlobalInt`(socket 事件分发);socket 接收/连接/断开事件通过 `qdx_port_sock_*_notify` 转发给 QDX 网络层;`qdx_port_net_lock/unlock` 用互斥量保护 WCHNET 调用,防止业务任务和网络任务并发访问