1. 新增协议绑定模块
This commit is contained in:
parent
82b9dfaa0c
commit
e76325dd2e
@ -131,7 +131,7 @@ typedef struct __attribute__((packed)) HDRPCCallBuffer {
|
|||||||
const char *name; ///< 函数名
|
const char *name; ///< 函数名
|
||||||
HDRPCCallback callback; ///< 回调
|
HDRPCCallback callback; ///< 回调
|
||||||
#ifdef HDRPC_TIMEOUT
|
#ifdef HDRPC_TIMEOUT
|
||||||
HDRPCTimeoutCall timeout; ///< 超时回调, 就算超时只要没有覆盖还是会调用正常回调
|
HDRPCTimeoutCall timeout; ///< 超时回调, 不为空时, 调用后释放
|
||||||
#endif
|
#endif
|
||||||
} HDRPCCallBuffer;
|
} HDRPCCallBuffer;
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ void HDRPCReadCallData(void *data, uint16_t len);
|
|||||||
* @param funcName 函数名称
|
* @param funcName 函数名称
|
||||||
* @param nameLen 名称长度
|
* @param nameLen 名称长度
|
||||||
* @param timeout 超时回调
|
* @param timeout 超时回调
|
||||||
* @return int16_t id索引(返回-1无效)
|
* @return int16_t id索引(返回-1则无存储返回回调)
|
||||||
*/
|
*/
|
||||||
int16_t _HDRPCSendData(HDRPCSession *session, uint16_t funcCode, HDRPCCallback callBack, const char *funcName, uint8_t nameLen, HDRPCTimeoutCall timeout);
|
int16_t _HDRPCSendData(HDRPCSession *session, uint16_t funcCode, HDRPCCallback callBack, const char *funcName, uint8_t nameLen, HDRPCTimeoutCall timeout);
|
||||||
#define HDRPCSendData(session, code, func) _HDRPCSendData(session, code, func, #func, sizeof(#func) - 1, NULL)
|
#define HDRPCSendData(session, code, func) _HDRPCSendData(session, code, func, #func, sizeof(#func) - 1, NULL)
|
||||||
|
|||||||
92
include/HProtocolBind.h
Normal file
92
include/HProtocolBind.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* 日期: 2025-10-18
|
||||||
|
* 作者: coffee
|
||||||
|
* 描述: 协议绑定回调, 用于等待数据回送再执行, 避免阻塞主进程
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_PROTOCOL_BIND_H_
|
||||||
|
#define _H_PROTOCOL_BIND_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// 需要处理的最大数量
|
||||||
|
#ifndef HPROTOCOL_BIND_MAX
|
||||||
|
#define HPROTOCOL_BIND_MAX (2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 协议绑定无效值
|
||||||
|
#ifndef HPROTOCOL_BIND_INVALID
|
||||||
|
#define HPROTOCOL_BIND_INVALID (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///< 协议绑定索引
|
||||||
|
typedef int16_t HProtocolBind_t;
|
||||||
|
|
||||||
|
///< 协议ID
|
||||||
|
typedef uint8_t HProtocolBindId_t;
|
||||||
|
|
||||||
|
///< 功能码
|
||||||
|
typedef uint16_t HProtocolBindFunc_t;
|
||||||
|
|
||||||
|
///< 协议回调
|
||||||
|
typedef void (*HProtocolBindCallback)(HProtocolBind_t index, uint8_t* data, uint16_t len);
|
||||||
|
#define HPROTOCOL_BIND_CALL_ARGS HProtocolBind_t index, uint8_t* data, uint16_t len
|
||||||
|
|
||||||
|
///< 协议会话
|
||||||
|
typedef struct HProtocolBindInfo
|
||||||
|
{
|
||||||
|
uint32_t enable : 2; ///< 是否启用
|
||||||
|
uint32_t delayMs : 20; ///< 超时时间(ms)
|
||||||
|
uint32_t isTimeout : 1; ///< 是否超时
|
||||||
|
HProtocolBindFunc_t func; ///< 功能码
|
||||||
|
uint32_t lastTime; ///< 发送时间
|
||||||
|
HProtocolBindCallback callback; ///< 回调, 超时时执行的数据和长度为空
|
||||||
|
} HProtocolBindInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 注册协议绑定信息
|
||||||
|
* @param id 协议ID
|
||||||
|
* @param info 协议绑定信息
|
||||||
|
* @param infoLen 协议绑定信息长度
|
||||||
|
*/
|
||||||
|
uint8_t HProtocolBindRegister(uint8_t id, HProtocolBindInfo *info, uint8_t infoLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 绑定协议功能码等待回调
|
||||||
|
* @param id 协议ID
|
||||||
|
* @param func 功能码
|
||||||
|
* @param callback 回调
|
||||||
|
* @param delayMs 超时时间(ms)
|
||||||
|
* @return HProtocolBind_t -1失败
|
||||||
|
*/
|
||||||
|
HProtocolBind_t HProtocolBindAddTask(HProtocolBindId_t id, HProtocolBindFunc_t func, HProtocolBindCallback callback, uint32_t delayMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 删除协议绑定
|
||||||
|
* @param index 绑定索引
|
||||||
|
*/
|
||||||
|
void HProtocolBindRemoveTask(HProtocolBind_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 查询是否超时, 用于超时回调检查
|
||||||
|
* @param index 绑定索引
|
||||||
|
* @return true超时 false未超时
|
||||||
|
*/
|
||||||
|
uint8_t HProtocolBindIsTimeout(HProtocolBind_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 更新协议数据
|
||||||
|
* @param id 协议ID
|
||||||
|
* @param func 功能码
|
||||||
|
* @param data 数据
|
||||||
|
* @param len 数据长度
|
||||||
|
*/
|
||||||
|
void HProtocolBindUpdateData(HProtocolBindId_t id, HProtocolBindFunc_t func, void* data, uint16_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 调度协议绑定
|
||||||
|
*/
|
||||||
|
void HProtocolBindRun(HProtocolBindId_t id);
|
||||||
|
|
||||||
|
#endif // _H_PROTOCOL_BIND_H_
|
||||||
@ -58,9 +58,9 @@ uint32_t HTimerGetMs();
|
|||||||
* @param id 定时器ID
|
* @param id 定时器ID
|
||||||
* @param info 定时器信息, 由外部提供定时器数组
|
* @param info 定时器信息, 由外部提供定时器数组
|
||||||
* @param infoLen 定时器信息长度
|
* @param infoLen 定时器信息长度
|
||||||
* @return HTIMER_INVALID 注册失败, 返回定时器ID
|
* @return 1成功 0失败
|
||||||
*/
|
*/
|
||||||
HTimer_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen);
|
uint8_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen);
|
||||||
|
|
||||||
///< 移除定时器信息
|
///< 移除定时器信息
|
||||||
void HTimerRemoveRegister(uint8_t id);
|
void HTimerRemoveRegister(uint8_t id);
|
||||||
|
|||||||
20
src/HDRPC.c
20
src/HDRPC.c
@ -42,7 +42,7 @@ static void FreeItem(uint8_t index)
|
|||||||
LogD("useCallLen[%d], timeoutCallLen[%d]", sInfo.useCallLen, sInfo.timeoutCallLen);
|
LogD("useCallLen[%d], timeoutCallLen[%d]", sInfo.useCallLen, sInfo.timeoutCallLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateTimeout(HDRPCCallBuffer *callBuff) {
|
static void UpdateTimeout(uint8_t index, HDRPCCallBuffer *callBuff) {
|
||||||
if (callBuff == NULL) {
|
if (callBuff == NULL) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
@ -58,11 +58,17 @@ static void UpdateTimeout(HDRPCCallBuffer *callBuff) {
|
|||||||
|
|
||||||
const uint32_t curr = HDLogGetTime();
|
const uint32_t curr = HDLogGetTime();
|
||||||
if (curr - callBuff->lastTime > callBuff->delayMs) {
|
if (curr - callBuff->lastTime > callBuff->delayMs) {
|
||||||
|
if (callBuff->timeout) {
|
||||||
|
callBuff->timeout();
|
||||||
|
}
|
||||||
|
|
||||||
callBuff->isTimeout = 1;
|
callBuff->isTimeout = 1;
|
||||||
++sInfo.timeoutCallLen;
|
++sInfo.timeoutCallLen;
|
||||||
LogD("Call[%s] Timeout, buffLen[%d]", callBuff->name, sInfo.timeoutCallLen);
|
LogD("Call[%s] Timeout, buffLen[%d]", callBuff->name, sInfo.timeoutCallLen);
|
||||||
|
|
||||||
|
// 如果超时函数有效, 则超时后释放
|
||||||
if (callBuff->timeout) {
|
if (callBuff->timeout) {
|
||||||
callBuff->timeout();
|
FreeItem(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -746,7 +752,7 @@ uint16_t HDRPCConvSendData(HDRPCSession *session, uint8_t *data, uint16_t len)
|
|||||||
|
|
||||||
void HDRPCSetDelayTime(int16_t idIndex, uint16_t delayMs)
|
void HDRPCSetDelayTime(int16_t idIndex, uint16_t delayMs)
|
||||||
{
|
{
|
||||||
if (idIndex <= 0 || idIndex >= sInfo.callLen) {
|
if (idIndex < 0 || idIndex >= sInfo.callLen) {
|
||||||
LogD("Invalid idIndex[%d]", idIndex);
|
LogD("Invalid idIndex[%d]", idIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -756,8 +762,8 @@ void HDRPCSetDelayTime(int16_t idIndex, uint16_t delayMs)
|
|||||||
|
|
||||||
HDRPCCallback HDRPCGetCallBack(int16_t idIndex)
|
HDRPCCallback HDRPCGetCallBack(int16_t idIndex)
|
||||||
{
|
{
|
||||||
if (idIndex <= 0 || idIndex >= sInfo.callLen) {
|
if (idIndex < 0 || idIndex >= sInfo.callLen) {
|
||||||
LogD("Invalid idIndex[%d]", idIndex);
|
LogD("Invalid idIndex[%d], len[%d]", idIndex, sInfo.callLen);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -766,7 +772,7 @@ HDRPCCallback HDRPCGetCallBack(int16_t idIndex)
|
|||||||
|
|
||||||
void HDRPCRemoveTask(int16_t idIndex)
|
void HDRPCRemoveTask(int16_t idIndex)
|
||||||
{
|
{
|
||||||
if (idIndex <= 0 || idIndex >= sInfo.callLen) {
|
if (idIndex < 0 || idIndex >= sInfo.callLen) {
|
||||||
LogD("Invalid idIndex[%d]", idIndex);
|
LogD("Invalid idIndex[%d]", idIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -785,6 +791,6 @@ void HDRPCRun()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (uint16_t i = 0; i < sInfo.callLen; ++i) {
|
for (uint16_t i = 0; i < sInfo.callLen; ++i) {
|
||||||
UpdateTimeout(&sInfo.localCallBuffer[i]);
|
UpdateTimeout(i, &sInfo.localCallBuffer[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
200
src/HProtocolBind.c
Normal file
200
src/HProtocolBind.c
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "HProtocolBind.h"
|
||||||
|
#include "HDLog.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef LogD
|
||||||
|
#define LogD(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CREATE_INDEX(id, index) ((id << 8) | index)
|
||||||
|
#define GET_ID(index) ((index >> 8) & 0xFF)
|
||||||
|
#define GET_INDEX(index) (index & 0xFF)
|
||||||
|
|
||||||
|
struct __attribute__((packed)) BindInfo
|
||||||
|
{
|
||||||
|
uint32_t enable : 1; ///< 绑定使能
|
||||||
|
uint32_t curr : 1; ///< 当前绑定
|
||||||
|
uint32_t useLen : 8; ///< 使用长度, 减少扫描次数
|
||||||
|
uint32_t len : 8; ///< 绑定个数
|
||||||
|
HProtocolBindInfo *binds; ///< 绑定
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct BindInfo sBindRegisters[HPROTOCOL_BIND_MAX];
|
||||||
|
|
||||||
|
static void FreeItem(uint8_t id, HProtocolBind_t index) {
|
||||||
|
--sBindRegisters[id].useLen;
|
||||||
|
memset(&sBindRegisters[id].binds[index], 0, sizeof(HProtocolBindInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t HProtocolBindRegister(uint8_t id, HProtocolBindInfo *info, uint8_t infoLen) {
|
||||||
|
if (id >= HPROTOCOL_BIND_MAX) {
|
||||||
|
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sBindRegisters[id].enable == 1) {
|
||||||
|
LogD("id[%d] already register", id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sBindRegisters[id].binds = info;
|
||||||
|
sBindRegisters[id].len = infoLen;
|
||||||
|
sBindRegisters[id].enable = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HProtocolBind_t HProtocolBindAddTask(HProtocolBindId_t id, HProtocolBindFunc_t func, HProtocolBindCallback callback, uint32_t delayMs) {
|
||||||
|
if (id >= HPROTOCOL_BIND_MAX) {
|
||||||
|
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
|
||||||
|
return HPROTOCOL_BIND_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sBindRegisters[id].enable == 0) {
|
||||||
|
LogD("not enable, id[%d]", id);
|
||||||
|
return HPROTOCOL_BIND_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback == NULL) {
|
||||||
|
LogD("callback is null, id[%d]", id);
|
||||||
|
return HPROTOCOL_BIND_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) {
|
||||||
|
if (sBindRegisters[id].binds[i].enable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防中断导致数据重叠
|
||||||
|
sBindRegisters[id].binds[i].enable = 1;
|
||||||
|
if (sBindRegisters[id].binds[i].enable != 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
++sBindRegisters[id].useLen;
|
||||||
|
sBindRegisters[id].binds[i].enable = 2;
|
||||||
|
sBindRegisters[id].binds[i].delayMs = delayMs;
|
||||||
|
sBindRegisters[id].binds[i].isTimeout = 0;
|
||||||
|
sBindRegisters[id].binds[i].func = func;
|
||||||
|
sBindRegisters[id].binds[i].lastTime = HDLogGetTime();
|
||||||
|
sBindRegisters[id].binds[i].callback = callback;
|
||||||
|
|
||||||
|
return CREATE_INDEX(id, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogD("bind full, id[%d], len[%d]", id, sBindRegisters[id].len);
|
||||||
|
return HPROTOCOL_BIND_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HProtocolBindRemoveTask(HProtocolBind_t index) {
|
||||||
|
const uint8_t id = GET_ID(index);
|
||||||
|
index = GET_INDEX(index);
|
||||||
|
if (id >= HPROTOCOL_BIND_MAX) {
|
||||||
|
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 0 || index >= sBindRegisters[id].len) {
|
||||||
|
LogD("error index[%d], len[%d]", index, sBindRegisters[id].len);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeItem(id, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t HProtocolBindIsTimeout(HProtocolBind_t index) {
|
||||||
|
const uint8_t id = GET_ID(index);
|
||||||
|
index = GET_INDEX(index);
|
||||||
|
if (id >= HPROTOCOL_BIND_MAX) {
|
||||||
|
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 0 || index >= sBindRegisters[id].len) {
|
||||||
|
LogD("error index[%d], len[%d]", index, sBindRegisters[id].len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sBindRegisters[id].binds[index].isTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HProtocolBindUpdateData(HProtocolBindId_t id, HProtocolBindFunc_t func, void* data, uint16_t len) {
|
||||||
|
if (id >= HPROTOCOL_BIND_MAX) {
|
||||||
|
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sBindRegisters[id].enable == 0) {
|
||||||
|
LogD("not enable, id[%d]", id);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 减少扫描次数
|
||||||
|
if (sBindRegisters[id].useLen == 0) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) {
|
||||||
|
if (sBindRegisters[id].binds[i].enable == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sBindRegisters[id].binds[i].func != func) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sBindRegisters[id].binds[i].isTimeout) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可能是同一个功能码绑定多个回调
|
||||||
|
if (sBindRegisters[id].binds[i].callback) {
|
||||||
|
sBindRegisters[id].binds[i].callback(CREATE_INDEX(id, i), (uint8_t*)data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回调后立即释放
|
||||||
|
FreeItem(id, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HProtocolBindRun(HProtocolBindId_t id)
|
||||||
|
{
|
||||||
|
if (id >= HPROTOCOL_BIND_MAX) {
|
||||||
|
LogD("error id[%d], max[%d]", id, HPROTOCOL_BIND_MAX);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sBindRegisters[id].enable == 0) {
|
||||||
|
LogD("not enable, id[%d]", id);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 减少扫描次数
|
||||||
|
if (sBindRegisters[id].useLen == 0) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < sBindRegisters[id].len; ++i) {
|
||||||
|
if (sBindRegisters[id].binds[i].enable == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sBindRegisters[id].binds[i].isTimeout) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HDLogGetTime() - sBindRegisters[id].binds[i].lastTime >= sBindRegisters[id].binds[i].delayMs) {
|
||||||
|
sBindRegisters[id].binds[i].isTimeout = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可能是同一个功能码绑定多个回调
|
||||||
|
if (sBindRegisters[id].binds[i].callback) {
|
||||||
|
sBindRegisters[id].binds[i].callback(CREATE_INDEX(id, i), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回调后立即释放
|
||||||
|
FreeItem(id, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -103,21 +103,21 @@ uint32_t HTimerGetMs() {
|
|||||||
return GetCurrentMs();
|
return GetCurrentMs();
|
||||||
}
|
}
|
||||||
|
|
||||||
HTimer_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen) {
|
uint8_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen) {
|
||||||
if (id >= HTIMER_REGISTER_MAX) {
|
if (id >= HTIMER_REGISTER_MAX) {
|
||||||
LogD("error id[%d], max[%d]", id, HTIMER_REGISTER_MAX);
|
LogD("error id[%d], max[%d]", id, HTIMER_REGISTER_MAX);
|
||||||
return HTIMER_INVALID;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sTimeRegisters[id].enable == 1) {
|
if (sTimeRegisters[id].enable == 1) {
|
||||||
LogD("id[%d] already register", id);
|
LogD("id[%d] already register", id);
|
||||||
return HTIMER_INVALID;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sTimeRegisters[id].timers = info;
|
sTimeRegisters[id].timers = info;
|
||||||
sTimeRegisters[id].len = infoLen;
|
sTimeRegisters[id].len = infoLen;
|
||||||
sTimeRegisters[id].enable = 1;
|
sTimeRegisters[id].enable = 1;
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTimerRemoveRegister(uint8_t id) {
|
void HTimerRemoveRegister(uint8_t id) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user