Files
CCU621M/app/pos_vtk/vtk_frame.h
T

135 lines
4.5 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.
#ifndef VTK_FRAME_H
#define VTK_FRAME_H
#include "publicdata/public_define.h"
#if (POS_VTK_EN)
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
/* VTK 基础协议号(串口模式) */
#define VTK_PD_VMC_TO_POS ((U16_T)0x96FB) /* CCU(VMC) → POS */
#define VTK_PD_POS_TO_VMC ((U16_T)0x97FB) /* POS → CCU(VMC) */
/* 串口帧相关常量 */
#define VTK_FRAME_START_BYTE ((U8_T)0x1F)
#define VTK_MAX_APP_LEN ((U16_T)512)
#define VTK_MAX_FRAME_LEN ((U16_T)(1 + 2 + 2 + VTK_MAX_APP_LEN + 2)) /* Start + Len + PD + App + CRC */
typedef struct
{
U16_T protoDisc; /* 协议号:VTK_PD_VMC_TO_POS / VTK_PD_POS_TO_VMC */
const U8_T *pApp; /* 指向应用层 TLV 数据起始地址 */
U16_T appLen; /* 应用层 TLV 数据长度 */
} VTK_FRAME_INFO_T;
/* 串口帧打包:把 TLV 应用数据封装为完整 VTK 串口帧
* @param[in] pApp 应用层 TLV 数据指针
* @param[in] appLen 应用层 TLV 数据长度
* @param[in] protoDisc 协议号(通常为 VTK_PD_VMC_TO_POS
* @param[out] pOut 输出缓冲区
* @param[in] outMax 输出缓冲区大小
* @return U16_T 串口帧总长度;0 表示失败(缓冲区不足等)
*/
U16_T vtk_build_frame(const U8_T *pApp, U16_T appLen, U16_T protoDisc,
U8_T *pOut, U16_T outMax);
/* 串口帧解析:对一整帧(含 0x1F 起始和 CRC)做合法性校验,并给出应用层 TLV 区段
* @param[in] pFrame 输入帧缓冲区
* @param[in] frameLen 输入帧长度
* @param[out] pInfo 输出解析结果(协议号、应用层指针与长度)
* @return U8_T 1=解析成功且 CRC 正确,0=失败
*/
U8_T vtk_parse_frame(const U8_T *pFrame, U16_T frameLen, VTK_FRAME_INFO_T *pInfo);
/* 流式解析器:用于从串口逐字节接收数据并拼出完整 VTK 帧 */
typedef enum
{
VTK_PARSE_WAIT_START = 0,
VTK_PARSE_LEN_H,
VTK_PARSE_LEN_L,
VTK_PARSE_BODY,
VTK_PARSE_CRC_H,
VTK_PARSE_CRC_L
} VTK_PARSE_STATE_E;
typedef struct
{
VTK_PARSE_STATE_E state;
U16_T lengthField; /* Length 字段值(Protocol Disc + App 长度) */
U16_T index; /* 当前已接收字节数 */
U16_T totalLen; /* 预期整帧长度(含起始和 CRC) */
U8_T buf[VTK_MAX_FRAME_LEN]; /* 内部缓冲区 */
} VTK_FRAME_PARSER_T;
/* 初始化帧解析器 */
void vtk_frame_parser_init(VTK_FRAME_PARSER_T *parser);
/* 向帧解析器输入 1 字节
* @param[in,out] parser 解析器状态
* @param[in] byte 串口接收到的 1 字节
* @param[out] ppFrame 当返回 1 时,指向完整帧起始地址(内部缓冲区)
* @param[out] pLen 当返回 1 时,给出完整帧长度
* @return U8_T 1=拼出完整合法帧;0=尚未完成或校验失败
*/
U8_T vtk_frame_parser_input(VTK_FRAME_PARSER_T *parser, U8_T byte,
const U8_T **ppFrame, U16_T *pLen);
/* 使用示例(发送 + 接收):
*
* // 发送侧:构造一帧带 TLV 的 VTK 串口报文并通过 UART 发送
* U8_T tlvBuf[VTK_MAX_APP_LEN];
* U16_T tlvLen = 0;
* U8_T frameBuf[VTK_MAX_FRAME_LEN];
* U16_T frameLen;
*
* // 追加 TLV 参数,例如 MessageName(Tag=0x01)="CDP"
* vtk_tlv_append_ascii(0x01, "CDP", tlvBuf, sizeof(tlvBuf), &tlvLen);
* // 追加 OperationNo(Tag=0x03)="12345"
* vtk_tlv_append_ascii_uint(0x03, 12345, 1, tlvBuf, sizeof(tlvBuf), &tlvLen);
* // 追加 Amount(Tag=0x04)="5000"
* vtk_tlv_append_ascii_uint(0x04, 5000, 1, tlvBuf, sizeof(tlvBuf), &tlvLen);
*
* // 封装为串口帧并发送
* frameLen = vtk_build_frame(tlvBuf, tlvLen, VTK_PD_VMC_TO_POS,
* frameBuf, sizeof(frameBuf));
* if (frameLen > 0U)
* {
* POS_VTK_UART_SEND(frameBuf, frameLen); // 由上层实现的串口发送函数
* }
*
* // 接收侧:在 UART 接收中断/任务中逐字节喂入解析器
* static VTK_FRAME_PARSER_T s_parser;
* static U8_T parserInited = 0;
*
* if (!parserInited)
* {
* vtk_frame_parser_init(&s_parser);
* parserInited = 1;
* }
*
* void UART_Rx_Handler_Byte(U8_T rxByte)
* {
* const U8_T *pFrame;
* U16_T frameLen;
*
* if (vtk_frame_parser_input(&s_parser, rxByte, &pFrame, &frameLen))
* {
* // 这里获得了一整帧 VTK 报文,可继续调用 vtk_parse_frame / vtk_parse_payment_response 解析
* }
* }
*/
#ifdef __cplusplus
}
#endif
#endif /* POS_VTK_EN */
#endif /* VTK_FRAME_H */