111
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-03-13
|
||||
@@ -0,0 +1,29 @@
|
||||
## Context
|
||||
|
||||
目前的系统已经具备了以太网 TCP Socket 基础和 DVP+DMA 红外数据矩阵的采集能力。然而主程序目前仅仅是将 DVP 采集到的流进行无差别循环上报,没有执行复杂的预处理逻辑。
|
||||
根据给定的架构设计文档 (`CH32二维运行结构概览.md` 与 `函数调用指南.md`),我们需要:
|
||||
1. 导入由第三方或算法工程师提供的闭源/封装好的预处理算法库 (`Preprocess_`) 和底层 TCP 控制流协议封装 (`TcpLogic_`)。
|
||||
2. 废弃当前无差别的整帧暴力上传阻塞逻辑。
|
||||
3. 利用 `TcpTxBuffer` 的带有 offset 缓冲池机制实现零拷贝的网络流装配上传。
|
||||
4. 提供上位机参数回调和错误处理功能(如通过 `TcpLogic_RegisterConfigCallback` 和 NG 控制逻辑)。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 在 `main.c` 和 `dvp.c` 中成功注册、初始化并接入 `Preprocess_xxx` 与 `TcpLogic_xxx` 的 API 生命周期。
|
||||
- 实现一个不产生内存额外拷贝 (Zero-Copy) 的缓冲区数据流,由预处理根据特定感兴趣区域截取有效温度点后,送入 TCP 模块利用预留位添加封包帧头发出。
|
||||
- 加入上位机动态热更新配置和外部气缸硬件IO回调处理。
|
||||
|
||||
**Non-Goals:**
|
||||
- 具体的红外滑窗滤波或 TCP 报文组装的底层逻辑编写(这部分属于已封装库,只做 API 调用层面的业务整合)。
|
||||
|
||||
## Decisions
|
||||
|
||||
- **API 包装策略**: 为了避免 DVP 中断卡死主线程流,将 DVP 完成一帧(软触发)的逻辑校验放到业务主循环 `main` 之内。DVP 中断仅仅传递 `Line_Ready_Flag` 或全局的缓冲区双指针结束标志给主循环去执行高耗时的 `Preprocess_CheckInternalTrigger2D` 操作。
|
||||
- **内存池预分配模型**: 在全局申请两个支持偏移量设定的发送大缓存 (`TcpTxBuffer_t`) 并常驻内存,确保网络封装只需向 Buffer 首部写入 TLV 标头而无需搬运大块图像数据。
|
||||
- **配置与剔除反馈同步**: 所有与上位机的异步通信指令解析都由 `TcpLogic` 完成,主程序在此阶段只需挂载好 callback 并使用 `volatile` 配置影寄存器或标志位与主循环交互即可。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Risk] 零拷贝模型的数组越界风险 → 确保 `Preprocess` 的目标裁断 Buffer 的尺寸 > (`Target Width*Height*2 + HeadOffset`) 且首字节地址分配精确。
|
||||
- [Risk] DMA 和 主循环取图并发导致冲突 (Tearing) → 要求 DVP 在更新下一帧时利用乒乓机制避免同址同时写读,主逻辑处理时需进行资源锁屏。
|
||||
@@ -0,0 +1,25 @@
|
||||
## Why
|
||||
|
||||
当前 CH32V30x 项目已经实现了基础的 ETH 和 DVP DMA 数据采集,但缺乏核心的业务逻辑运转。根据《CH32二维运行结构概览》和《函数调用指南》,我们需要将采集到的原始图像数据进行“掩膜过滤 - 滑窗极值捕捉 - 预处理裁切”,然后通过自定义的 TCP 栈进行零拷贝封装与双流(5511控制流、5512数据流)通信,形成完整的闭环机制。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 引入并使用 `Preprocess_` 相关 API 进行内部软触发判定与数据裁切(滑窗算法)。
|
||||
- 引入外部分配缓冲内存池 `TcpTxBuffer_t`。
|
||||
- 修改主循环/中断,加入触发判断。
|
||||
- 采用 `TcpLogic_` 库提供的封包方法替换现有的普通 TCP 发送。
|
||||
- 加入上位机动态参数热更新的更新回调 `TcpLogic_RegisterConfigCallback` 机制和 NG 外部继电器 (DO) 控制逻辑。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `image-preprocess-filter`: 处理红外传感器捕获画面的掩膜过滤、滑动窗口平均温极值捕捉以及零拷贝剪裁提取。
|
||||
- `tcp-stream-logic`: 控制流(5511)与数据流(5512)管理、重连、TLV 封包与零拷贝发送,及热更新回调注册等功能。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
## Impact
|
||||
|
||||
- 受影响的文件主要在主应用层:`prj/TCPClient/User/main.c` (调度流血重构)。
|
||||
- 内存分配策略改变(需要保留 `HeadOffset` 并在全局开辟外部分配预留池)。
|
||||
- 依赖网络基础模块提供的 `qdx_port_tcp_send` 接口和硬件 IO 库(若要驱动剔除气缸/报警灯)。
|
||||
@@ -0,0 +1,15 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Matrix triggering via Preprocess library
|
||||
系统必须能够在主循环中捕获到 DVP 采集到的满帧,并将图像缓冲(按照 `RawImageBuffer_t` 结构体规范)投喂给 `Preprocess_CheckInternalTrigger2D` 以判断是否满足内部的高温触发标准。
|
||||
|
||||
#### Scenario: Full frame is captured and inspected
|
||||
- **WHEN** DVP 产生满帧完成标志位并被主程序获取时
|
||||
- **THEN** 单片机将调用触发函数,并在命中时冻结该目标帧缓冲阻隔覆盖。
|
||||
|
||||
### Requirement: Zero-Copy cropping algorithm extraction
|
||||
利用前向保留(Offset)特性规划的缓冲池(`TcpTxBuffer_t`),将锁定的被触发二维矩阵图像原始数据通过 `Preprocess_Execute` 去掉无关低温部分后提取并原样写入缓冲有效区域内。
|
||||
|
||||
#### Scenario: Sub-frame extracting with proper length
|
||||
- **WHEN** 图像完成触发并执行截断输出操作时
|
||||
- **THEN** `PreprocessResult_t` 中的统计结果将被正确填充,且目标数据只在 `pBuffer + HeadOffset` 开始出现,不在内存间产生额外拷贝拖死中断。
|
||||
@@ -0,0 +1,26 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Independent Twin-Port connection tracking
|
||||
必须引入并运用 `TcpLogic_Start` 抽象接管双端口(5511, 5512) TCP 栈的心跳维持与发包等工作。不再直接向 CH32 WCHNET Socket 原口写入业务。
|
||||
|
||||
#### Scenario: Business TCP tasks initialize and start
|
||||
- **WHEN** main 函数结束物理层网卡 ETH Setup 之后
|
||||
- **THEN** 调用 `TcpLogic_Init` 并传入 UUID 开启内部监控服务,随后的状态流转由库自动接管。
|
||||
|
||||
### Requirement: Offset-based direct packetization
|
||||
调用 `TcpLogic_BuildAndSendTemperatureFrame` 获取带偏移量的截断目标发送缓冲 `TcpTxBuffer_t`。由库在头部(`HeadOffset`)安全组装 TLV 等标头进而发送到 5512 端口发出。完全消除向以太网 Socket 递送前的高耗时大范围 Memcpy 拼包。
|
||||
|
||||
#### Scenario: Sub-frame sent efficiently after processed
|
||||
- **WHEN** 触发的图像提取阶段完成后提交至 TCP 管理模块
|
||||
- **THEN** 系统通过位运算写入帧头与校验位,在指定字节空间内原地打包并最终推入以太网发送缓冲区。
|
||||
|
||||
### Requirement: Remote Parameters updating via callbacks
|
||||
必须注册实现监听由上位机下发的配置动作以及废料剔除等行为(基于 `ConfigUpdateCallback_t` 和 `DetectionResultCallback_t` 句柄),让这批回调充当系统动态控制信号输入源。
|
||||
|
||||
#### Scenario: Update Triggering config on the fly
|
||||
- **WHEN** 通过 5511 端口收到控制主机的有效组包设置参数报文时
|
||||
- **THEN** 主程序的事件机制会触发,自动更新 `Config2D_t` 结构体并通过 `Preprocess_Settings_Change` 影响处理流。
|
||||
|
||||
#### Scenario: NG defect removal trigger by Host
|
||||
- **WHEN** 上台判别系统对某帧评估失败(NG)并发回报错标志包时
|
||||
- **THEN** `OnHardwareReject` 回调函数被触发并让设定的 DO GPIO 电平翻转以排废。
|
||||
@@ -0,0 +1,19 @@
|
||||
## 1. 原网络及采集链路调整与重构
|
||||
|
||||
- [ ] 1.1 在 `prj/TCPClient/User/main.c` 中删除或注释掉陈旧的一般 TCP 阻塞式轮询测试发送代码/函数。
|
||||
- [ ] 1.2 在全局预分配 2 个带偏移量预留空间的网络封包静态池结构 `TcpTxBuffer_t`。
|
||||
- [ ] 1.3 移除 DVP 中断或其附带任务中直接封包或打印大量数据的行为,只保留 `Line_Ready_Flag` 或向外吐出可用 Buffer 的指针指示功能。
|
||||
|
||||
## 2. 图像预处理流水线接入
|
||||
|
||||
- [ ] 2.1 在 `main` 初始化中添加 `Preprocess_Init` 例程并配置默认的二维参数最大宽高。
|
||||
- [ ] 2.2 在主循环里,当获取到一完整帧缓存后,包装成 `RawImageBuffer_t`。
|
||||
- [ ] 2.3 调用 `Preprocess_CheckInternalTrigger2D` 进行掩膜触发扫描校验,如果返回值验证被触发通过(1),进入提取分支,否则略过。
|
||||
- [ ] 2.4 在触发分支内应用被锁定的物理 Frame 内存和空闲的一侧 `TcpTxBuffer`,调用 `Preprocess_Execute` 零拷贝执行滑窗提取操作获取有效数据负载与温度统计极值。
|
||||
|
||||
## 3. TCP 协议接管与外部交互
|
||||
|
||||
- [ ] 3.1 在 `main` 初始化网卡层等底层网络完成后,调用 `TcpLogic_Init` 和 `TcpLogic_Start`。
|
||||
- [ ] 3.2 定义系统被上位机修改参数时的回调 `ConfigUpdateCallback_t`,在其内部联级调用 `Preprocess_Settings_Change` 来影响全局阈值。
|
||||
- [ ] 3.3 定义接收上位机检测下发判断的 `DetectionResultCallback_t`,预留好对某一设定 GPIO 口拉高(作为报警/废品剔除气缸动作)响应函数。
|
||||
- [ ] 3.4 经过 `Preprocess_Execute` 获取到的有效内容数组,作为参量通过调用 `TcpLogic_BuildAndSendTemperatureFrame` 执行偏移组包完成以太网 DMA 数据包压入队列工作。
|
||||
Reference in New Issue
Block a user