337 lines
8.1 KiB
C
337 lines
8.1 KiB
C
/**
|
||
* @file qdx_protocol.h
|
||
* @brief Communication Protocol 2.0 Structures and Constants
|
||
*
|
||
* Platform-independent header for CH32 MCU and other systems.
|
||
* All structures use 1-byte alignment. Focuses on safe uint8_t
|
||
* serialization and avoiding hardware faults from unaligned access.
|
||
*/
|
||
|
||
#ifndef QDX_PROTOCOL_H
|
||
#define QDX_PROTOCOL_H
|
||
|
||
#include <stdint.h>
|
||
|
||
/* ============================================================
|
||
* Protocol Constants
|
||
* ============================================================ */
|
||
#define PROTO_MAGIC 0x55AA /* Frame Header Magic */
|
||
#define PROTO_VERSION 0x20 /* Protocol Version v2.0 */
|
||
|
||
/* Message Classes (Class) */
|
||
#define CLASS_CONTROL 0x01 /* Configuration / Control */
|
||
#define CLASS_DATA 0x02 /* Real-time Data Report */
|
||
#define CLASS_RESPONSE 0x03 /* ACK / NACK / Error */
|
||
#define CLASS_SYSTEM 0x04 /* Handshake / Heartbeat / Sync */
|
||
|
||
/* TLV Types */
|
||
#define TYPE_HANDSHAKE 0x01
|
||
#define TYPE_HEARTBEAT 0x02
|
||
#define TYPE_SYNC_TIME 0x03
|
||
#define TYPE_DEVID_ASSIGN 0x05
|
||
#define TYPE_TEMP_FRAME 0x10
|
||
#define TYPE_RAW_FRAME 0x11
|
||
#define TYPE_CONFIG_COMMON 0x20
|
||
#define TYPE_CONFIG_2D 0x22
|
||
#define TYPE_CONFIG_1D 0x23
|
||
#define TYPE_ACK_PAYLOAD 0x30
|
||
#define TYPE_DETECTION_RESULT 0x40
|
||
|
||
/* Flags */
|
||
#define FLAG_PRIORITY_MASK 0x03
|
||
#define FLAG_COMPRESSED 0x04
|
||
#define FLAG_ENCRYPTED 0x08
|
||
#define FLAG_ACK_REQ 0x10
|
||
#define FLAG_LAST_FRAGMENT 0x20
|
||
|
||
/* Frame Structure Sizes */
|
||
#define HEADER_SIZE 16 /* FrameHeader_t size */
|
||
#define TLV_HEADER_SIZE 3 /* TLV_t size (Type + Length) */
|
||
#define CRC_SIZE 2 /* CRC16 size */
|
||
|
||
/* Fragmentation limit */
|
||
#define MAX_FRAGMENT_PAYLOAD 1400
|
||
|
||
/* Error Codes */
|
||
#define ERR_NONE 0x0000
|
||
#define ERR_CRC 0x1001
|
||
#define ERR_VERSION 0x1002
|
||
#define ERR_LENGTH 0x1003
|
||
#define ERR_AUTH 0x2001
|
||
#define ERR_BUSY 0x2002
|
||
#define ERR_DEV_ID_CONFLICT 0x2003
|
||
#define ERR_PARAM 0x3001
|
||
|
||
/* ============================================================
|
||
* Internal Protocol Structures (Packed to 1 byte)
|
||
* ============================================================ */
|
||
|
||
#pragma pack(push, 1)
|
||
|
||
/**
|
||
* @brief Frame Header (16 bytes)
|
||
*/
|
||
typedef struct {
|
||
uint16_t Magic;
|
||
uint8_t Version;
|
||
uint16_t Length;
|
||
uint16_t Sequence;
|
||
uint32_t Timestamp;
|
||
uint8_t Source;
|
||
uint16_t DevID;
|
||
uint8_t Class;
|
||
uint8_t Flags;
|
||
} FrameHeader_t;
|
||
|
||
/**
|
||
* @brief TLV Header (3 bytes)
|
||
*/
|
||
typedef struct {
|
||
uint8_t Type;
|
||
uint16_t Length;
|
||
} TLV_t;
|
||
|
||
/**
|
||
* @brief Handshake (46 bytes)
|
||
*/
|
||
typedef struct {
|
||
uint16_t ProtocolVersion;
|
||
uint8_t DeviceUUID[16];
|
||
uint8_t AuthToken[16];
|
||
char HardwareVersion[8];
|
||
char FirmwareVersion[8];
|
||
uint32_t Capabilities;
|
||
} Handshake_t;
|
||
|
||
/**
|
||
* @brief Heartbeat (6 bytes)
|
||
*/
|
||
typedef struct {
|
||
uint32_t UpTime;
|
||
uint8_t CpuLoad;
|
||
uint8_t MemUsage;
|
||
} Heartbeat_t;
|
||
|
||
/**
|
||
* @brief ACK Payload (5 bytes)
|
||
*/
|
||
typedef struct {
|
||
uint16_t AckSeq;
|
||
uint8_t Status;
|
||
uint16_t ErrorCode;
|
||
} Ack_t;
|
||
|
||
/**
|
||
* @brief Device ID Assignment (4 bytes)
|
||
*/
|
||
typedef struct {
|
||
uint16_t NewDevID;
|
||
uint16_t Reserved;
|
||
} DevIDAssignment_t;
|
||
|
||
/**
|
||
* @brief Temperature Frame Header (18 bytes)
|
||
*/
|
||
typedef struct {
|
||
uint32_t FrameNumber;
|
||
uint16_t Width;
|
||
uint16_t Height;
|
||
int16_t MinTemp;
|
||
int16_t MaxTemp;
|
||
int16_t AvgTemp;
|
||
int16_t RoiTemp;
|
||
uint8_t FrameType;
|
||
uint8_t Status;
|
||
uint8_t Is2D;
|
||
uint8_t Reserved;
|
||
} TemperatureFrameHeader_t;
|
||
|
||
/**
|
||
* @brief 1D Temperature Point (4 bytes)
|
||
*/
|
||
typedef struct {
|
||
uint16_t TimeOffset;
|
||
uint16_t Temperature;
|
||
} TempPoint1D_t;
|
||
|
||
/**
|
||
* @brief Detection Result (8 bytes)
|
||
*/
|
||
typedef struct {
|
||
uint32_t FrameNumber;
|
||
uint8_t Result;
|
||
uint8_t Reserved[3];
|
||
} DetectionResult_t;
|
||
|
||
/**
|
||
* @brief Common Configuration
|
||
*/
|
||
typedef struct {
|
||
char PipelineId[16];
|
||
uint8_t PipelineType;
|
||
uint8_t WorkMode;
|
||
uint8_t ConfigTag;
|
||
uint8_t StrictnessLevel;
|
||
uint8_t IsCustomMode;
|
||
uint8_t Reserved[2];
|
||
} ConfigCommon_t;
|
||
|
||
/**
|
||
* @brief 2D Configuration
|
||
*/
|
||
typedef struct {
|
||
uint8_t Enabled;
|
||
uint8_t IsLive;
|
||
uint16_t DeviceId;
|
||
uint16_t Width;
|
||
uint16_t Height;
|
||
uint8_t Fps;
|
||
uint32_t Exposure;
|
||
uint8_t AutoExposure;
|
||
uint8_t MaskEnabled;
|
||
int16_t MaskThreshold;
|
||
uint16_t MaskWidth;
|
||
uint16_t MaskHeight;
|
||
int16_t Angle;
|
||
uint16_t TargetWidth;
|
||
uint16_t TargetHeight;
|
||
uint8_t TriggerMode;
|
||
uint8_t TriggerGpioLine;
|
||
uint16_t TriggerDelayMs;
|
||
uint8_t TriggerBurstCount;
|
||
uint16_t TriggerInternalIntervalMs;
|
||
int16_t TriggerTemperatureThreshold;
|
||
uint16_t TriggerDebounceIntervalMs;
|
||
uint8_t TriggerCondition;
|
||
uint16_t TriggerRoiX;
|
||
uint16_t TriggerRoiY;
|
||
uint16_t TriggerRoiW;
|
||
uint16_t TriggerRoiH;
|
||
uint16_t NGioDelay;
|
||
uint8_t OutputGpioLine;
|
||
uint8_t AlarmGpioLine;
|
||
uint16_t AlarmHoldMs;
|
||
uint8_t StoreNgImagesOnly;
|
||
uint8_t TrainingEnabled;
|
||
uint16_t TrainingSampleThreshold;
|
||
uint16_t ProcessingTimeoutMs;
|
||
uint8_t MaxProcessingQueueSize;
|
||
uint8_t Reserved;
|
||
} Config2D_t;
|
||
|
||
/**
|
||
* @brief 1D Configuration
|
||
*/
|
||
typedef struct {
|
||
uint8_t Enabled;
|
||
uint8_t RunMode;
|
||
uint8_t TriggerType;
|
||
uint16_t BufferSize;
|
||
int16_t TriggerTempLimit;
|
||
uint16_t StartPointsToRemove;
|
||
uint16_t ReferenceLength;
|
||
uint16_t HighTimerLimit;
|
||
uint16_t TimerCLimit;
|
||
uint8_t NgCountLimit;
|
||
uint16_t LSizeStart;
|
||
uint16_t RSizeStart;
|
||
uint16_t NGioDelay;
|
||
uint8_t OutputGpioLine;
|
||
uint8_t AlarmGpioLine;
|
||
uint16_t AlarmHoldMs;
|
||
} Config1D_t;
|
||
|
||
#pragma pack(pop)
|
||
|
||
/* ============================================================
|
||
* Application Level Business Structures
|
||
* ============================================================ */
|
||
|
||
/**
|
||
* @brief Raw Image Buffer provided by capture module
|
||
*/
|
||
typedef struct {
|
||
uint16_t *pData;
|
||
uint16_t Width;
|
||
uint16_t Height;
|
||
uint32_t FrameNumber;
|
||
} RawImageBuffer_t;
|
||
|
||
/**
|
||
* @brief Preprocessing result metadata
|
||
*/
|
||
typedef struct {
|
||
uint8_t *pValidData;
|
||
uint32_t DataLength;
|
||
uint16_t ValidWidth;
|
||
uint16_t ValidHeight;
|
||
int16_t MinTemp;
|
||
int16_t MaxTemp;
|
||
int16_t AvgTemp;
|
||
int16_t RoiTemp;
|
||
uint8_t Status;
|
||
uint32_t FrameNumber;
|
||
} PreprocessResult_t;
|
||
|
||
/**
|
||
* @brief Buffer wrapper for Zero-Copy TCP packet building
|
||
*/
|
||
typedef struct {
|
||
uint8_t *pBuffer;
|
||
uint32_t TotalCapacity;
|
||
uint32_t HeadOffset; /* Reserved header space for envelope */
|
||
uint32_t ValidPayloadLen;
|
||
} TcpTxBuffer_t;
|
||
|
||
/* System global config hook types */
|
||
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);
|
||
|
||
/* ============================================================
|
||
* Protocol Utility Function Declarations
|
||
* ============================================================ */
|
||
|
||
/* Calculate Modbus CRC16 */
|
||
uint16_t qdx_crc16_modbus(const uint8_t *data, int len);
|
||
|
||
/* Shift-safe write: 16-bit little-endian */
|
||
void qdx_write_u16_le(uint8_t *buf, uint16_t val);
|
||
|
||
/* Shift-safe write: 32-bit little-endian */
|
||
void qdx_write_u32_le(uint8_t *buf, uint32_t val);
|
||
|
||
/* Shift-safe read: 16-bit little-endian */
|
||
uint16_t qdx_read_u16_le(const uint8_t *buf);
|
||
|
||
/* Shift-safe read: 32-bit little-endian */
|
||
uint32_t qdx_read_u32_le(const uint8_t *buf);
|
||
|
||
/**
|
||
* @brief Build a complete protocol frame using safe byte shifts.
|
||
*/
|
||
int qdx_build_frame(uint8_t *buf, uint8_t msg_class, uint8_t tlv_type,
|
||
const uint8_t *payload, uint16_t payload_len,
|
||
uint16_t dev_id, uint16_t seq, uint32_t timestamp,
|
||
uint8_t flags);
|
||
|
||
/**
|
||
* @brief In-place frame build: 仅填写帧头并追加 CRC,不拷贝 payload。
|
||
* 用于零拷贝场景,payload(含 TLV)已在 buf[HEADER_SIZE] 处就位。
|
||
*/
|
||
int qdx_build_frame_inplace(uint8_t *buf, uint8_t msg_class,
|
||
uint16_t payload_len, uint16_t dev_id, uint16_t seq,
|
||
uint32_t timestamp, uint8_t flags);
|
||
|
||
/**
|
||
* @brief Build a fragmented payload frame (No TLV wrapper).
|
||
*/
|
||
int qdx_build_fragment_frame(uint8_t *buf, uint8_t msg_class,
|
||
const uint8_t *chunk, uint16_t chunk_len,
|
||
uint16_t dev_id, uint16_t seq, uint32_t timestamp,
|
||
uint8_t flags);
|
||
|
||
#endif /* QDX_PROTOCOL_H */
|