fix(add): 新增resp功能

This commit is contained in:
chenyf 2024-11-21 16:59:31 +08:00
parent 70fb05c650
commit c31caa0e72
7 changed files with 268 additions and 227 deletions

View File

@ -16,7 +16,11 @@
"list.h": "c", "list.h": "c",
"array": "c", "array": "c",
"string": "c", "string": "c",
"string_view": "c" "string_view": "c",
"windows.h": "c",
"string.h": "c",
"stdio.h": "c",
"stdlib.h": "c"
}, },
"makefile.launchConfigurations": [ "makefile.launchConfigurations": [
{ {

View File

@ -9,14 +9,11 @@
erpc_sleep erpc_sleep_tick = NULL; erpc_sleep erpc_sleep_tick = NULL;
static list_t erpc_hw; static list_t erpc_hw;
void clean_cache(erpc_hw_cfg_t *hw) void clean_cache(erpc_hw_cfg_t *hw) {
{ for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) {
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++)
{
hw->rec_cache->state = ERPC_CMD_NO_ERROR; hw->rec_cache->state = ERPC_CMD_NO_ERROR;
} }
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) {
{
hw->send_cache[i].state = ERPC_CMD_NO_ERROR; hw->send_cache[i].state = ERPC_CMD_NO_ERROR;
} }
} }
@ -24,35 +21,29 @@ void clean_cache(erpc_hw_cfg_t *hw)
* hardware * hardware
* 线 * 线
*/ */
u32 erpc_hw_add(erpc_hw_cfg_t *hw) u32 erpc_hw_add(erpc_hw_cfg_t *hw) {
{
list_t *list = &erpc_hw; list_t *list = &erpc_hw;
if (list->data == NULL) if (list->data == NULL) {
{
list->data = (void *)hw; list->data = (void *)hw;
clean_cache(hw); clean_cache(hw);
return ERPC_NO_ERROR; return ERPC_NO_ERROR;
} }
list_t *list_node = malloc(sizeof(list_t)); list_t *list_node = malloc(sizeof(list_t));
if (list_node == NULL) if (list_node == NULL) {
{
return ERPC_ERR_MALLOC_ERROR; return ERPC_ERR_MALLOC_ERROR;
} }
list_node->data = (void *)hw; list_node->data = (void *)hw;
u8 hw_ord = hw->ord; u8 hw_ord = hw->ord;
// 检查hw是否已经存在 // 检查hw是否已经存在
while (list != NULL) while (list != NULL) {
{
erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data; erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
if (hw_cfg->ord == hw_ord) if (hw_cfg->ord == hw_ord) {
{
return ERPC_ERR_HW_EXIST; return ERPC_ERR_HW_EXIST;
} }
list = list->next; list = list->next;
} }
list_t *result = list_append(&erpc_hw, hw); list_t *result = list_append(&erpc_hw, hw);
if (result == NULL) if (result == NULL) {
{
return ERPC_ERR_MALLOC_ERROR; return ERPC_ERR_MALLOC_ERROR;
} }
clean_cache(hw); clean_cache(hw);
@ -62,17 +53,14 @@ 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_add_cmd_list(erpc_hw_cfg_t *hw, erpc_cmd_list_t *cmd_list) {
{
list_t *list = &hw->cmd_list; list_t *list = &hw->cmd_list;
if (list->data == NULL) if (list->data == NULL) {
{
list->data = (void *)cmd_list; list->data = (void *)cmd_list;
return ERPC_NO_ERROR; return ERPC_NO_ERROR;
} }
list = list_append(&hw->cmd_list, cmd_list); list = list_append(&hw->cmd_list, cmd_list);
if (list == NULL) if (list == NULL) {
{
return ERPC_ERR_MALLOC_ERROR; return ERPC_ERR_MALLOC_ERROR;
} }
return ERPC_NO_ERROR; return ERPC_NO_ERROR;
@ -81,18 +69,14 @@ u32 erpc_add_cmd_list(erpc_hw_cfg_t *hw, erpc_cmd_list_t *cmd_list)
* hardware * hardware
* 线 * 线
*/ */
u32 erpc_hw_remove(u8 hw) u32 erpc_hw_remove(u8 hw) {
{
list_t *list = &erpc_hw; list_t *list = &erpc_hw;
if (list->data == NULL) if (list->data == NULL) {
{
return ERPC_ERR_NOFOND_HW; return ERPC_ERR_NOFOND_HW;
} }
while (list != NULL) while (list != NULL) {
{
erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data; erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
if (hw_cfg->ord == hw) if (hw_cfg->ord == hw) {
{
list_delete(&erpc_hw, list); list_delete(&erpc_hw, list);
free(list); free(list);
return ERPC_NO_ERROR; return ERPC_NO_ERROR;
@ -104,87 +88,78 @@ u32 erpc_hw_remove(u8 hw)
/** /**
* hardware * hardware
*/ */
erpc_hw_cfg_t *erpc_hw_get(u8 hw) erpc_hw_cfg_t *erpc_hw_get(u8 hw) {
{
list_t *list = &erpc_hw; list_t *list = &erpc_hw;
if (list->data == NULL) if (list->data == NULL) {
{
return NULL; return NULL;
} }
while (list != NULL) while (list != NULL) {
{
erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data; erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
if (hw_cfg->ord == hw) if (hw_cfg->ord == hw) {
{
return hw_cfg; return hw_cfg;
} }
} }
return NULL; return NULL;
} }
u32 erpc_send_base(erpc_hw_cfg_t *hw_cfg, u8 dest_id, u16 port, u8 package_type,
u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len) u8 *data, u16 len) {
{
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW); CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
u8 cache_ord = 255; u8 cache_ord = 255;
// 查找可用的发送缓存 // 查找可用的发送缓存
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) {
{ if (hw_cfg->send_cache[i].state == ERPC_CMD_NO_ERROR) {
if (hw_cfg->send_cache[i].state == ERPC_CMD_NO_ERROR)
{
printf("find send cache %d\n", i); printf("find send cache %d\n", i);
cache_ord = i; cache_ord = i;
break; break;
} }
} }
CHECK_IF_ERROR(cache_ord == 255, ERPC_ERR_SEND_CACHE_FULL); CHECK_IF_ERROR(cache_ord == 255, ERPC_ERR_SEND_CACHE_FULL);
// 准备数据 // 准备数据
hw_cfg->send_cache[cache_ord].state = ERPC_CMD_DATA_DEAL; hw_cfg->send_cache[cache_ord].state = ERPC_CMD_DATA_DEAL;
erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw_cfg->send_cache[cache_ord].data[0]; erpc_cmd_def_t *cmd =
(erpc_cmd_def_t *)&hw_cfg->send_cache[cache_ord].data[0];
cmd->head.dest_id = dest_id; cmd->head.dest_id = dest_id;
cmd->head.port = port; cmd->head.port = port;
cmd->head.msg_len = len; cmd->head.msg_len = len;
cmd->head.type = PACKAGE_TYPE_CMD_REQ; if (data != NULL) {
cmd->head.msg_len = 0;
}
cmd->head.type = package_type;
cmd->head.src_id = hw_cfg->local_id; cmd->head.src_id = hw_cfg->local_id;
memcpy(cmd->data, data, len); if (len > 0 && data != NULL) {
memcpy(cmd->data, data, len);
}
// 计算校验和 // 计算校验和
cmd_cal_crc16(cmd); cmd_cal_crc16(cmd);
// 发送数据 // 发送数据
hw_cfg->send_cache[cache_ord].state = ERPC_CMD_WAIT_SEND; hw_cfg->send_cache[cache_ord].state = ERPC_CMD_WAIT_SEND;
// 等待数据发送完成 // 等待数据发送完成
int wait_time = CMD_TIMEOUT; int wait_time = CMD_TIMEOUT;
while (wait_time > 0) while (wait_time > 0) {
{ if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_OK) {
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_OK)
{
break; break;
} }
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_DEST_BUSY) if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_DEST_BUSY) {
{
return ERPC_ERR_DEST_BUSY; return ERPC_ERR_DEST_BUSY;
} }
if (erpc_sleep_tick != NULL) if (erpc_sleep_tick != NULL) {
{
erpc_sleep_tick(1); erpc_sleep_tick(1);
} }
wait_time--; wait_time--;
} }
u32 ret = ERPC_NO_ERROR; u32 ret = ERPC_NO_ERROR;
do do {
{ if (wait_time == 0) {
if (wait_time == 0)
{
ret = ERPC_ERR_SEND_TIMEOUT; ret = ERPC_ERR_SEND_TIMEOUT;
break; break;
} }
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_ONCE) if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_ONCE) {
{
ret = ERPC_ERR_DEST_NO_RESPONSE; ret = ERPC_ERR_DEST_NO_RESPONSE;
break; break;
} }
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_REPEAT) if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_REPEAT) {
{
ret = ERPC_ERR_DEST_NO_RESPONSE; ret = ERPC_ERR_DEST_NO_RESPONSE;
break; break;
} }
@ -192,13 +167,69 @@ u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len)
hw_cfg->send_cache[cache_ord].state = ERPC_CMD_NO_ERROR; hw_cfg->send_cache[cache_ord].state = ERPC_CMD_NO_ERROR;
return ret; return ret;
} }
u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len) {
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
u32 ret =
erpc_send_base(hw_cfg, dest_id, port, PACKAGE_TYPE_CMD_REQ, data, len);
return ret;
}
u32 erpc_send_data(erpc_hw_cfg_t *hw) u32 erpc_wait_resp_package(u8 hw, u8 dest_id, u16 port, u8 *reply_data,
{ u16 *reply_len, u32 time_out) {
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
{ CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
if (hw->send_cache[i].state == ERPC_CMD_WAIT_SEND) while (time_out > 0) {
{ for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) {
erpc_data_cache_t *rec_cahce = &hw_cfg->rec_cache[i];
if (rec_cahce->state != ERPC_CMD_RESP_OK) {
continue;
}
erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&rec_cahce->data[0];
if (cmd->head.port != port) {
continue;
}
if (cmd->head.src_id != dest_id) {
continue;
}
if (reply_data != NULL) {
memccpy(reply_data, cmd->data, 0, cmd->head.msg_len);
*reply_len = cmd->head.msg_len;
}
rec_cahce->state = ERPC_CMD_NO_ERROR;
return ERPC_NO_ERROR;
}
if (erpc_sleep_tick != NULL) {
erpc_sleep_tick(1);
}
time_out--;
}
CHECK_IF_ERROR(time_out == 0, ERPC_ERR_DEST_NO_REPLY);
return ERPC_NO_ERROR;
}
u32 erpc_send_wait_reply(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len,
u8 *reply_data, u16 *reply_len, u32 timeout) {
u32 ret = erpc_send(hw, dest_id, port, data, len);
if (reply_len != NULL) {
*reply_len = 0;
}
CHECK_IF_ERROR(ret != ERPC_NO_ERROR, ret);
printf("send ok\n");
ret =
erpc_wait_resp_package(hw, dest_id, port, reply_data, reply_len, timeout);
CHECK_IF_ERROR(ret != ERPC_NO_ERROR, ret);
return ERPC_NO_ERROR;
}
u32 erpc_replay(u8 hw, u8 dest_id, u16 port, u8 *data_out, u16 len) {
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
u32 ret = erpc_send_base(hw_cfg, dest_id, port, PACKAGE_TYPE_CMD_REPEAT,
data_out, len);
return ret;
}
u32 erpc_send_data(erpc_hw_cfg_t *hw) {
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) {
if (hw->send_cache[i].state == ERPC_CMD_WAIT_SEND) {
erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->send_cache[i].data[0]; erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd->head.msg_len; u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd->head.msg_len;
hw->send_lock(); hw->send_lock();
@ -208,17 +239,15 @@ u32 erpc_send_data(erpc_hw_cfg_t *hw)
hw->send_cache[i].state = ERPC_CMD_SEND_ONCE; hw->send_cache[i].state = ERPC_CMD_SEND_ONCE;
} }
} }
return ERPC_NO_ERROR;
} }
u32 erpc_rev_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) u32 erpc_rev_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
{ for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) {
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE ||
{ hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT) {
if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE || hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT)
{
erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0]; erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
if (cmd_rev->head.port == cmd_send->head.port) if (cmd_rev->head.port == cmd_send->head.port) {
{
hw->send_cache[i].state = ERPC_CMD_SEND_OK; hw->send_cache[i].state = ERPC_CMD_SEND_OK;
return ERPC_NO_ERROR; return ERPC_NO_ERROR;
} }
@ -226,30 +255,41 @@ u32 erpc_rev_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
} }
return ERPC_NO_ERROR; return ERPC_NO_ERROR;
} }
u32 erpc_rev_resp_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
erpc_cmd_def_t cmd_send;
cmd_send.head.dest_id = cmd_rev->head.src_id;
cmd_send.head.port = cmd_rev->head.port;
cmd_send.head.msg_len = 0;
cmd_send.head.type = PACKAGE_TYPE_CMD_RESP_ACK;
cmd_send.head.src_id = hw->local_id;
cmd_cal_crc16(&cmd_send);
u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd_send.head.msg_len;
hw->send_lock();
u8 ret = hw->write((u8 *)&cmd_send, len);
hw->send_unlock();
CHECK_IF_ERROR(ret != 0, ERPC_ERR_HW_SEND_FAIL);
return ERPC_NO_ERROR;
}
// 重发数据包 // 重发数据包
u32 erpc_rev_repeat_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) u32 erpc_rev_repeat_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
{ for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) {
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE ||
{ hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT) {
if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE || hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT)
{
erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0]; erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
if (cmd_rev->head.port == cmd_send->head.port) if (cmd_rev->head.port == cmd_send->head.port) {
{
u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd_send->head.msg_len; u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd_send->head.msg_len;
hw->send_lock(); hw->send_lock();
u8 ret = hw->write((u8 *)hw->send_cache[i].data, len); u32 ret = hw->write((u8 *)hw->send_cache[i].data, len);
hw->send_unlock(); hw->send_unlock();
hw->send_cache[i].state = ERPC_CMD_SEND_REPEAT; hw->send_cache[i].state = ERPC_CMD_SEND_REPEAT;
CHECK_IF_ERROR(ret, ERPC_ERR_HW_SEND_FAIL); //
return ERPC_NO_ERROR; return ERPC_NO_ERROR;
} }
} }
} }
return ERPC_NO_ERROR; return ERPC_NO_ERROR;
} }
u32 erpc_send_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) u32 erpc_send_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
{
erpc_cmd_def_t cmd_send; erpc_cmd_def_t cmd_send;
cmd_send.head.dest_id = cmd_rev->head.src_id; cmd_send.head.dest_id = cmd_rev->head.src_id;
cmd_send.head.port = cmd_rev->head.port; cmd_send.head.port = cmd_rev->head.port;
@ -265,73 +305,68 @@ u32 erpc_send_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
return ERPC_NO_ERROR; return ERPC_NO_ERROR;
} }
u32 erpc_rev_package(erpc_hw_cfg_t *hw) u32 erpc_rev_package(erpc_hw_cfg_t *hw) {
{ for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) {
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) if (hw->rec_cache[i].state == ERPC_CMD_WAIT_SERVER_DEAL) {
{
if (hw->rec_cache[i].state == ERPC_CMD_WAIT_SERVER_DEAL)
{
erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->rec_cache[i].data[0]; erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->rec_cache[i].data[0];
// 检查crc // 检查crc
u8 crc_result = cmd_check_crc16(cmd); u8 crc_result = cmd_check_crc16(cmd);
// 丢弃错误数据包 // 丢弃错误数据包
if (crc_result) if (crc_result) {
{
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR; hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
continue; continue;
} }
// 丢弃不是本地数据包 // 丢弃不是本地数据包
if (cmd->head.dest_id != hw->local_id) if (cmd->head.dest_id != hw->local_id) {
{
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR; hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
continue; continue;
} }
// 处理数据包 // 处理数据包
switch (cmd->head.type) switch (cmd->head.type) {
{ case PACKAGE_TYPE_CMD_REQ:
case PACKAGE_TYPE_CMD_REQ: printf("{REQ}\n");
erpc_send_ack_package(hw, cmd); erpc_send_ack_package(hw, cmd);
hw->rec_cache[i].state = ERPC_CMD_WAIT_TASK_DEAL; hw->rec_cache[i].state = ERPC_CMD_WAIT_TASK_DEAL;
break; break;
case PACKAGE_TYPE_CMD_REQ_ACK: case PACKAGE_TYPE_CMD_REQ_ACK:
erpc_rev_ack_package(hw, cmd); case PACKAGE_TYPE_CMD_RESP_ACK:
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR; printf("{ACK}\n");
break; erpc_rev_ack_package(hw, cmd);
case PACKAGE_TYPE_CMD_REPEAT: hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
erpc_rev_repeat_package(hw, cmd); break;
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR; case PACKAGE_TYPE_CMD_REPEAT:
break; erpc_rev_repeat_package(hw, cmd);
default: hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
break;
case PACKAGE_TYPE_CMD_RESP:
printf("{RESP}\n");
erpc_rev_resp_package(hw, cmd);
hw->rec_cache[i].state = ERPC_CMD_RESP_OK;
break;
default:
break; break;
} }
} }
} }
return ERPC_NO_ERROR;
} }
void erpc_rev_package_core() void erpc_rev_package_core() {
{
list_t *list = &erpc_hw; list_t *list = &erpc_hw;
if (list->data == NULL) if (list->data == NULL) {
{
return; return;
} }
while (list != NULL) while (list != NULL) {
{
erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data; erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
erpc_rev_package(hw); erpc_rev_package(hw);
list = list->next; list = list->next;
} }
} }
u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len) u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len) {
{
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw); erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW); CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) {
{ if (hw_cfg->rec_cache[i].state == ERPC_CMD_NO_ERROR) {
if (hw_cfg->rec_cache[i].state == ERPC_CMD_NO_ERROR)
{
printf("set rev cache %d\r\n", i); printf("set rev cache %d\r\n", i);
memcpy(hw_cfg->rec_cache[i].data, data, len); memcpy(hw_cfg->rec_cache[i].data, data, len);
hw_cfg->rec_cache[i].state = ERPC_CMD_WAIT_SERVER_DEAL; hw_cfg->rec_cache[i].state = ERPC_CMD_WAIT_SERVER_DEAL;
@ -340,77 +375,63 @@ u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len)
} }
return ERPC_ERR_REC_CACHE_FULL; return ERPC_ERR_REC_CACHE_FULL;
} }
void erpc_send_deal_core() void erpc_send_deal_core() {
{
list_t *list = &erpc_hw; list_t *list = &erpc_hw;
if (list->data == NULL) if (list->data == NULL) {
{
return; return;
} }
while (list != NULL) while (list != NULL) {
{
erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data; erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
erpc_send_data(hw); erpc_send_data(hw);
} }
if (erpc_sleep_tick != NULL) if (erpc_sleep_tick != NULL) {
{
erpc_sleep_tick(1); erpc_sleep_tick(1);
} }
} }
void erpc_rev_deal_core() void erpc_rev_deal_core() {
{
list_t *list = &erpc_hw; list_t *list = &erpc_hw;
if (list->data == NULL) if (list->data == NULL) {
{
return; return;
} }
while (list != NULL) while (list != NULL) {
{
erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data; erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
{ // 遍历接收缓存 { // 遍历接收缓存
for (int j = 0; j < MAX_REC_CMD_CACHE_NUM; j++) for (int j = 0; j < MAX_REC_CMD_CACHE_NUM; j++) {
{ { // 发现等待处理的数据包
{ // 发现等待处理的数据包 if (hw->rec_cache[j].state != ERPC_CMD_WAIT_TASK_DEAL) {
if (hw->rec_cache[j].state != ERPC_CMD_WAIT_TASK_DEAL)
{
continue; continue;
} }
} }
{ // 多线程下,抢占处理权限 { // 多线程下,抢占处理权限
hw->deal_lock(); hw->deal_lock();
if (hw->rec_cache[j].state == ERPC_CMD_WAIT_TASK_DEAL) if (hw->rec_cache[j].state == ERPC_CMD_WAIT_TASK_DEAL) {
{
// 获取指令的处理权限 // 获取指令的处理权限
hw->rec_cache[j].state = ERPC_CMD_WAIT_TASK_DEAL_FINISH; hw->rec_cache[j].state = ERPC_CMD_WAIT_TASK_DEAL_FINISH;
} } else {
else
{
// 已经有线程抢先执行了 // 已经有线程抢先执行了
hw->deal_unlock(); hw->deal_unlock();
continue; continue;
} }
hw->deal_unlock(); hw->deal_unlock();
} }
{ // 处理指令 { // 处理指令
// 搜索指令列表 // 搜索指令列表
list_t *cmd_list = &hw->cmd_list; list_t *cmd_list = &hw->cmd_list;
// 链表是空的 // 链表是空的
if (cmd_list->data == NULL) if (cmd_list->data == NULL) {
{
continue; continue;
} }
// 获取指令指针 // 获取指令指针
erpc_cmd_def_t *cmd_def = (erpc_cmd_def_t *)hw->rec_cache[j].data; erpc_cmd_def_t *cmd_def = (erpc_cmd_def_t *)hw->rec_cache[j].data;
while (cmd_list != NULL) while (cmd_list != NULL) { // 搜索指令列表
{ // 搜索指令列表
erpc_cmd_list_t *cmd_obj = (erpc_cmd_list_t *)cmd_list->data; erpc_cmd_list_t *cmd_obj = (erpc_cmd_list_t *)cmd_list->data;
if (cmd_obj->cmd == cmd_def->head.port) if (cmd_obj->cmd == cmd_def->head.port) {
{ if (cmd_obj->handle != NULL) {
if (cmd_obj->handle != NULL)
{
// 指令调用 // 指令调用
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); 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);
} }
break; break;
@ -424,8 +445,7 @@ void erpc_rev_deal_core()
} }
list = list->next; list = list->next;
} }
if (erpc_sleep_tick != NULL) if (erpc_sleep_tick != NULL) {
{
erpc_sleep_tick(1); erpc_sleep_tick(1);
} }
} }

View File

@ -1,21 +1,21 @@
#ifndef ERPC_CORE_H_ #ifndef ERPC_CORE_H_
#define ERPC_CORE_H_ #define ERPC_CORE_H_
#include "config.h"
#include "list.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "config.h"
#include "list.h"
#define ERPC_VERSION "0.0.1" #define ERPC_VERSION "0.0.1"
typedef enum package_type typedef enum package_type {
{
PACKAGE_TYPE_DEV_POWER_ON = 0, PACKAGE_TYPE_DEV_POWER_ON = 0,
PACKAGE_TYPE_CMD_REQ, PACKAGE_TYPE_CMD_REQ,
PACKAGE_TYPE_CMD_REQ_ACK, PACKAGE_TYPE_CMD_REQ_ACK,
PACKAGE_TYPE_CMD_RESP, PACKAGE_TYPE_CMD_RESP,
PACKAGE_TYPE_CMD_RESP_ACK, PACKAGE_TYPE_CMD_RESP_ACK,
PACKAGE_TYPE_CMD_REPEAT, // crc校验失败请求重发 PACKAGE_TYPE_CMD_REPEAT, // crc校验失败请求重发
PACKAGE_TYPE_DEV_POWER_OFF, PACKAGE_TYPE_DEV_POWER_OFF,
PACKAGE_TYPE_CMD_SERCH_DEV_ONLINE, PACKAGE_TYPE_CMD_SERCH_DEV_ONLINE,
} package_type; } package_type;
@ -23,61 +23,58 @@ typedef enum package_type
// 广播ID // 广播ID
#define ERPC_BOARDCAST_ID 0xff #define ERPC_BOARDCAST_ID 0xff
typedef struct erpc_cmd_head_t typedef struct erpc_cmd_head_t {
{
u8 src_id; u8 src_id;
u8 dest_id; u8 dest_id;
package_type type; u8 type; // package_type
u16 port; // 指令号,指令号=端口号 u16 port; // 指令号,指令号=端口号
u8 msg_len; u8 msg_len;
} erpc_cmd_head_t; } erpc_cmd_head_t;
typedef struct erpc_cmd_def_t typedef struct erpc_cmd_def_t {
{
erpc_cmd_head_t head; erpc_cmd_head_t head;
u8 crc_16[2]; u8 crc_16[2];
u8 *data; u8 *data;
} erpc_cmd_def_t; } erpc_cmd_def_t;
#define MAX_CMD_LEN (256 - sizeof(erpc_cmd_head_t)) // crc16最大支持256字节 #define MAX_CMD_LEN (256 - sizeof(erpc_cmd_head_t)) // crc16最大支持256字节
#define CMD_MAX_RETRY 5 // 最大重发次数 #define CMD_MAX_RETRY 5 // 最大重发次数
#define CMD_TIMEOUT 30 // 超时时间 tick #define CMD_TIMEOUT 30 // 超时时间 tick
#define MAX_REC_CMD_CACHE_NUM 10 // 最大接收指令缓存数量,接受指令优先级>处理指令优先级 #define MAX_REC_CMD_CACHE_NUM \
#define MAX_SEND_CMD_CACHE_NUM 10 // 最大发送指令缓存数量,发送指令优先级>接收指令优先级 10 // 最大接收指令缓存数量,接受指令优先级>处理指令优先级
typedef enum erpc_status #define MAX_SEND_CMD_CACHE_NUM \
{ 10 // 最大发送指令缓存数量,发送指令优先级>接收指令优先级
ERPC_CMD_NO_ERROR, // 发送cache接收cache空闲 typedef enum erpc_status {
ERPC_CMD_DATA_DEAL, // 发送cache数据组织中 ERPC_CMD_NO_ERROR, // 发送cache接收cache空闲
ERPC_CMD_WAIT_SERVER_DEAL, // 等待服务线程处理接受cache ERPC_CMD_DATA_DEAL, // 发送cache数据组织中
ERPC_CMD_WAIT_TASK_DEAL, // 等待任务线程处理指令 ERPC_CMD_WAIT_SERVER_DEAL, // 等待服务线程处理接受cache
ERPC_CMD_WAIT_TASK_DEAL_FINISH, // 等待任务线程处理指令完成 ERPC_CMD_WAIT_TASK_DEAL, // 等待任务线程处理指令
ERPC_CMD_WAIT_SEND, // 等待服务线程处理发送cache ERPC_CMD_WAIT_TASK_DEAL_FINISH, // 等待任务线程处理指令完成
ERPC_CMD_SEND_ONCE, // 发送指令成功 ERPC_CMD_WAIT_SEND, // 等待服务线程处理发送cache
ERPC_CMD_SEND_REPEAT, // 发送指令重发 ERPC_CMD_SEND_ONCE, // 发送指令成功
ERPC_CMD_SEND_OK, // 发送指令成功 ERPC_CMD_SEND_REPEAT, // 发送指令重发
ERPC_CMD_DEST_BUSY, // 目标设备忙 ERPC_CMD_SEND_OK, // 发送指令成功
ERPC_CMD_DEST_BUSY, // 目标设备忙
ERPC_CMD_RESP_OK, // 指令响应成功
} erpc_status; } erpc_status;
typedef struct erpc_data_cache_t typedef struct erpc_data_cache_t {
{
u8 state; u8 state;
u8 data[256]; u8 data[256];
} erpc_data_cache_t; } erpc_data_cache_t;
typedef u32 (*erpc_cmd_handle_t)(u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len); typedef u32 (*erpc_cmd_handle_t)(u8 src_id, u8 dest_id, u16 port, u8 *data,
u16 len);
typedef struct erpc_cmd_list_t typedef struct erpc_cmd_list_t {
{
u16 cmd; u16 cmd;
u32 (*handle)(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len); u32 (*handle)(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len);
} erpc_cmd_list_t; } erpc_cmd_list_t;
typedef enum ERPC_ROLE typedef enum ERPC_ROLE {
{
ERPC_ROLE_MASTER, ERPC_ROLE_MASTER,
ERPC_ROLE_SLAVE, ERPC_ROLE_SLAVE,
} ERPC_ROLE; } ERPC_ROLE;
typedef struct erpc_hw_cfg_t typedef struct erpc_hw_cfg_t {
{
u8 ord; u8 ord;
u8 local_id; u8 local_id;
u8 (*write)(u8 *data, u16 len); u8 (*write)(u8 *data, u16 len);
@ -91,40 +88,49 @@ typedef struct erpc_hw_cfg_t
} erpc_hw_cfg_t; } erpc_hw_cfg_t;
#define CHECK_IF_ERROR(condition, error) \ #define CHECK_IF_ERROR(condition, error) \
if (condition) \ if (condition) { \
{ \
return error; \ return error; \
} }
#define CHECK_IF_ERROR_AND_DO(condition, error, action) \ #define CHECK_IF_ERROR_AND_DO(condition, error, action) \
if (condition) \ if (condition) { \
{ \
action; \ action; \
return error; \ return error; \
} }
typedef enum erpc_error typedef enum erpc_error {
{
ERPC_NO_ERROR = 0, ERPC_NO_ERROR = 0,
ERPC_ERR_NOFOND_HW, ERPC_ERR_NOFOND_HW,
ERPC_ERR_SEND_CACHE_FULL, ERPC_ERR_SEND_CACHE_FULL,
ERPC_ERR_SEND_TIMEOUT, ERPC_ERR_SEND_TIMEOUT,
ERPC_ERR_HW_SEND_FAIL, // 硬件层发来的错误 erpc_hw_cfg_t.write返回错误 ERPC_ERR_HW_SEND_FAIL, // 硬件层发来的错误 erpc_hw_cfg_t.write返回错误
ERPC_ERR_DEST_BUSY, ERPC_ERR_DEST_BUSY,
ERPC_ERR_DEST_NO_RESPONSE, // 目标设备无响应 ERPC_ERR_DEST_NO_RESPONSE, // 目标设备无响应
ERPC_ERR_MALLOC_ERROR, // malloc失败,内存不足 ERPC_ERR_DEST_NO_REPLY, // 目标设备无回复或者回复超时
ERPC_ERR_HW_EXIST, // 硬件已经存在 ERPC_ERR_MALLOC_ERROR, // malloc失败,内存不足
ERPC_ERR_HW_NOT_EXIST, // 硬件不存在 ERPC_ERR_HW_EXIST, // 硬件已经存在
ERPC_ERR_REC_CACHE_FULL, // 接收缓存满 ERPC_ERR_HW_NOT_EXIST, // 硬件不存在
ERPC_ERR_REC_CACHE_FULL, // 接收缓存满
} erpc_error; } erpc_error;
typedef void (*erpc_sleep)(u32 tick); 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); // 写入接受缓存 u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len); // 写入接受缓存
void erpc_rev_package_core(); // 处理接受到的包,通讯层面处理 void erpc_rev_package_core(); // 处理接受到的包,通讯层面处理
void erpc_rev_deal_core(); // 处理接受到的指令,业务层面处理 void erpc_rev_deal_core(); // 处理接受到的指令,业务层面处理
extern erpc_sleep erpc_sleep_tick; extern erpc_sleep erpc_sleep_tick;
u32 erpc_hw_add(erpc_hw_cfg_t *hw); 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_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); u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len);
/**
*
*/
u32 erpc_send_wait_reply(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len,
u8 *reply_data, u16 *reply_len, u32 timeout);
/**
*
*/
u32 erpc_replay(u8 hw, u8 dest_id, u16 port, u8 *data_out, u16 len);
#endif /* ERPC_CORE_H_ */ #endif /* ERPC_CORE_H_ */

