1. 新增协议绑定模块

This commit is contained in:
coffee 2025-10-21 16:18:53 +08:00
parent 82b9dfaa0c
commit e76325dd2e
6 changed files with 313 additions and 15 deletions

View File

@ -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
View 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_

View File

@ -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);

View File

@ -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
View 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);
}
}

View File

@ -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) {