This commit is contained in:
2026-03-13 22:22:45 +08:00
parent 2cdb65309f
commit ea4368bf15
19 changed files with 28899 additions and 0 deletions
Binary file not shown.
+25589
View File
File diff suppressed because it is too large Load Diff
+274
View File
@@ -0,0 +1,274 @@
# Page 1
⼆维运⾏结构概览
CH32
版本:
V1.1
更新说明 :更新系统架构图
概述
1.
本⽂档旨在描述运⾏于 CH32 单⽚机上的核⼼业务逻辑和软件架构。系统屏蔽了底层的硬件驱动细节,
主要聚焦于单⽚机端的业务流转和数据处理。整个系统由采集、处理、发送三⼤核⼼模块组成,并辅以
TCP 协议栈库和动态参数配置功能,以确保系统在⾼性能要求下稳定⾼效地运⾏。
系统核⼼架构
2.
系统整体基于数据流驱动,涵盖了从图像帧获取到最终⽹络传输的完整⽣命周期。
# Page 2
外部物理
相机接⼝
硬件接⼝
单⽚机端系统架构
业务核⼼层
DI 传感器 采集与 DMA 连续轮询
电平跳变缓冲 满帧就绪事件
每满帧触发的 DMA 处理
Loop
外部 IO 状态缓冲 触发模式配置
有效电平指令 外部硬触发模式
内部软触发模式
待下⼀帧 外部触发等待模块 内部软触发判定模块
信号跳变读取历史 单帧掩膜嗅探达标
锁定事件帧 ⽆跳变 未达标
交付绝对控制权
预处理提取模块 丢弃 动态切换_触发设定
安全热更新_触发阈值与ROI 零拷⻉有效数据负载
打包与发送模块
安全热更新_
⼨
裁剪位置与尺
调⽤ Send API (5512)
⽹络与底层传输层
调整发送策略 TCP 协议栈库
以太⽹/Wi-Fi TCP 报⽂
触发 Recv 回调 (5511)
参数管理与控制模块 上位机 ConfigServer
收到 NG 检测结果
硬件 IO 交互边界
定时驱动模块
发出维持延迟⾼电平
DO ⽓缸/报警灯
核⼼功能模块详细设计
3.
采集模块
3.1
定位:底层硬件和信号抽象。
职责:负责与相机进⾏物理通信。对单⽚机其他业务代码⽽⾔,它是⼀个完全解耦的⿊盒。
业务对接机制:采集模块内部⾃⾏处理相机通信、触发延时、DMA采集等。每完成⼀帧的采集,模
块会将数据转化为统⼀的⼆维整数矩阵(Integer Matrix),存⼊单⽚机内存的环形缓冲区,并通过
软中断、回调函数或信号量通知预处理模块接管数据。
# Page 3
内部软触发判定模块(核⼼控制块)
3.2
定位:轮询模式下的事件嗅探器。
职责:在内部触发( TriggerMode = 0 )模式下,⾼频处理由底层 DMA 源源不断抛出的完整原始测
温满帧,判断并锁定有效⽬标进⼊画⾯的“瞬间”。
⼯作机制:
i. ⾼速嗅探:每收到⼀帧满帧,⽴即调⽤ Preprocess_CheckInternalTrigger2D API 快速浏览预
设的触发感兴趣区域 (Trigger ROI)。这避免了对⽆需关注的⽆⽬标区域进⾏毫⽆意义的算⼒浪
费。
ii. 掩膜嗅探:运⽤设定的温度阈值将低温背景瞬间剥除,并迅速计算出该⼩格 ROI 内部的最⾼温
度或平均温度。
iii. 定格:当发现温度满⾜判定条件时,⽴刻向主控系统反馈命中信号(返回 1),主控随即接管该
帧缓冲区的绝对控制权(防⽌它被后续 DMA 盲⽬轮询覆盖),将其确认为事件起点帧(第 0
帧),推⼊下⼀级的数据裁剪与提取阶段,并开启定时连拍。
预处理与提取模块(核⼼业务块)
3.3
定位:数据加⼯、过滤清洗与裁剪提炼。
职责:接收整数矩阵,并根据当前的算法参数(如过滤阈值
TriggerTemperatureThreshold
、⽬标
尺⼨
TargetWidth * TargetHeight
)进⾏滑动滤波和坐标锁定。
核⼼处理逻辑(温度过滤与最⼤均温滑动计算):
i. 温度过滤预处理:识别出低于阈值的像素,在计算中视作默认低温值(如 90,即9.0°C),保
留⾼于等于阈值的像素原始温度参与计算。
ii. 滑动窗⼝计算:通过列累加和向右滑动窗⼝(加右侧新列减左侧旧列),快速计算⼆维矩阵内
连续
TargetWidth * TargetHeight
区域的总和(即平均温度)。
iii. 位置锁定:在预设或受控范围(如 ROI)内记录总和最⼤值的起始坐标 (X, Y) ,这即是触发
帧的最佳裁剪位置。
iv. 零拷⻉极速搬运:基于锁定好的坐标 (X, Y) ,从原始环形缓冲区中原样提取出这块
TargetWidth * TargetHeight
的未被修改过的真实测温有效像素。直接填⼊外部提供的已经偏
移好的⽹络打包内存中。
执⾏流程:
# Page 4
收到新帧就绪信号
获取当前帧⼆维数组指针
是否开启内部触发判定?
是
否(外部硬触发) 计算触发ROI内的最⾼/均温
达标 未触发
读取匹配参数: 阈值与⽬标
丢弃退出
尺⼨
温度阈值过滤计算_仅⽤于
统计寻优
执⾏窗⼝滑动累加与最⼤均
温计算
# Page 5
锁定最优坐标 X, Y
根据 X, Y 裁剪提取原汁原味
的未处理像素矩阵
附带正确极值统计信息⽣成
结果
⽆缝移交⽹络 TCP 组包零拷
⻉发送
打包与发送模块(核⼼业务块)
3.4 TCP
定位:基于 TCP Raw Stream 2.0 协议的应⽤层通信封装、链路管理与调度引擎。
主要功能总结:
i. 双流管理与主动连接:采⽤“采集端主动连接,上位机被动监听”模式,解决 IP 不固定的问题。
系统维护两个独⽴的 TCP ⻓连接以实现控制与数据解耦:
控制流 (Port 5511):⽤于配置下发、指令控制与⼼跳维护。
数据流 (Port 5512):专属⽤于⾼频温度数据(如 TemperatureFrame_t)的实时上报。
ii. ⾝份握⼿与动态绑定:连接建⽴后发送⾸包进⾏握⼿(Handshake),携带硬件 UUID。⽀持服
务端对逻辑设备 ID (DevID) 的冲突检测和动态重新分配,保证多设备并发下的正确识别。
iii. 数据封装与打包:按照 2.0 ⼩端序规范,将业务数据封装为 TLV(Type-Length-Value)结构。
⾃动在其外侧包裹核⼼帧头(包含
Magic标识(0x55AA)
、序列号、时间戳、载荷属性等)以及
尾部的
CRC16
校验和。
iv. 可靠性传输机制:
重传与确认:针对控制指令和握⼿实施 ACK 确认与重传。
⼤包分⽚ (Fragmentation):当业务载荷超过 MTU/分⽚最⼤限制时,⾃动进⾏序列分⽚
传输,以确保⽹络利⽤率。
v. 链路诊断与恢复:维持周期⼼跳机制(Keep-Alive)具备超时判定功能;在遭遇断⽹或对端重
置后,可执⾏指数退避式的⾼容忍度重连,并⾃动重启握⼿绑定流程。
执⾏流程概览:
# Page 6
应⽤层触发通信
消息类型分类
业务数据上报
按 TLV 封装并定位⾄ 5512
⼼跳/响应/状态
数据流
载荷是否⼤于允许的单次发 按 TLV 封装并定位⾄ 5511
送上限? 控制流
否
是
执⾏⼤包分⽚
⽣成完整数据包
Fragmentation
附加 FrameHeader 与
CRC16 校验帧
# Page 7
CRC16 校验帧
调⽤底层 TCP 协议栈对应
Socket 发送接⼝
参数更改模块(控制业务块)
3.5
定位:系统的“神经中枢”与配置通道。
职责:解析基于 TCP 连接传来的上位机控制指令,动态修改单⽚机的⼯作⾏为及参数(如:预处
理阈值,⽹络打包频率等),⽽⽆需复位单⽚机。
执⾏流程:
i. 解析:TCP 栈触发接收回调,提取载荷中的指令码及配置数据。
ii. 校验:检查数据的合法性。
iii. 应⽤:使⽤原⼦操作或影⼦寄存器(Shadow Buffer)机制更新全局参数结构体,确保正在进
⾏图像处理的流⽔线不会因为参数中途突变⽽导致指针越界或计算崩溃。
iv. 回执:向客⼾端回传 ACK 包,告知参数修改⽣效。
硬件 与触发反馈模块(交互边界)
3.6 IO
定位:处理与外部硬件的物理数字电平交互(DI/DO),连接“触发动作”与“剔除执⾏”。
职责与⼯作机制:负责实时响应外部脉冲输⼊或程序内部事件,并能根据⽹络判定结果执⾏动作以
控制外部设备。
① 触发采集机制(影响⼯作流起点)
采集流⽔线的启动⽅式严格受触发模式配置参数的影响:
1. 外部触发 (External Trigger):
⾏为逻辑:系统实时监听预设的 DI 触发引脚(例如:接收光电传感器的输⼊)。当检测到有效
电平变化,并在通过设定的消抖滤波间隔 ( TriggerDebounceIntervalMs ) 确认信号稳定后,视
为正式触发。
影响:系统在经历特定的触发延时后,命令采集模块连续捕捉设定的张数
( TriggerBurstCount )。只有被这批动作捕捉到的⼆维矩阵数据才会进⼊预处理与 TCP 发送队
列。⾮触发状态下,系统处于待机且不产⽣多余计算和⽹络流量。
2. 内部触发 (Internal Trigger / 轮询阈值触发):
⾏为逻辑:采集模块通过底层 DMA 持续不间断地循环向单⽚机缓冲内存区抛出测温画⾯。主
程序每收到⼀帧,都会调⽤ Preprocess_CheckInternalTrigger2D 进⾏轻量级的 ROI 温度计算
嗅探。
# Page 8
算法双轨制设计:(核⼼重点) ⽆论是触发嗅探还是后续的截取寻优,系统都会使⽤配置的恒
定底噪温度(如 9.0℃)掩盖低温像素。但最终打包进⽹络的数据与统计报告(最⾼/最低/平均
温)必须是原汁原味、从未被过滤过的测温像素。这种分离设计既保证了单⽚机极速抓取⽬标
的抗⼲扰能⼒,⼜避免了上位机 AI 模型因收到修改过的纯⾊背景图⽽发⽣误判。
影响:⼀旦⽬标进⼊画⾯,触发算法判定达标,系统会⽴刻“锁定”该帧所在缓冲区(防⽌被
DMA 再次覆盖),确认其为事件起点帧(第0帧),并在提取发出后稳定连拍指定的定格张数。
内部触发 (基于轮询) ⾏为动作图:
硬件采集/DMA 单⽚机主循环 Preprocess模块
loop [每⼀帧采集完成]
推送当前帧 (Raw Buffer)
1. Preprocess_CheckInternalTrigger2D()
在 TriggerRoi 内执⾏(掩膜过滤 + 极值判定)
alt [判定未触发 (< Threshold)]
返回 0 (丢弃)
解锁缓冲让下⼀次 DMA 覆盖
[判定触发 (>= Threshold)]
返回 1 (锁定⽬标)
记录本帧为 [事件第0帧], 锁定缓冲
2. Preprocess_Execute()
全范围滑窗寻优 + 原样零拷⻉提取
TcpTxBuffer 组装完毕
开启定时连拍并推送到⽹络发送队列
硬件采集/DMA 单⽚机主循环 Preprocess模块
# Page 9
② ⾃动剔除与报警输出机制 驱动机构
( )
本架构⽀持全链路防错的闭环响应机制,将上位机的智能分析结果迅速转译为实际动作:
接收判定 (触发下发):TCP 接收任务(控制流)收到来⾃主机的特定结果回调封包(如
DetectionResult_t 宣告当前帧检测失败/缺陷,即 Result == 1 / NG)。
执⾏输出 (DO 直接驱动):
i. 识别到 NG,系统内部回调会⽴即响应,拉⾼预先配置的 DO 输出引脚(对应⽣产流⽔线的废
料剔除⽓缸、拨⽚或是声光报警装置)。
ii. 系统内部开启定时器,维持该⾼电平动作状态 NGioDelay 毫秒时⻓,这确保了较慢的机械分拨
机构能吃满⾏程去推落次品。
iii. NGioDelay 时间期满后,定时中断会⾃动将对应 DO 信号电平拉低复位,⼲净利落地收回⽓
缸,复归常态以应对下⼀次测试。
协议栈功能库(底层⽀持)
3.7 TCP
定位:可靠的流式⽹络传输⽀持(如 LwIP 移植)。
职责:
Socket 抽象:提供标准化、极简的创建、监听、连接、发送、接收 API。
状态机维护:⾃动处理三次握⼿、四次挥⼿、重传及断线侦测操作。
缓冲管理:管理底层的发送缓冲和接收窗⼝(TCP Window)。
性能保证与优化策略
4.
为确保“采集 -> 处理 -> 发送”这⼀重负载流⽔线在 CH32 上具备⾼帧率、低延迟的性能,需采⽤以下策
略保障:
1. 零拷⻉ (Zero-Copy) 内存流转:
在整个数据链路中,严禁在不同业务逻辑之间进⾏⼤块内存的
memcpy
复制。应当采⽤传递内存指
针的⽅式,让不同的模块轮流获取同⼀块内存的读写权限。
2. Ping-Pong 双缓冲设计 (Double Buffering):
为“矩阵输出”和“预处理”分配 A/B 两块缓冲区。当采集模块(⿊盒)向 Buffer A 写⼊第 N 帧时,预处
理模块正在读取 Buffer B 处理第 N-1 帧。两者物理隔离,实现 CPU 和外设间的全并发,⽆缝衔
接。
3. 事件驱动与 RTOS 并发:
抛弃低效的死循环轮询模式。围绕 RTOS 任务构建模型:采集结束触发信号量 -> 唤醒⾼优先级处
理任务 -> 唤醒发送任务。其余时间 CPU 处于休眠或处理低速⽹络事件。
4. 发包防阻塞与 TCP 合并传输:
将不重要且碎⽚的包合并发送;针对⼤数据块发送,采⽤异步队列机制或者结合 DMA 送到⽹络
# Page 10
MAC 接⼝,防⽌ CPU ⻓时间处于等待 TCP ACK 的阻塞状态。
Binary file not shown.
+237
View File
@@ -0,0 +1,237 @@
# Page 1
语⾔版本函数调⽤指南
C
版本V1.0
1. 概述
本指南旨在为 CH32 单⽚机其他业务代码提供调⽤“图像预处理模块”和“TCP 打包与发送模块”的 C 语⾔ API 说明。这两个模块被封装为独⽴的底层库函数,
负责将原始采集数据处理并推送⾄上位机,同时接收上位机配置。
开发者⽆需关⼼内部的滑窗算⼒优化或是 TCP 连接维持、分⽚等细节,只需按照约定的结构体提供⼊参并调⽤相关 API 即可。
2. 核⼼数据结构
2.1 原始图像数据结构 ( RawImageBuffer_t )
该结构由采集模块(⿊盒)在采集完成后构建并传⼊处理库。注意:本库所有内部计算和过滤针对的均是 16位整数矩阵 (精确到 0.1℃的定点数)。
typedef struct {
uint16_t* pData; // 指向二维 16位 整数矩阵的起始指针(如 275 代表 27.5℃)
uint16_t Width; // 原始图像宽度
uint16_t Height; // 原始图像高度
uint32_t FrameNumber; // 当前帧号(或时间戳),用于溯源
} RawImageBuffer_t;
2.2 预处理结果结构 ( PreprocessResult_t )
预处理模块运算完毕后产出的有效数据载荷结构。
typedef struct {
uint8_t* pValidData; // 必须是 uint8_t 类型的外部缓冲区指针,规避结构体强转导致的内存对齐陷阱
uint32_t DataLength; // 有效数据的字节长度 (宽度 * 高度 * sizeof(元素))
uint16_t ValidWidth; // 产出图像宽度 (对于一维,可表示点数)
uint16_t ValidHeight; // 产出图像高度
int16_t MinTemp; // 有效区域内的最低温度
int16_t MaxTemp; // 有效区域内的最高温度
int16_t AvgTemp; // 有效区域内的平均温度
int16_t RoiTemp; // 触发点温度
uint8_t Status; // 处理状态 (0: OK, 1: 异常)
uint32_t FrameNumber; // 继承自原始图像的帧号
} PreprocessResult_t;
2.3 ⽹络封装缓冲结构 ( TcpTxBuffer_t )
专为 TCP 零拷⻉封包设计的外部分配缓冲区。应⽤层(或专⻔的内存池)提供⾜够⼤的连续内存空间。
typedef struct {
uint8_t* pBuffer; // 指向由应用层分配的具体内存区 (包含物理组装全空间)
uint32_t TotalCapacity; // 该 Buffer 总容量
uint32_t HeadOffset; // 【核心】预留给封包用的首部偏移量。载荷将从 pBuffer + HeadOffset 开始写入
uint32_t ValidPayloadLen; // 在调用封装函数后,由网络库回填的最终报文总长度
} TcpTxBuffer_t;
# Page 2
2.4 系统运⾏状态与配置 ( ConfigCommon_t , Config2D_t , Config1D_t )
系统参数配置不再使⽤单⼀的句柄封装,⽽是由通信协议中定义的三个独⽴结构体分别管理: ConfigCommon_t (通⽤参数)、 Config2D_t (⼆维专有参数)
与
Config1D_t
(⼀维专有参数)。TCP 模块会通过回调动态更新这三个结构体,应⽤层需要保存最新配置以供预处理等模块使⽤(详⻅通信协议规范 2.0)。
3. 预处理模块 API
3.1 Preprocess_Init
功能:初始化预处理模块,分配静态计算所需的⼯作内存(如列累加数组)。
原型:
int8_t Preprocess_Init(uint16_t maxWidth, uint16_t maxHeight);
⼊参:
maxWidth / maxHeight : 系统允许的最⼤处理分辨率,⽤于预分配内存池。
返回值: 0 成功, <0 失败。
3.2 Preprocess_Execute
功能:对单帧⼆维矩阵进⾏裁剪并导出。系统会基于温度过滤启动滑动窗⼝去寻找热源,锁定⽬标区域(ROI)后,会将这段区域内未被修改过的真实
原始像素原样导出,写⼊外部提供的 Buffer 中。
原型: int8_t Preprocess_Execute(const RawImageBuffer_t* input, TcpTxBuffer_t* out_buffer, PreprocessResult_t* output_meta);
⼊参:
input : 采集模块提供的原始数据句柄。
out_buffer : 应⽤层预先分配好的待发送缓冲区。库将直接通过 out_buffer->pBuffer + out_buffer->HeadOffset 零拷⻉写⼊原始图像测温字节。
出参:
output_meta : 运算完成的规范化统计结果(⻓宽、最⼤、最⼩温度、平均温度等信息,统计依据同样为未失真的原始像素)。
返回值:
0
表⽰处理成功并锁定 ROI,
<0
表⽰内存越界或其他致命错误。
3.3 Preprocess_CheckInternalTrigger2D
功能:根据上位机设定的“触发 ROI 区域”、“温度触发阈值”及“判定条件(最⾼温/平均温)”,对传⼊的单帧原始图像进⾏内部热源触发判定。
原型:
int8_t Preprocess_CheckInternalTrigger2D(const RawImageBuffer_t* input);
⼊参:
input : 当前需要评判的原始图像。
返回值: 1 表⽰触发条件满⾜(画⾯中设定的 ROI 区域发现了⾜够⾼温的⽬标), 0 表⽰未触发, <0 参数错误。
使⽤场景:在内部触发机制( TriggerMode = 0 )下,结合相机的连续 DMA 或轮询输出使⽤。
3.4 Preprocess_Settings_Change
功能:安全地将通过 TCP 接收到的最新业务⼯作参数更新⾄预处理库内部。⽀持影⼦机制加锁更新策略,确保不会破坏正在进⾏处理的流⽔线帧。
原型: int8_t Preprocess_Settings_Change(const Config2D_t* newConfig2D, const Config1D_t* newConfig1D, const ConfigCommon_t* newCommon);
⼊参:
newConfig2D / newConfig1D : 从上位机新下发的专⽤参数结构体(如 TargetWidth , TriggerTemperatureThreshold )。
newCommon : 从上位机新下发的通⽤配置结构体。
返回值: 0 成功, <0 失败。
4. TCP 打包与发送模块 API
4.1 TcpLogic_Init
功能:初始化整个应⽤层 TCP 管理任务,包括底层 Socket 绑定、接收任务建⽴以及缓冲池初始化。
原型: int8_t TcpLogic_Init(const uint8_t* deviceUUID, const uint8_t* authToken);
⼊参:
deviceUUID : 16 字节的设备物理识别码(如 MAC 或 UID)。
authToken : ⾝份验证令牌。
返回值:
0
成功,
<0
失败。
# Page 3
4.2 TcpLogic_Start
功能:⾮阻塞启动 TCP 服务管理引擎。此后库将在后台⾃动进⾏ 5511 (控制流) 与 5512 (数据流) 的连接、握⼿(Handshake)、重连和⼼跳维持。
原型:
void TcpLogic_Start(void);
4.3 TcpLogic_BuildAndSendTemperatureFrame
功能:将之前由预处理写⼊ TcpTxBuffer_t 内的数据(连同 PreprocessResult_t 结构体中的统计数据)封装。函数不需要搬移⼤块矩阵数据,直接利
⽤移位操作和 HeadOffset 空间从前向后组装报⽂头(包含 TLV、Magic等),最后压⼊ 5512 发送缓冲。
原
型:
int8_t TcpLogic_BuildAndSendTemperatureFrame(TcpTxBuffer_t* io_buffer, const PreprocessResult_t* processMeta, uint8_t frameType, uint8_t is2D);
⼊参:
io_buffer : 包含已被预处理模块填充过载荷的 Buffer 包裹器。本函数执⾏完后,其中的 ValidPayloadLen 将被更新。
processMeta : 包含帧号与温区极值统计。
frameType : 帧类型 (0x00 LIVE, 0x01 TRIGGER, 0x02 MASKED)。
is2D : 1 为⼆维数组, 0 为⼀维。
返回值: 0 已组装完毕并压⼊队列, <0 失败。
4.4 TcpLogic_GetLatestConfig
功能:主动查询并返回 TCP 库缓存的、由上位机最近⼀次下发的完整配置参数结构体。适⽤于应⽤层需要在⾮回调上下⽂中(如初始化后⾸次同步或
故障恢复后重新拉取)获取当前⽣效配置的场景。
原型:
int8_t TcpLogic_GetLatestConfig(ConfigCommon_t* out_common, Config2D_t* out_cfg2d, Config1D_t* out_cfg1d);
出参:
out_common : 由调⽤者提供的通⽤配置结构体指针,库将最新缓存的通⽤配置拷⻉到此处。
out_cfg2d : 由调⽤者提供的⼆维专有配置结构体指针。
out_cfg1d : 由调⽤者提供的⼀维专有配置结构体指针。
返回值:
0
成功(配置有效),
-1
尚未从上位机收到过任何配置,
<0
其他错误。
4.5 接收与配置更新回调注册
TCP 库在后台线程处理收到的指令(如参数更改或控制信号)。主业务通过注册回调函数来处理这些上位机下发的事件,确保底层安全。
// 定义回调函数类型
typedef void (*ConfigUpdateCallback_t)(const ConfigCommon_t* common, const Config2D_t* cfg2d, const Config1D_t* cfg1d);
typedef void (*DetectionResultCallback_t)(uint32_t frameNumber, uint8_t resultStatus);
// 【注意】:此回调专门用于测试上位机主动请求帧。实际业务由硬件触发或DMA循环完成,业务代码不应依赖或实现此回调。
typedef void (*TempFrameRequestCallback_t)(uint8_t is2dRequest);
// 注册回调 API
void TcpLogic_RegisterConfigCallback(ConfigUpdateCallback_t cb);
void TcpLogic_RegisterDetectionCallback(DetectionResultCallback_t cb);
void TcpLogic_RegisterTempFrameRequestCallback(TempFrameRequestCallback_t cb);
应⽤⽰例:参数热更新
当注册了 ConfigUpdateCallback_t ,TCP 发⽣控制流的参数接收时,后台库完成参数解析及 CRC 校验后,触发此回调。⽤⼾可在回调中利⽤软中断或影⼦
积存器机制将新参数赋予当前正在使⽤的
SystemConfig_t
。
5. 核⼼ API 设计准则与开发规范
为兼顾底层性能考量与可靠性⽹络封装,本库严格遵循以下原则:
1. “传⼊指针 + ⻓度” 与预留偏移封包 (Zero-Copy Offset) ⽅案
物理内存分配由应⽤层(依托其内存池机制)负责,传递给库的操作句柄为 out_buffer 。预处理在填充矩阵数据时,会越过 HeadOffset (这个偏移量
等于后续 TCP 组合包所需的 Header 及 TLV 指⽰器的⼤⼩)。后续 TCP ⽹络库封装时,仅需要往前填充封包信息,⽆需对上百 KB 的矩阵数据做任何
memcpy
内存搬移动作。
# Page 4
2. 防范访问陷阱 (Strict uint8_t Vectoring)
禁⽌将⽹⼝收发缓冲区中的指针强转为 uint32_t 或是具体通讯结构体使⽤。库内部所有的数据移动与地址递增处理严格使⽤ uint8_t * 处理⽹络数据
流,从根本上阻绝了因不同编译器或单⽚机对⻬法则不⼀导致的 HardFault 或越界访问。
3. 内置安全⼤⼩端转化 (Bitwise Disassembly/Assembly)
**这是针对 16位 整数矩阵数据的核⼼保障。**⽆论是将采集到的定点温度( uint16_t / int16_t )拆分成⽹络字节流(封包),还是从字节流解析成单⽚
机状态(解包),都彻底抛弃了直接强转或结构体对⻬强塞的⽅式。库内部严格规定使⽤单字节移位操作(如 val = (buf[0]) | (buf[1]<<8); ),完美
解决“⽹络端与主机⼩端”之间的安全切换,并在提取矩阵数据时保证 2-Byte Little-Endian 输出。
6. 底层数据收发机制与平台移植架构 (Port 层解耦)
(预处理及TCP封包逻辑)绝对不会直接操作硬件寄存器或特定的 Socket API。
取⽽代之的是⼀个位于 qdx_port.h 的硬件抽象层(HAL,Port层)。
1. 发送:硬件发送缓冲区写⼊地址 ( qdx_port_tcp_send )
当应⽤层调⽤类似 TcpLogic_BuildAndSendTemperatureFrame 时,传递的是在外部通过内存池预先分派好、并在前⾯加上了协议头的业务缓冲数组(即
io_buffer->pBuffer )。⽹络库内部并不会“写⼊⽹卡相关的寄存器”,⽽是调⽤ qdx_port_tcp_send 。这保证了只需将封装好的完整、连续的 RAM 地址
指针和⻓度丢给驱动层。内部的 WCH NET 或 LwIP 会从给定的这个内存地址将其发往 DMA 或以太⽹ MAC。
2. 接收:硬件接收缓冲区 ( qdx_port_tcp_recv )
对应地,系统会启动后台线程监听 TCP 数据流。它每次都会从 qdx_port_tcp_recv 尝试获取数据,由底层协议栈驱动将接收到的真正⽹络⽐特流存⼊
库提供的接收缓冲中,随后库再去解析配置命令。
7. 常规调⽤流程图 (伪代码模式)
// 1. 初始化
Preprocess_Init(MAX_W, MAX_H);
TcpLogic_Init(MyUUID, MyToken);
TcpLogic_RegisterConfigCallback(OnConfigUpdated);
TcpLogic_RegisterDetectionCallback(OnHardwareReject);
// 2. 启动网络引擎线程 (RTOS环境下)
TcpLogic_Start();
// 3. 图像中断 / DMA 轮询回调
void OnCameraDataReady(uint16_t* matrix, uint16_t w, uint16_t h) {
RawImageBuffer_t rawBuff = {matrix, w, h, ++frameCnt};
// 【核心】判断这帧图像里是否有物体达到了设定的触发温度
if (Preprocess_CheckInternalTrigger2D(&rawBuff) == 1) {
// 发现高温目标!分配一块发送专用的零拷贝缓冲
TcpTxBuffer_t txBuff = MemoryPool_GetTxBuffer();
PreprocessResult_t resMeta = {0};
// 交由库执行滑动窗口剪裁,将最核心的高温区域内原始像素直接填入缓冲的预留偏移后
if (0 == Preprocess_Execute(&rawBuff, &txBuff, &resMeta)) {
// TCP封包:在头部预留好的 HeadOffset 内执行无损组包并发出
TcpLogic_BuildAndSendTemperatureFrame(&txBuff, &resMeta, 0x01, 1);
} else {
MemoryPool_FreeTxBuffer(&txBuff);
}
}
}
// 4. 当参数更新回调触发时
void OnConfigUpdated(const ConfigCommon_t* common, const Config2D_t* cfg2d, const Config1D_t* cfg1d) {
// 将获得配置输入给预处理模块,利用互斥锁安全地刷新工作参数(如 TriggerRoi)
Preprocess_Settings_Change(cfg2d, cfg1d, common);
}
# Page 5
6. 函数调⽤时序图 (Control Flow)
通过下⽅时序图,可清晰展⽰从设备启动,到外部通信介⼊,再到硬件持续触发采集的数据流动与函数调⽤顺序。
# Page 6
主机/中断(Main) TcpLogic (⽹络库) Preprocess (预处理库) ConfigServer (上位机)
1. Preprocess_Init(W, H)
2. TcpLogic_Init(UUID, Token)
3. TcpLogic_RegisterConfigCallback()
4. TcpLogic_Start()
5. ⾃动连接 5511 与 5512,完成握⼿
6. 下发⾸批动态配置指令 (Type 0x20/0x22)
7. 触发参数回调 OnConfigUpdated()
8. Preprocess_Settings_Change(cfg)
循环运转:依靠中断或任务调度持续⼯作
9. 分配待发内存 TcpTxBuffer_t(预留 Offset)
10. 等待相机 DMA 完成⼀帧或 IO 触发
11. Preprocess_Execute(&rawBuff, &txBuff)
在 Offset 位置后写⼊图⽚矩阵⻓串数据
返回处理 meta 信息及成功的 txBuff
12. TcpLogic_BuildAndSend(txBuff)
在头部 Offset 内利⽤移位封包 TLV/序列号
数据送⼊ TCP 流发送 (零拷⻉达成)
opt [获取到剔除响应]
TCP 数据流返回 Defect Result (NG)
触发 DetectionResultCallback
拉⾼ DO1 定时执⾏剔除动作
主机/中断(Main) TcpLogic (⽹络库) Preprocess (预处理库) ConfigServer (上位机)
Binary file not shown.