Binary file not shown.

View File

@ -14,9 +14,17 @@ void hello_cat()
{ {
printf("Hello Cat!\n"); printf("Hello Cat!\n");
} }
void hello_dog(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len)
{
printf("Hello Dog!\n");
u8 data_out[10] = "12345";
erpc_replay(hw, dest_id, port, data_out, sizeof(data_out));
}
erpc_cmd_list_t erpc_cmd_list[] = { erpc_cmd_list_t erpc_cmd_list[] = {
{.cmd = 0x01, hellworld}, {.cmd = 0x01, hellworld},
{.cmd = 0x02, hello_cat}, {.cmd = 0x02, hello_cat},
{.cmd = 0x03, hello_dog},
}; };
HANDLE deal_lock; HANDLE deal_lock;
@ -93,8 +101,11 @@ DWORD WINAPI test_task(LPVOID lpParam)
{ {
// printf("[test_task]send\n"); // printf("[test_task]send\n");
u32 ret = erpc_send(self_hw_cfg.ord, self_hw_cfg.local_id, 0x01, NULL, 0); u32 ret = erpc_send(self_hw_cfg.ord, self_hw_cfg.local_id, 0x01, NULL, 0);
printf("[test_task]send ret:%d\n", ret);
ret = erpc_send(self_hw_cfg.ord, self_hw_cfg.local_id, 0x02, NULL, 0); ret = erpc_send(self_hw_cfg.ord, self_hw_cfg.local_id, 0x02, NULL, 0);
printf("[test_task]send ret:%d\n", ret); printf("[test_task]send ret:%d\n", ret);
ret = erpc_send_wait_reply(self_hw_cfg.ord, self_hw_cfg.local_id, 0x03, NULL, 0, data, NULL, 1000);
printf("[test_task]send ret:%d\n", ret);
sys_sleep(1000); sys_sleep(1000);
} }
} }

Binary file not shown.

Binary file not shown.