165 lines
5.9 KiB
C
165 lines
5.9 KiB
C
/**
|
|
* 日期: 2025-08-26
|
|
* 作者: coffee
|
|
* 描述: 调度协议, 用于多数据口接收数据和发送数据后回复数据临时调度回来
|
|
*/
|
|
|
|
#ifndef __HD_PROTOCOL_SERVER_H__
|
|
#define __HD_PROTOCOL_SERVER_H__
|
|
|
|
|
|
#include "HRingBuffer.h"
|
|
#include <stdint.h>
|
|
|
|
#ifndef __COUNT_ARGS_IMPL
|
|
#define __COUNT_ARGS_IMPL(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
|
|
#endif
|
|
#ifndef __COUNT_ARGS
|
|
#define __COUNT_ARGS(...) __COUNT_ARGS_IMPL(dummy, ##__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
|
#endif
|
|
|
|
/**
|
|
* demo:
|
|
* 1. 设置调度回调函数 HDProtocolSetCallback(HScheduleCallback callback);
|
|
* 2. 注册调度数据信息数组 HDProtocolRegisterInfo(HDProtocolServerInfo *info, uint8_t src, void *data, int dataLen);
|
|
* 3. HDProtocolRun();
|
|
*/
|
|
|
|
// 再次发送超时时间
|
|
#define HDPROTOCOL_DELAY_TIMEOUT (100)
|
|
|
|
// 数据占用时间
|
|
#define HDPROTOCOL_OCCUPY_TIMEOUT (1000)
|
|
|
|
|
|
enum eHDProtocolSupport
|
|
{
|
|
kHDProtocolNone = 0x00, ///< 无协议, 不阻塞等待
|
|
kHDProtocolFpga = 0x01, ///< fpga协议, 独占解析端
|
|
kHDProtocolVP = 0x02, ///< vp协议, 独占解析端
|
|
kHDProtocolTV = 0x04, ///< tv协议
|
|
};
|
|
|
|
/**
|
|
* @brief 协议信息结构
|
|
* @note 协议信息结构里面的buffer需要用户自己分配内存, 通过 HDProtocolInitInfo 初始化传递内存
|
|
* 用户只需要读取环状缓冲区即可
|
|
*/
|
|
typedef struct __attribute__((__packed__)) HDProtocolServerInfo
|
|
{
|
|
HRingBufferType *readBuff; ///< 读取环状缓冲区, 内存需要用户调用 HDProtocolInitInfo 提供, 最低需要 sizeof(_HRingBufferBase) + 1 的空间
|
|
uint8_t supportProtocol; ///< 支持的协议, 用于解析端选择, 避免多路口同时解析
|
|
uint8_t src; ///< 源数据口
|
|
uint8_t dst; ///< 目标数据口(如果需要始终转发可以修改该项目, 否则默认和src一样)
|
|
uint8_t tmpDst; ///< 临时回送目标数据口(用于该指令需要先请求某个数据后才能回复的情况)
|
|
uint8_t tmpReadCount : 5; ///< 临时数据最大等待回复次数
|
|
uint8_t tmpEnable : 1; ///< 当前临时目标等待数据, 需要等待数据内部标记开启, 数据完成或者超时后自动关闭
|
|
uint8_t run : 1; ///< 内部标记当前正常读取, 如果再次触发解析, 则不等待
|
|
uint8_t checkAlarm : 1; ///< 启动缓存报警检查
|
|
uint8_t notifyAlarm : 1; ///< 通知缓存报警(内部管理)
|
|
uint8_t occupy : 1; ///< 内部标记当前正在占用
|
|
uint8_t delayCount : 6; ///< 延时等待次数(默认: 1), 每次等待时间为 HSCHEDULE_DELAY_TIMEOUT
|
|
} HDProtocolServerInfo;
|
|
|
|
/**
|
|
* @brief 读取回调函数
|
|
* @param info 协议信息
|
|
* param isTimeout 是否超时, 1: 表示当前数据已经超时, 协议需要重置让渡给其他解析, 0: 表示当前数据未超时
|
|
* @return 返回协议解析长度, 返回0表示解析结束
|
|
*/
|
|
typedef int (*HDProtocolReadCallback)(HDProtocolServerInfo *info, uint8_t isTimeout);
|
|
typedef void (*HDProtocolWriteCallback)(HDProtocolServerInfo *info, const uint8_t *data, int len);
|
|
typedef void (*HDProtocolCheckAlarmCallback)(HDProtocolServerInfo *info);
|
|
/**
|
|
* @brief 设置协议回调函数
|
|
* @param readCall 读取回调函数
|
|
* @param writeCall 写入回调函数
|
|
*/
|
|
void HDProtocolSetCallback(HDProtocolReadCallback readCall, HDProtocolWriteCallback writeCall);
|
|
|
|
/**
|
|
* @brief 设置缓冲区报警回调, 需要立刻返回, 不能阻塞
|
|
* @param checkCall 检查缓冲区报警回调函数
|
|
*/
|
|
void HDProtocolCheckAlarmCall(HDProtocolCheckAlarmCallback checkCall);
|
|
|
|
/**
|
|
* @brief 初始化协议信息结构, 将原始缓冲器转换成环状缓冲区(需要消耗一些字节)
|
|
* @param info 协议信息结构
|
|
* @param src 源数据口和目标数据口
|
|
* @param data 原始缓冲区
|
|
* @param dataLen 原始缓冲区长度
|
|
*/
|
|
void HDProtocolInitInfo(HDProtocolServerInfo *info, uint8_t src, void *data, int dataLen);
|
|
|
|
/**
|
|
* @brief 设置支持的协议
|
|
* @param info 协议信息结构
|
|
* @param len 支持的协议个数
|
|
* @param ... 支持的协议
|
|
*/
|
|
void _HDProtocolSetSupportProtocol(HDProtocolServerInfo *info, int len, ...);
|
|
#define HDProtocolSetSupportProtocol(info, ...) _HDProtocolSetSupportProtocol(info, __COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__)
|
|
|
|
/**
|
|
* @brief 注册协议信息
|
|
* @param info 协议信息结构
|
|
* @param len 协议信息结构长度
|
|
*/
|
|
void HDProtocolRegisterInit(HDProtocolServerInfo *info, int len);
|
|
|
|
/**
|
|
* @brief 根据当前路由发送(用于解析数据后回送数据, 如果不是读取回调的时候调用, 则找不到对应路由报错, 返回0)
|
|
* @param data 发送数据
|
|
* @param len 发送数据长度
|
|
* @return 发送成功返回1 失败返回0
|
|
*/
|
|
uint8_t HDProtocolCurrSend(const void *data, int len);
|
|
|
|
/**
|
|
* @brief 根据目标数据口发送
|
|
* @param dst 需要往那个目标数据口发送
|
|
* @param data 发送数据
|
|
* @param len 发送数据长度
|
|
*/
|
|
void HDProtocolSendPort(uint8_t dst, const void *data, int len);
|
|
|
|
/**
|
|
* @brief 临时路由发送(用于发送目标端口的数据后, 解析端临时更改目标端口, 通过 HDProtocolGetDest 获取目标端口)
|
|
* @param src 发送源端口
|
|
* @param dst 回送后需要转发到的目标端口
|
|
* @param data 发送数据
|
|
* @param len 发送数据长度
|
|
* @param needReadCount 需要读取次数
|
|
* @param waitCount 等待次数
|
|
*/
|
|
void HDProtocolTmpSend(uint8_t src, uint8_t dst, const void *data, int len, uint8_t needReadCount, uint8_t waitCount);
|
|
|
|
/**
|
|
* @brief 获取目标数据口
|
|
* @param info 协议信息
|
|
* @return 目标数据口
|
|
*/
|
|
uint8_t HDProtocolGetDest(HDProtocolServerInfo *info);
|
|
|
|
/**
|
|
* @brief 获取当前协议信息
|
|
* @return 当前协议信息
|
|
*/
|
|
HDProtocolServerInfo *HDProtocolGetCurrInfo();
|
|
|
|
/**
|
|
* @brief 告知服务当前对应源端读取数据
|
|
* @param src 源数据口
|
|
* @param data 读取数据
|
|
* @param len 读取数据长度
|
|
*/
|
|
void HDProtocolRead(uint8_t src, const void *data, int len);
|
|
|
|
/**
|
|
* @brief 运行调度协议
|
|
*/
|
|
void HDProtocolRun();
|
|
|
|
#endif // __HD_PROTOCOL_SERVER_H__
|