From 8357f41a75cce8498c445a9b5e63ea76360cf901 Mon Sep 17 00:00:00 2001 From: chenyf <1343619937@qq.com> Date: Thu, 21 Nov 2024 00:12:48 +0800 Subject: [PATCH] =?UTF-8?q?fix(simple=20cmd)=20=E5=AE=8C=E6=88=90=E7=AE=80?= =?UTF-8?q?=E5=8D=95=E9=80=9A=E8=AE=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 7 ------ .vscode/settings.json | 14 +++++++++-- erpc_core.c | 45 +++++++++++++++++++++++++---------- erpc_core.h | 53 +++++++++++++++++++++++------------------- erpc_core.o | Bin 6128 -> 6260 bytes makefile | 6 ++--- port_self.c | 7 ++++-- port_self.exe | Bin 70831 -> 70831 bytes port_self.o | Bin 9981 -> 10021 bytes 9 files changed, 82 insertions(+), 50 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index f980ab9..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // 使用 IntelliSense 了解相关属性。 - // 悬停以查看现有属性的描述。 - // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 964e7d2..c9ee9c3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,16 @@ "erpc_core.h": "c", "type_traits": "c", "list": "c", - "list.h": "c" - } + "list.h": "c", + "array": "c", + "string": "c", + "string_view": "c" + }, + "makefile.launchConfigurations": [ + { + "cwd": "d:\\WORK\\erpc", + "binaryPath": "d:\\WORK\\erpc\\port_self.exe", + "binaryArgs": [] + } + ] } \ No newline at end of file diff --git a/erpc_core.c b/erpc_core.c index fa0db9d..570de48 100644 --- a/erpc_core.c +++ b/erpc_core.c @@ -132,6 +132,7 @@ u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len) { if (hw_cfg->send_cache[i].state == ERPC_CMD_NO_ERROR) { + printf("find send cache %d\n", i); cache_ord = i; break; } @@ -169,12 +170,28 @@ u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len) wait_time--; } - CHECK_IF_ERROR(wait_time == 0, ERPC_ERR_SEND_TIMEOUT); - CHECK_IF_ERROR(hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_ONCE, ERPC_ERR_DEST_NO_RESPONSE); - CHECK_IF_ERROR(hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_REPEAT, ERPC_ERR_DEST_NO_RESPONSE); - return ERPC_NO_ERROR; + u32 ret = ERPC_NO_ERROR; + do + { + if(wait_time == 0){ + ret = ERPC_ERR_SEND_TIMEOUT; + break; + } + if(hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_ONCE){ + ret = ERPC_ERR_DEST_NO_RESPONSE; + break; + } + if(hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_REPEAT){ + ret = ERPC_ERR_DEST_NO_RESPONSE; + break; + } + } while (0); + hw_cfg->send_cache[cache_ord].state = ERPC_CMD_NO_ERROR; + return ret; } + + u32 erpc_send_data(erpc_hw_cfg_t *hw) { for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) @@ -314,6 +331,7 @@ u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len) { if (hw_cfg->rec_cache[i].state == ERPC_CMD_NO_ERROR) { + printf("set rev cache %d\r\n", i); memcpy(hw_cfg->rec_cache[i].data, data, len); hw_cfg->rec_cache[i].state = ERPC_CMD_WAIT_SERVER_DEAL; return ERPC_NO_ERROR; @@ -352,6 +370,7 @@ void erpc_rev_deal_core() for (int j = 0; j < MAX_REC_CMD_CACHE_NUM; j++) { + // 发现等待处理的数据包 if (hw->rec_cache[j].state == ERPC_CMD_WAIT_TASK_DEAL) { // 多线程处理 @@ -368,30 +387,32 @@ void erpc_rev_deal_core() continue; } hw->deal_unlock(); - - list_t *list = &hw->cmd_list; + // 搜索指令列表 + list_t *cmd_list = &hw->cmd_list; // 链表是空的 - if (list->data == NULL) + if (cmd_list->data == NULL) { continue; } - while (list != NULL) + while (cmd_list != NULL) { - erpc_cmd_list_t *cmd_list = (erpc_cmd_list_t *)list->data; + erpc_cmd_list_t *cmd_obj = (erpc_cmd_list_t *)cmd_list->data; erpc_cmd_def_t *cmd_def = (erpc_cmd_def_t *)hw->rec_cache[j].data; - if (cmd_list->cmd == cmd_def->head.port) + if (cmd_obj->cmd == cmd_def->head.port) { - if (cmd_list->handle != NULL) + if (cmd_obj->handle != NULL) { // 指令调用 - cmd_list->handle(hw->ord, cmd_def->head.src_id, cmd_def->head.dest_id, cmd_def->head.port, cmd_def->data, cmd_def->head.msg_len); + cmd_obj->handle(hw->ord, cmd_def->head.src_id, cmd_def->head.dest_id, cmd_def->head.port, cmd_def->data, cmd_def->head.msg_len); } // 处理完成 丢弃缓存 hw->rec_cache[j].state = ERPC_CMD_NO_ERROR; } + cmd_list = cmd_list->next; } } } + list = list->next; } if (erpc_sleep_tick != NULL) { diff --git a/erpc_core.h b/erpc_core.h index cfbe330..a32907d 100644 --- a/erpc_core.h +++ b/erpc_core.h @@ -46,17 +46,17 @@ typedef struct erpc_cmd_def_t #define MAX_SEND_CMD_CACHE_NUM 10 // 最大发送指令缓存数量,发送指令优先级>接收指令优先级 typedef enum erpc_status { - ERPC_CMD_NO_ERROR, // 发送cache,接收cache空闲 - ERPC_CMD_DATA_DEAL, // 发送cache数据组织中 - ERPC_CMD_WAIT_SERVER_DEAL, // 等待服务线程处理接受cache - ERPC_CMD_WAIT_TASK_DEAL, // 等待任务线程处理指令 + ERPC_CMD_NO_ERROR, // 发送cache,接收cache空闲 + ERPC_CMD_DATA_DEAL, // 发送cache数据组织中 + ERPC_CMD_WAIT_SERVER_DEAL, // 等待服务线程处理接受cache + ERPC_CMD_WAIT_TASK_DEAL, // 等待任务线程处理指令 ERPC_CMD_WAIT_TASK_DEAL_FINISH, // 等待任务线程处理指令完成 - ERPC_CMD_WAIT_SEND, // 等待服务线程处理发送cache - ERPC_CMD_SEND_ONCE, // 发送指令成功 - ERPC_CMD_SEND_REPEAT, // 发送指令重发 - ERPC_CMD_SEND_OK, // 发送指令成功 - ERPC_CMD_DEST_BUSY, // 目标设备忙 -}erpc_status; + ERPC_CMD_WAIT_SEND, // 等待服务线程处理发送cache + ERPC_CMD_SEND_ONCE, // 发送指令成功 + ERPC_CMD_SEND_REPEAT, // 发送指令重发 + ERPC_CMD_SEND_OK, // 发送指令成功 + ERPC_CMD_DEST_BUSY, // 目标设备忙 +} erpc_status; typedef struct erpc_data_cache_t { @@ -71,7 +71,11 @@ typedef struct erpc_cmd_list_t u16 cmd; u32 (*handle)(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len); } erpc_cmd_list_t; - +typedef enum ERPC_ROLE +{ + ERPC_ROLE_MASTER, + ERPC_ROLE_SLAVE, +} ERPC_ROLE; typedef struct erpc_hw_cfg_t { u8 ord; @@ -91,7 +95,12 @@ typedef struct erpc_hw_cfg_t { \ return error; \ } - +#define CHECK_IF_ERROR_AND_DO(condition, error, action) \ + if (condition) \ + { \ + action; \ + return error; \ + } typedef enum erpc_error { ERPC_NO_ERROR = 0, @@ -101,25 +110,21 @@ typedef enum erpc_error ERPC_ERR_HW_SEND_FAIL, // 硬件层发来的错误 erpc_hw_cfg_t.write返回错误 ERPC_ERR_DEST_BUSY, ERPC_ERR_DEST_NO_RESPONSE, // 目标设备无响应 - ERPC_ERR_MALLOC_ERROR, // malloc失败,内存不足 - ERPC_ERR_HW_EXIST, // 硬件已经存在 - ERPC_ERR_HW_NOT_EXIST, // 硬件不存在 - ERPC_ERR_REC_CACHE_FULL, // 接收缓存满 -}erpc_error; + ERPC_ERR_MALLOC_ERROR, // malloc失败,内存不足 + ERPC_ERR_HW_EXIST, // 硬件已经存在 + ERPC_ERR_HW_NOT_EXIST, // 硬件不存在 + ERPC_ERR_REC_CACHE_FULL, // 接收缓存满 +} erpc_error; typedef void (*erpc_sleep)(u32 tick); - -void erpc_send_deal_core(); // 发送指令处理线程 +void erpc_send_deal_core(); // 发送指令处理线程 u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len); // 写入接受缓存 -void erpc_rev_package_core(); // 处理接受到的包,通讯层面处理 -void erpc_rev_deal_core(); // 处理接受到的指令,业务层面处理 +void erpc_rev_package_core(); // 处理接受到的包,通讯层面处理 +void erpc_rev_deal_core(); // 处理接受到的指令,业务层面处理 extern erpc_sleep erpc_sleep_tick; - - u32 erpc_hw_add(erpc_hw_cfg_t *hw); u32 erpc_add_cmd_list(erpc_hw_cfg_t *hw, erpc_cmd_list_t *cmd_list); - u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len); #endif /* ERPC_CORE_H_ */ \ No newline at end of file diff --git a/erpc_core.o b/erpc_core.o index afdbadc8b96362b9daf7da09b043ecca06b856b5..d9d50ac2cbe424258a49de7477193b386e931a5a 100644 GIT binary patch delta 1246 zcmY*YT}TvB6h5P~>+ZPjsJLr|+F;gdl-eH@6lpXuMMV$MOFbC6VPzrZN>rQDy3w)} zEf;!-2zsiX3KpWE2er_bilu_;AzFgU%|MHVHjt+8+%cC1=AQ3<=iKx2&7Ik{e7n|j zsf_q(s7Yx{syh5cs}!Q`Rg$E-)Q00qU+Q+qZB!B+s!qLZaJ9qrCiNp!qE@AsC|^qg zyGn>AOxvC`3w&z2(@O4{5?#t-(WbiBFHV|;#JF{(f_+oGfVgbh(^||dD6we4d*ShL z)V3qqBjlmn7nB#Ru7>oW>QR&@V#u{JIBCxE!B{j;5id5S*i0WpRHM%=2{#j~nJ6!d zco4zFHBO^VaKTwC_H3W{;SDMuMXNicrr{P@Pop^J?pIpH8h5>ag4{844h_wD^{ch% z=CapnfVajQa8=QqJ4Dw1+o$9xzzE(;j5O~Hj%HWAP9 zOfy*ii_d*<7#Wr@-=PhwJ7Xm>)>zhKDH-d^K7$X4W`BQO7R~7oM-#i7ns+A-H5rMq zPWx4{vD!^ey$+A89g9wp9$#kLcFfE}`#iMo`U9z?GBT(jWz*wp#dm*;sMGU9EiR(X zXo+n*KC}hQR>w`=56t#}ho}pf?N7XYz-;3h(HUU2@9~ZRvmGzTeF0|MPKU8{Hy-Zp4I9gQG&&s~FiwRBjqZ7-0*T}!Qk8dxs&Px}u~n%SXoW=Y zfkF~}25Oe*m`YSD(cl8QfmR*wK`#cC-fPJ2#O*|rPUgKpPUc}CC-Vy+#H~hQ6%#l| zDi=`O0;S2f}9t!0>~6Po)ZfnmSPyxUYm#odNMYa8?`(R*N0M Kru6yXfbtjPjyJdf delta 1133 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 delta 7107 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 VB;9J_3;FKkhYI=OTYRC zfr7_~4+?tFy+jlgTfA6$6r}VZ*rF&Xf}m(zznNj@(1EZ&zW-x4%tB|b!}ES3pYZc9 zNJvxKQ$XYC=M{7_-IXx65jU@92DQ@Do3~c#uQhfSw^AKmYsyoI(lLGn4zq~f>aTN? z^tmnq$j3)nK76uI(K>(cIFqmMQajl7!R@jpP2OQm z`G28orM#@uX!Fjv4-LSufZ>e@pSvDFD Z-Jn?>KEMyZRrhGbZ{J3bD7$)5`v4t2hhYE!