From 3a20363f232b5e5ec6189b241d85893dd3422f40 Mon Sep 17 00:00:00 2001 From: coffee Date: Mon, 8 Sep 2025 14:58:58 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E5=AE=8C=E5=96=84RPC=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HDRPC.h | 63 +++++++++++++++++++++++++++++-------------------- src/HDRPC.c | 26 +++++++++++++++++--- 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/include/HDRPC.h b/include/HDRPC.h index 6a32bdb..d5295dd 100644 --- a/include/HDRPC.h +++ b/include/HDRPC.h @@ -2,6 +2,15 @@ * 日期: 2025-09-04 * 作者: coffee * 描述: ARM和MCU交互通信模块 + * demo: + * 首次需要先初始化RPC调用 + * HDRPCInitCall(发送回调, 存储RPC回调缓存, 回调缓存长度, 读取RPC会话); + * 读取数据: + * HDRPCReadData(...); + * 发送调用 + * HDRPCSendData(sesion, 枚举值, 回调函数); + * 不需要回调 + * HDRPCSendDataNotCall(sesion, 枚举值); */ #ifndef __HDRPC_H__ @@ -9,17 +18,11 @@ #include -// 无效类型 -#define HDRPC_INVAID_TYPE 0xFF - -// 无效功能 -#define HDRPC_INVAID_FUNC 0xFFFF - -// 默认超时 +// 设置超时时间 #define HDRPC_TIMEOUT 3000 // 如果使用栈参数解析, 则最大支持的参数个数 -#define HDRPC_USE_SESSION_ARGS (5) +#define HDRPC_USE_SESSION_ARGS (9) // 使用64位 // #define HDRPC_USE_64 @@ -42,7 +45,6 @@ typedef uint32_t HDRPCValue_t; * 0x11: UTF-16BE字符串, 数据首个字节为长度 * 0x20: 异常类型, u16类型 */ - enum eHDRPCType { kHDRPCUserData = 0x00, ///< 用户数据 @@ -55,6 +57,14 @@ enum eHDRPCType kHDRPCException = 0x20, ///< 异常, u16 }; +// 协议异常指令 +enum eHDRPCException { + kHDRPCNotException = 0x00, ///< 无异常 + kHDRPCNotSupportFunction = 0x01, ///< 对应功能不支持 + kHDRPCArgsTypeNotMatch = 0x02, ///< 参数类型不匹配 +}; + + typedef struct __attribute__((packed)) _HDRPCBuffer { uint8_t len; ///< 数据长度 @@ -62,7 +72,7 @@ typedef struct __attribute__((packed)) _HDRPCBuffer } _HDRPCBuffer; ///< 参数包 -typedef struct __attribute__((packed)) _HDRPCArgs +typedef struct __attribute__((packed)) HDRPCArgs { uint8_t type; ///< 类型数据 union __attribute__((packed)) @@ -79,29 +89,32 @@ typedef struct __attribute__((packed)) _HDRPCArgs typedef struct __attribute__((packed)) HDRPCSession { - uint8_t index; ///< 当前添加到的参数索引 - uint8_t len; ///< 参数总长度 - uint16_t func; ///< 调用功能, 用于解析数据得到 - HDRPCArgs *args; + uint16_t func; ///< 调用功能, 用于解析数据得到 + uint8_t index; ///< 当前添加到的参数索引 + uint8_t exceptionSkip : 1; ///< 异常时不要调用回调(默认0: 调用回调, 1: 不调用回调) + uint8_t len : 7; ///< 参数总长度 + HDRPCArgs *args; ///< 参数 } HDRPCSession; // 此宏用于其他回调的参数声明 -#define HDRPC_CALL_ARGS HDRPCSession *session -typedef void (*HDRPCCallback)(HDRPCSession *session); +#define HDRPC_CALL_ARGS HDRPCSession *session, uint8_t exception +#define HDRPC_IS_EXCEPTION() (exception != kHDRPCNotException) +typedef void (*HDRPCCallback)(HDRPCSession *session, uint8_t exception); typedef void (*HDRPCSendData)(HDRPCSession *session); -// 调用缓存, 数据由用户提供 +// 调用缓存, 内存由用户提供 typedef struct __attribute__((packed)) HDRPCCallBuffer { - uint8_t enbale : 1; - uint8_t nameLen : 7; - uint32_t time; - const char *name; - HDRPCCallback callback; + uint8_t enbale : 1; ///< 是否启用 + uint8_t nameLen : 7; ///< 函数名长度 + uint32_t time; ///< 上次调用时间 + const char *name; ///< 函数名 + HDRPCCallback callback; ///< 回调 } HDRPCCallBuffer; /** * @brief 初始化RPC会话 * @param session 参数会话 + * @param args 参数包, 用于存储参数 * @param len 参数会话长度 */ void HDRPCInitSession(HDRPCSession *session, HDRPCArgs *args, uint8_t len); @@ -109,14 +122,14 @@ void HDRPCInitSession(HDRPCSession *session, HDRPCArgs *args, uint8_t len); /** * @brief 初始化RPC调用 * @param sendCall 发送数据回调 - * @param callback 回调缓存, 用于可注册RPC回调数量 + * @param callBuff 回调缓存, 用于可注册RPC回调数量, 必须提供对应的内存, 如为空则无回调 * @param callLen 回调缓存长度 - * @param buffer 参数会话(如果不传递则使用栈分配) + * @param buffer 读取的RPC会话(如果不传递则使用栈分配) */ void HDRPCInitCall(HDRPCSendData sendCall, HDRPCCallBuffer *callBuff, uint8_t callLen, HDRPCSession *buffer); /** - * @brief 使用这个来创建栈内参数包, 内部自增一个用于存储内部需要使用的用户数据 + * @brief 使用这个来创建栈内参数包, 内部自增一个用于存储内部回调数据 * @param _name 参数包名称 * @param _len 参数包长度 */ diff --git a/src/HDRPC.c b/src/HDRPC.c index 34aa21f..1a15024 100644 --- a/src/HDRPC.c +++ b/src/HDRPC.c @@ -10,6 +10,9 @@ #define LogD(format, ...) printf("[%s:%s:%d]"format "\r\n", __FILE_NAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) #endif +// 无效功能 +#define HDRPC_INVAID_FUNC 0xFFFF + struct RPCInfo { HDRPCSendData writeCall; HDRPCCallBuffer *callback; @@ -29,13 +32,15 @@ static void UpdateTimeout(HDRPCCallBuffer *callBuff) { } uint32_t curr = HDLogGetTime(); +#ifdef HDRPC_TIMEOUT if (curr - callBuff->time > HDRPC_TIMEOUT) { callBuff->enbale = 0; LogD("Call[%s] Timeout", callBuff->name); } +#endif } -static void Call(HDRPCSession *session) { +static void Call(HDRPCSession *session, uint16_t exception) { if (session == NULL) { LogD("Session is nullptr"); return ; @@ -63,7 +68,7 @@ static void Call(HDRPCSession *session) { } LogD("Call[%s]", sInfo.callback[i].name); - sInfo.callback[i].callback(session); + sInfo.callback[i].callback(session, exception); LogD("Call[%s] End", sInfo.callback[i].name); sInfo.callback[i].enbale = 0; @@ -238,7 +243,22 @@ static void ReadCall(HDRPCSession *session, void *data, uint16_t len) { return ; } - Call(session); + uint16_t exception = kHDRPCNotException;; + for (uint8_t i = 0; i < session->index; ++i) { + if (session->args[i].type != kHDRPCException) { + continue; + } + + exception = session->args[i].dataU16; + LogD("Call type[0x%x] Exception[0x%x]", session->args[i].type, exception); + + // 开启异常跳过后, 出现异常不回调 + if (session->exceptionSkip) { + return ; + } + } + + Call(session, exception); }