2026-03-13 22:42:57 +08:00

337 lines
8.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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 */