diff --git a/.$架构.drawio.bkp b/.$架构.drawio.bkp deleted file mode 100644 index faa5e5c..0000000 --- a/.$架构.drawio.bkp +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/.vscode/settings.json b/.vscode/settings.json index dfd61ea..1f11490 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,7 @@ { "files.associations": { + "*.ndjson": "jsonl", + "*.dbclient-js": "javascript", "spi_port.h": "c", "cmd_def.h": "c", "config.h": "c", @@ -20,7 +22,10 @@ "windows.h": "c", "string.h": "c", "stdio.h": "c", - "stdlib.h": "c" + "stdlib.h": "c", + "algorithm": "c", + "initializer_list": "c", + "utility": "c" }, "makefile.launchConfigurations": [ { diff --git a/build/crc16.o b/build/crc16.o index 2af0e39..39c8746 100644 Binary files a/build/crc16.o and b/build/crc16.o differ diff --git a/build/erpc_core.o b/build/erpc_core.o index bd19ae2..5c18b91 100644 Binary files a/build/erpc_core.o and b/build/erpc_core.o differ diff --git a/build/erpc_port_self.o b/build/erpc_port_self.o new file mode 100644 index 0000000..07103e8 Binary files /dev/null and b/build/erpc_port_self.o differ diff --git a/build/list.o b/build/list.o index f195381..f613a8d 100644 Binary files a/build/list.o and b/build/list.o differ diff --git a/build/port_self.o b/build/port_self.o deleted file mode 100644 index 33c53e0..0000000 Binary files a/build/port_self.o and /dev/null differ diff --git a/config.h b/config.h index 9850bae..6237f32 100644 --- a/config.h +++ b/config.h @@ -9,6 +9,14 @@ #define u32 unsigned int #define UNUSED(x) (void)(x) + + +#define ERPC_DEBUG_ENABLE 1 +#if(ERPC_DEBUG_ENABLE == 1) #define ERPC_DEBUG(...) printf(__VA_ARGS__) -// #define ERPC_DEBUG(...) +#else +#define ERPC_DEBUG(...) +#endif + + #endif /* _CONFIG_H_ */ \ No newline at end of file diff --git a/crc16.c b/crc16.c index fd32d26..c125018 100644 --- a/crc16.c +++ b/crc16.c @@ -1,6 +1,6 @@ #include "crc16.h" -static const uint16_t crc16tab[256] = { +static const u16 crc16tab[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, @@ -31,38 +31,7 @@ static const uint16_t crc16tab[256] = { 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; -// uint16_t crc16(const unsigned char *buf, size_t len) { -// int counter; -// uint16_t crc = 0; -// for (counter = 0; counter < (int)len; counter++) -// crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *buf++) & 0x00FF]; -// return crc; -// } - -u16 cmd_cal_crc16(erpc_cmd_def_t *cmd) { - u16 crc = 0; - u32 counter = 0; - crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.src_id) & 0x00FF]; - crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.dest_id) & 0x00FF]; - crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.msg_len) & 0x00FF]; - crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.type) & 0x00FF]; - crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->head.port) & 0x00FF]; - for (counter = 0; counter < cmd->head.msg_len; counter++) - crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ cmd->data[counter]) & 0x00FF]; - cmd->crc_16[0] = (u8)(crc >> 8); - cmd->crc_16[1] = (u8)(crc & 0x00FF); - return crc; -} -/** - * 检查crc16校验 - * return 0:校验成功 - * return 1:校验失败 - */ -u8 cmd_check_crc16(erpc_cmd_def_t *cmd) { - u16 crc = cmd_cal_crc16(cmd); - if (cmd->crc_16[0] != (u8)(crc >> 8) || - cmd->crc_16[1] != (u8)(crc & 0x00FF)) { - return 1; - } - return 0; -} \ No newline at end of file +inline u16 crc16_cal(u16 data,u16 crc) +{ + return (crc << 8) ^ crc16tab[((crc >> 8) ^ data) & 0x00FF]; +} diff --git a/crc16.h b/crc16.h index adb86fb..c722b4e 100644 --- a/crc16.h +++ b/crc16.h @@ -8,10 +8,8 @@ extern "C" { #include #include #include "config.h" -#include "erpc_core.h" -uint16_t crc16(const unsigned char *buf, size_t len); -u8 cmd_check_crc16(erpc_cmd_def_t *cmd); -u16 cmd_cal_crc16(erpc_cmd_def_t *cmd); +u16 crc16_cal(u16 data,u16 crc); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/erpc_core.c b/erpc_core.c index 05fb2ee..965dcec 100644 --- a/erpc_core.c +++ b/erpc_core.c @@ -1,614 +1,413 @@ #include "erpc_core.h" - #include "crc16.h" - -/** - * 操作系统相关 - */ - -erpc_sleep erpc_sleep_tick = NULL; - -static list_t erpc_hw; -void clean_cache(erpc_hw_cfg_t *hw) +#include "string.h" +void cal_crc16(erpc_msg_t *msg) { - for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) - { - hw->rec_cache->state = ERPC_CMD_NO_ERROR; - } - for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) - { - hw->send_cache[i].state = ERPC_CMD_NO_ERROR; - } + u16 crc = 0; + crc = crc16_cal(msg->src_id, crc); + crc = crc16_cal(msg->dest_id, crc); + crc = crc16_cal(msg->type, crc); + crc = crc16_cal(msg->len, crc); + for (int i = 0; i < msg->len; i++) + { + crc = crc16_cal(msg->data[i], crc); + } + msg->crc = crc; } -/** - * 注册 hardware 设备 - * 线程不安全 - */ -u32 erpc_hw_add(erpc_hw_cfg_t *hw) +u8 check_crc16(erpc_msg_t *msg) { - list_t *list = &erpc_hw; - if (list->data == NULL) - { - list->data = (void *)hw; - clean_cache(hw); - return ERPC_NO_ERROR; - } - list_t *list_node = malloc(sizeof(list_t)); - if (list_node == NULL) - { - return ERPC_ERR_MALLOC_ERROR; - } - list_node->data = (void *)hw; - u8 hw_ord = hw->ord; - // 检查hw是否已经存在 - while (list != NULL) - { - erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data; - if (hw_cfg->ord == hw_ord) + u16 crc = 0; + crc = crc16_cal(msg->src_id, crc); + crc = crc16_cal(msg->dest_id, crc); + crc = crc16_cal(msg->type, crc); + crc = crc16_cal(msg->len, crc); + for (int i = 0; i < msg->len; i++) { - return ERPC_ERR_HW_EXIST; + crc = crc16_cal(msg->data[i], crc); } - list = list->next; - } - list_t *result = list_append(&erpc_hw, hw); - if (result == NULL) - { - return ERPC_ERR_MALLOC_ERROR; - } - clean_cache(hw); - return ERPC_NO_ERROR; -} -/** - * 注册命令列表 - * 线程不安全 - */ -u32 erpc_add_cmd_list(erpc_hw_cfg_t *hw, erpc_cmd_list_t *cmd_list) -{ - list_t *list = &hw->cmd_list; - if (list->data == NULL) - { - list->data = (void *)cmd_list; - return ERPC_NO_ERROR; - } - list = list_append(&hw->cmd_list, cmd_list); - if (list == NULL) - { - return ERPC_ERR_MALLOC_ERROR; - } - return ERPC_NO_ERROR; -} -/** - * 移除 hardware 设备 - * 线程不安全 - */ -u32 erpc_hw_remove(u8 hw) -{ - list_t *list = &erpc_hw; - if (list->data == NULL) - { - return ERPC_ERR_NOFOND_HW; - } - while (list != NULL) - { - erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data; - if (hw_cfg->ord == hw) - { - list_delete(&erpc_hw, list); - free(list); - return ERPC_NO_ERROR; - } - list = list->next; - } - return ERPC_ERR_NOFOND_HW; -} -/** - * 获取 hardware 设备 - */ -erpc_hw_cfg_t *erpc_hw_get(u8 hw) -{ - list_t *list = &erpc_hw; - if (list->data == NULL) - { - return NULL; - } - while (list != NULL) - { - erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data; - if (hw_cfg->ord == hw) - { - return hw_cfg; - } - } - return NULL; -} -u32 erpc_send_base(erpc_hw_cfg_t *hw_cfg, u8 dest_id, u16 port, u8 package_type, - u8 *data, u16 len) -{ - CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW); - u8 cache_ord = 255; - // 查找可用的发送缓存 - for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) - { - if (hw_cfg->send_cache[i].state == ERPC_CMD_NO_ERROR) - { - // ERPC_DEBUG("find send cache %d\n", i); - cache_ord = i; - break; - } - } - - CHECK_IF_ERROR(cache_ord == 255, ERPC_ERR_SEND_CACHE_FULL); - // 准备数据 - 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]; - cmd->head.dest_id = dest_id; - cmd->head.port = port; - cmd->head.msg_len = len; - if (data == NULL) - { - cmd->head.msg_len = 0; - len = 0; - } - cmd->head.type = package_type; - cmd->head.src_id = hw_cfg->local_id; - if (len > 0 && data != NULL) - { - for (int i = 0; i < len; i++) - { - cmd->data[i] = data[i]; - } - } - // 计算校验和 - cmd_cal_crc16(cmd); - - // 发送数据 - hw_cfg->send_cache[cache_ord].state = ERPC_CMD_WAIT_SEND; - // 等待数据发送完成 - int wait_time = CMD_TIMEOUT; - while (wait_time > 0) - { - if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_OK) - { - break; - } - if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_DEST_BUSY) - { - return ERPC_ERR_DEST_BUSY; - } - if (erpc_sleep_tick != NULL) - { - erpc_sleep_tick(1); - } - wait_time--; - } - u32 ret = ERPC_NO_ERROR; - do - { - if (wait_time == 0) - { - printf("send timeout,state:%d\n", hw_cfg->send_cache[cache_ord].state); - 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_boardcast(u16 port, u8 *data, u16 len) -{ - list_t *list = &erpc_hw; - if (list->data == NULL) - { - return ERPC_ERR_NOFOND_HW; - } - while (list != NULL) - { - erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data; - u8 cache_ord = 255; - // 查找可用的发送缓存 - for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) - { - if (hw_cfg->send_cache[i].state == ERPC_CMD_NO_ERROR) - { - // ERPC_DEBUG("find send cache %d\n", i); - cache_ord = i; - break; - } - } - if (cache_ord == 255) - { - continue; - } - // 准备数据 - 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]; - cmd->head.dest_id = ERPC_BOARDCAST_ID; - cmd->head.port = port; - cmd->head.src_id = hw_cfg->local_id; - cmd->head.msg_len = len; - if (data == NULL) - { - cmd->head.msg_len = 0; - } - if (len > 0 && data != NULL) - { - for (int i = 0; i < len; i++) - { - cmd->data[i] = data[i]; - } - } - // 计算校验和 - cmd_cal_crc16(cmd); - hw_cfg->send_cache[cache_ord].state = ERPC_CMD_WAIT_SEND; - } + return crc == msg->crc; } -u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len) +static erpc_cache_t *find_free_cache(erpc_hw_t *hw) { - 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_wait_resp_package(u8 hw, u8 dest_id, u16 port, u8 *reply_data, - u16 *reply_len, u32 time_out) -{ - erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw); - CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW); - while (time_out > 0) - { - for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; 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); - memcpy(reply_data, cmd->data, cmd->head.msg_len); - if (reply_len != NULL) + + if (hw->send_cache[i].state == CACHE_FREE) { - *reply_len = cmd->head.msg_len; + return &hw->send_cache[i]; } - } - rec_cahce->state = ERPC_CMD_NO_ERROR; - return ERPC_NO_ERROR; } - if (erpc_sleep_tick != NULL) + return NULL; +} +// static erpc_cache_t *clean_ack_cache(erpc_hw_t *hw, u8 dest_id) +// { +// return NULL; +// } +static erpc_cache_t *find_ack_cache(erpc_hw_t *hw, u8 dest_id, u16 port) +{ + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++) { - 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); - 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_RESP, - 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]; - u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd->head.msg_len; - hw->send_lock(); - u8 ret = hw->write((u8 *)hw->send_cache[i].data, len); - hw->send_unlock(); - CHECK_IF_ERROR(ret != 0, ERPC_ERR_HW_SEND_FAIL); - 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) -{ - 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) - { - 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) - { - hw->send_cache[i].state = ERPC_CMD_SEND_OK; - 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) -{ - 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) - { - 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) - { - u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd_send->head.msg_len; - hw->send_lock(); - u32 ret = hw->write((u8 *)hw->send_cache[i].data, len); - hw->send_unlock(); - 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; -} -u32 erpc_send_ack_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_REQ_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_package(erpc_hw_cfg_t *hw) -{ - for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) - { - if (hw->rec_cache[i].state == ERPC_CMD_WAIT_SERVER_DEAL) - { - hw->deal_lock(); - if (hw->rec_cache[i].state == ERPC_CMD_WAIT_SERVER_DEAL) - { - hw->rec_cache[i].state = ERPC_CMD_SERVER_DEAL; - } - else - { - hw->deal_unlock(); - continue; - } - hw->deal_unlock(); - // ERPC_DEBUG("find cmd wait server deal %d\n", i); - erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->rec_cache[i].data[0]; - // 检查crc - u8 crc_result = cmd_check_crc16(cmd); - // 丢弃错误数据包 - if (crc_result) - { - hw->rec_cache[i].state = ERPC_CMD_NO_ERROR; - continue; - } - // 丢弃不是本地数据包 - if (cmd->head.dest_id != hw->local_id) - { - hw->rec_cache[i].state = ERPC_CMD_NO_ERROR; - continue; - } - // 处理数据包 - switch (cmd->head.type) - { - case PACKAGE_TYPE_CMD_REQ: - ERPC_DEBUG("{REQ}\n"); - erpc_send_ack_package(hw, cmd); - hw->rec_cache[i].state = ERPC_CMD_WAIT_TASK_DEAL; - break; - case PACKAGE_TYPE_CMD_REQ_ACK: - ERPC_DEBUG("{ACK}\n"); - - erpc_rev_ack_package(hw, cmd); - hw->rec_cache[i].state = ERPC_CMD_NO_ERROR; - break; - - case PACKAGE_TYPE_CMD_REPEAT: - erpc_rev_repeat_package(hw, cmd); - hw->rec_cache[i].state = ERPC_CMD_NO_ERROR; - break; - case PACKAGE_TYPE_CMD_RESP: - ERPC_DEBUG("{RESP}\n"); - erpc_rev_resp_package(hw, cmd); - hw->rec_cache[i].state = ERPC_CMD_RESP_OK; - break; - case PACKAGE_TYPE_CMD_RESP_ACK: - ERPC_DEBUG("{RESP_ACK}\n"); - erpc_rev_ack_package(hw, cmd); - hw->rec_cache[i].state = ERPC_CMD_NO_ERROR; - break; - default: - - break; - } - } - } - return ERPC_NO_ERROR; -} -void erpc_rev_package_core() -{ - list_t *list = &erpc_hw; - if (list->data == NULL) - { - return; - } - while (list != NULL) - { - erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data; - erpc_rev_package(hw); - list = list->next; - } -} -u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len) -{ - erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw); - CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW); - for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) - { - if (hw_cfg->rec_cache[i].state == ERPC_CMD_NO_ERROR) - { - // ERPC_DEBUG("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; - } - } - return ERPC_ERR_REC_CACHE_FULL; -} -void erpc_send_deal_core() -{ - list_t *list = &erpc_hw; - if (list->data == NULL) - { - return; - } - while (list != NULL) - { - erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data; - erpc_send_data(hw); - } - if (erpc_sleep_tick != NULL) - { - erpc_sleep_tick(1); - } -} - -void erpc_rev_deal_core() -{ - list_t *list = &erpc_hw; - if (list->data == NULL) - { - return; - } - while (list != NULL) - { - erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data; - { // 遍历接收缓存 - for (int j = 0; j < MAX_REC_CMD_CACHE_NUM; j++) - { - { // 发现等待处理的数据包 - if (hw->rec_cache[j].state != ERPC_CMD_WAIT_TASK_DEAL) - { - continue; - } + erpc_cache_t *cache = &hw->send_cache[i]; + if (cache->state == CACHE_REC_ACK && cache->msg.src_id == dest_id && cache->msg.port == port) + { + return cache; } - { // 多线程下,抢占处理权限 - hw->deal_lock(); - if (hw->rec_cache[j].state == ERPC_CMD_WAIT_TASK_DEAL) - { - // 获取指令的处理权限 - hw->rec_cache[j].state = ERPC_CMD_WAIT_TASK_DEAL_FINISH; - } - else - { - // 已经有线程抢先执行了 - hw->deal_unlock(); - continue; - } - hw->deal_unlock(); - } - { // 处理指令 - // 搜索指令列表 - list_t *cmd_list = &hw->cmd_list; - // 链表是空的 - if (cmd_list->data == NULL) - { - continue; - } - // 获取指令指针 - erpc_cmd_def_t *cmd_def = (erpc_cmd_def_t *)hw->rec_cache[j].data; - while (cmd_list != NULL) - { // 搜索指令列表 - erpc_cmd_list_t *cmd_obj = (erpc_cmd_list_t *)cmd_list->data; - if (cmd_obj->cmd == cmd_def->head.port) + } + return NULL; +} +static u8 check_port_send_available(erpc_hw_t *hw, u8 port) +{ + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++) + { + erpc_cache_t *cache = &hw->send_cache[i]; + if (cache->state != CACHE_FREE) + { + if (cache->msg.port == port) { - 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); - } - - break; + return 0; } - cmd_list = cmd_list->next; - } } - // 处理完成 丢弃缓存 , 无论是否执行指令,都需要把数据包丢弃 - hw->rec_cache[j].state = ERPC_CMD_NO_ERROR; - } } - list = list->next; - } - if (erpc_sleep_tick != NULL) - { - erpc_sleep_tick(1); - } + return 1; } +static void free_port_ack_cache(erpc_hw_t *hw, u16 port) +{ + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++) + { + erpc_cache_t *cache = &hw->recv_cache[i]; + if (cache->state == CACHE_REC_ACK) + { + if (cache->msg.port == port) + { + cache->state = CACHE_FREE; + } + } + } +} +static u32 send_data(erpc_hw_t *hw, erpc_cache_t *cache, u16 port, u16 *timeout) +{ + free_port_ack_cache(hw, port); + cache->state = CACHE_WAIT_SEND; + // 等待发送完成 + while (*timeout) + { + if (cache->state == CACHE_SEND_OK) + { + return 0; + } + else if (cache->state == CACHE_SEND_HW_ERR) + { + return ERPC_ERR_SEND_HW_ERR; + } + else + { + hw->sleep(1); + } + (*timeout)--; + } + + if (*timeout == 0) + { + return ERPC_ERR_SEND_TIMEOUT; + } + return 0; +} +static u32 wait_ack(erpc_hw_t *hw, erpc_cache_t *rec, u8 dest_id, u16 port, u16 *timeout) +{ + while (*timeout) + { + rec = find_ack_cache(hw, dest_id, port); + if (rec != NULL) + { + return 0; + } + hw->sleep(1); + (*timeout)--; + } + if (timeout == 0) + { + return ERPC_ERR_SEND_ACK_TIMEOUT; + } + return 0; +} + u32 send_request(erpc_hw_t *hw, u8 dest_id, u16 port, u8 *data, u16 len, u16 timeout, u8 retry) +{ + erpc_cache_t *cache = find_free_cache(hw); + CHECK_DEAL(cache == NULL, ERPC_ERR_NO_FREE_SEND_CACHE); + hw->lock(); + if (check_port_send_available(hw, port) == 0) + { + hw->unlock(); + return ERPC_ERR_SEND_PORT_IS_INUSE; + } + cache->msg.dest_id = dest_id; + cache->state = CACHE_IN_USE; + hw->unlock(); + cache->msg.src_id = hw->local_id; + cache->msg.type = ERPC_MSG_TYPE_REQUEST; + cache->msg.len = len; + cache->msg.port = port; + memcpy(cache->msg.data, data, len); + cal_crc16(&cache->msg); + erpc_cache_t *rec = NULL; + u16 timeout_copy = timeout; + while (retry--) + { + /** + * 发送失败应该立即返回,不能retry + */ + u32 ret = send_data(hw, cache, port, &timeout); + if (ret) + { + cache->state = CACHE_FREE; + return ret; + } + // 等待ack + ret = wait_ack(hw, rec, dest_id, port, &timeout); + if (ret == 0) + { + break; + } + timeout = timeout_copy; + } + CHECK_DEAL(retry == 0, ERPC_ERR_SEND_ACK_TIMEOUT); + // 释放cache + cache->state = CACHE_FREE; + rec->state = CACHE_FREE; + return 0; +} + +static erpc_cache_t *find_response_cache(erpc_hw_t *hw, u8 dest_id, u16 port) +{ + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++) + { + erpc_cache_t *cache = &hw->recv_cache[i]; + if (cache->state == CACHE_GET_RESP && cache->msg.src_id == dest_id && cache->msg.port == port) + { + return cache; + } + } + return NULL; +} +static void free_response_cache(erpc_hw_t *hw, u8 dest_id, u16 port) +{ + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++) + { + erpc_cache_t *cache = &hw->recv_cache[i]; + if (cache->state == CACHE_GET_RESP && cache->msg.src_id == dest_id && cache->msg.port == port) + { + cache->state = CACHE_FREE; + } + } +} +static u32 send_ack(erpc_hw_t *hw, u8 dest_id, u16 port, u16 time_out) +{ + erpc_cache_t *cache = find_free_cache(hw); + CHECK_DEAL(cache == NULL, ERPC_ERR_NO_FREE_SEND_CACHE); + hw->lock(); + if (check_port_send_available(hw, port) == 0) + { + hw->unlock(); + return ERPC_ERR_SEND_PORT_IS_INUSE; + } + cache->msg.dest_id = dest_id; + cache->state = CACHE_IN_USE; + hw->unlock(); + cache->msg.src_id = hw->local_id; + cache->msg.type = ERPC_MSG_TYPE_ACK; + cache->msg.len = 0; + cache->msg.port = port; + cal_crc16(&cache->msg); + u32 ret = send_data(hw, cache, port, &time_out); + return ret; +} +/** + * 发送请求,等待响应 + * @param hw 硬件接口 + * @param dest_id 目标ID + * @param port 端口号 + * @param data_out 请求数据 + * @param len_out 请求数据长度 + * @param data_in 响应数据 + * @param len_in 响应数据长度 + * @param send_timeout 发送超时时间 + * @param recv_timeout 接收超时时间 + * @param retry 重试次数 + * @return 0 成功,其他失败 + */ + u32 send_request_wait_response(erpc_hw_t *hw, u8 dest_id, u16 port, u8 *data_out, u16 len_out, u8 *data_in, u16 *len_in, u16 send_timeout, u16 recv_timeout, u8 retry) +{ + free_response_cache(hw, dest_id, port); + u32 ret = send_request(hw, dest_id, port, data_out, len_out, send_timeout, retry); + CHECK_DEAL(ret != 0, ret); + while (recv_timeout) + { + erpc_cache_t *rec = find_response_cache(hw, dest_id, port); + if (rec != NULL) + { + // 拷贝数据 + int len = rec->msg.len; + if (len > *len_in) + { + len = *len_in; + } + memcpy(data_in, rec->msg.data, len); + *len_in = len; + rec->state = CACHE_FREE; + break; + } + recv_timeout--; + hw->sleep(1); + } + CHECK_DEAL(recv_timeout == 0, ERPC_ERR_NO_CMD_RETURN); + ret = send_ack(hw, dest_id, port, send_timeout); + CHECK_DEAL(ret != 0, ret); + return 0; +} + + u32 send_response(erpc_hw_t *hw, erpc_cache_t *cache_rec, u8 *data, u16 len, u16 timeout, u8 retry) +{ + erpc_cache_t *cache = find_free_cache(hw); + CHECK_DEAL(cache == NULL, ERPC_ERR_NO_FREE_SEND_CACHE); + hw->lock(); + if (check_port_send_available(hw, cache->msg.port) == 0) + { + hw->unlock(); + return ERPC_ERR_SEND_PORT_IS_INUSE; + } + cache->msg.dest_id = cache_rec->msg.src_id; + cache->state = CACHE_IN_USE; + hw->unlock(); + cache->msg.src_id = hw->local_id; + cache->msg.type = ERPC_MSG_TYPE_ACK; + cache->msg.len = 0; + cache->msg.port = cache_rec->msg.port; + memcpy(cache->msg.data, data, len); + cal_crc16(&cache->msg); + u16 timeout_copy = timeout; + erpc_cache_t *rec = NULL; + while (retry--) + { + u32 ret = send_data(hw, cache, cache->msg.port, &timeout); + if (ret) + { + cache->state = CACHE_FREE; + return ret; + } + // 等待ack + ret = wait_ack(hw, rec,cache->msg.dest_id,cache->msg.port, &timeout); + if (ret == 0) + { + break; + } + timeout = timeout_copy; + } + CHECK_DEAL(retry == 0, ERPC_ERR_SEND_ACK_TIMEOUT); + // 释放cache + cache->state = CACHE_FREE; + rec->state = CACHE_FREE; + return 0; +} + +u32 write_rec_cache(erpc_hw_t *hw, u8 *data, u16 len) +{ + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++) + { + if (hw->recv_cache[i].state == CACHE_FREE) + { + hw->lock(); + u8 *data_in = (u8 *)&hw->recv_cache[i].msg; + for (int j = 0; j < len; j++) + { + data_in[j] = data[j]; + } + hw->recv_cache[i].state = CACHE_GET_DATA; + hw->unlock(); + return 0; + } + + } + return 1; +} + void send_core(erpc_hw_t *hw) +{ + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++) + { + erpc_cache_t *cache = &hw->send_cache[i]; + if (cache->state == CACHE_WAIT_SEND) + { + u32 ret = hw->send((u8 *)&cache->msg, cache->msg.len + ERPC_MSG_HEADER_SIZE); + if (ret == 0) + { + cache->state = CACHE_SEND_OK; + } + else + { + cache->state = CACHE_SEND_HW_ERR; + } + } + } +} + + void recv_core(erpc_hw_t *hw) +{ + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++) + { + erpc_cache_t *cache = &hw->recv_cache[i]; + if (cache->state == CACHE_GET_DATA) + { + if (check_crc16(&cache->msg) == 1) + { + cache->state = CACHE_GET_MSG; + } + else + { + cache->state = CACHE_FREE; + } + } + switch (cache->state) + { + case CACHE_GET_MSG: + { + switch (cache->msg.type) + { + case ERPC_MSG_TYPE_ACK: + { + cache->state = CACHE_REC_ACK; + } + break; + case ERPC_MSG_TYPE_RESPONSE: + { + cache->state = CACHE_GET_RESP; + } + break; + case ERPC_MSG_TYPE_REQUEST: + { + cache->state = CACHE_WAIT_HANDLE; + } + break; + default: + break; + } + } + break; + + default: + break; + } + } +} + +void recv_handle(erpc_hw_t *hw) +{ + for (int i = 0; i < ERPC_MSG_CACHE_SIZE; i++) + { + erpc_cache_t *cache = &hw->recv_cache[i]; + if (cache->state == CACHE_WAIT_HANDLE) + { + + cache->state = CACHE_FREE; + } + } +} \ No newline at end of file diff --git a/erpc_core.h b/erpc_core.h index 0f19aaf..280997a 100644 --- a/erpc_core.h +++ b/erpc_core.h @@ -1,145 +1,110 @@ -#ifndef ERPC_CORE_H_ -#define ERPC_CORE_H_ - -#include -#include -#include - +#ifndef _ERPC_CORE_H_ +#define _ERPC_CORE_H_ #include "config.h" #include "list.h" -#define ERPC_VERSION "0.0.1" +#define ERPC_VERSION_MAJOR 1 +#define ERPC_VERSION_MINOR 0 +#define ERPC_VERSION_PATCH 0 -typedef enum package_type { - PACKAGE_TYPE_DEV_POWER_ON = 0, - PACKAGE_TYPE_CMD_REQ, - PACKAGE_TYPE_CMD_REQ_ACK, - PACKAGE_TYPE_CMD_RESP, - PACKAGE_TYPE_CMD_RESP_ACK, - PACKAGE_TYPE_CMD_REPEAT, // crc校验失败,请求重发 - PACKAGE_TYPE_DEV_POWER_OFF, - PACKAGE_TYPE_CMD_SERCH_DEV_ONLINE, -} package_type; +#define ERPC_MSG_HEADER_SIZE 9 +#define ERPC_MSG_DATA_MAX_SIZE (256 - ERPC_MSG_HEADER_SIZE + 2) +#define ERPC_MSG_CACHE_SIZE 16 // Maximum number of messages in cache -// 广播ID -#define ERPC_BOARDCAST_ID 0xff +#define ERPC_SEND_TIMEOUT 30 // 发送超时时间,单位tick +typedef struct erpc_msg_t +{ + u8 src_id; + u8 dest_id; + u8 type; + u16 port; + u16 len; + u16 crc; + u8 data[ERPC_MSG_DATA_MAX_SIZE]; +} erpc_msg_t; -typedef struct erpc_cmd_head_t { - u8 src_id; - u8 dest_id; - u8 type; // package_type - u16 port; // 指令号,指令号=端口号 - u8 msg_len; -} erpc_cmd_head_t; - -#define MAX_CMD_LEN (256 - sizeof(erpc_cmd_head_t)) // crc16最大支持256字节 - -typedef struct erpc_cmd_def_t { - erpc_cmd_head_t head; - u8 crc_16[2]; - u8 data[MAX_CMD_LEN]; -} erpc_cmd_def_t; - -#define CMD_MAX_RETRY 5 // 最大重发次数 -#define CMD_TIMEOUT 30 // 超时时间 tick -#define MAX_REC_CMD_CACHE_NUM \ - 10 // 最大接收指令缓存数量,接受指令优先级>处理指令优先级 -#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_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_CMD_RESP_OK, // 指令响应成功 -} erpc_status; - -typedef struct erpc_data_cache_t { - u8 state; - u8 data[256]; -} erpc_data_cache_t; - -typedef u32 (*erpc_cmd_handle_t)(u8 src_id, u8 dest_id, u16 port, u8 *data, - u16 len); - -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; - u8 local_id; - u8 (*write)(u8 *data, u16 len); - void (*send_lock)(void); - void (*send_unlock)(void); - erpc_data_cache_t rec_cache[MAX_REC_CMD_CACHE_NUM]; - erpc_data_cache_t send_cache[MAX_SEND_CMD_CACHE_NUM]; - void (*deal_lock)(void); - void (*deal_unlock)(void); - list_t cmd_list; -} erpc_hw_cfg_t; - -#define CHECK_IF_ERROR(condition, error) \ - if (condition) { \ - return error; \ - } -#define CHECK_IF_ERROR_AND_DO(condition, error, action) \ - if (condition) { \ - action; \ - return error; \ - } -typedef enum erpc_error { - ERPC_NO_ERROR = 0, - ERPC_ERR_NOFOND_HW, - ERPC_ERR_SEND_CACHE_FULL, - ERPC_ERR_SEND_TIMEOUT, - ERPC_ERR_HW_SEND_FAIL, // 硬件层发来的错误 erpc_hw_cfg_t.write返回错误 - ERPC_ERR_DEST_BUSY, - ERPC_ERR_DEST_NO_RESPONSE, // 目标设备无响应 - ERPC_ERR_DEST_NO_REPLY, // 目标设备无回复或者回复超时 - ERPC_ERR_MALLOC_ERROR, // malloc失败,内存不足 - ERPC_ERR_HW_EXIST, // 硬件已经存在 - ERPC_ERR_HW_NOT_EXIST, // 硬件不存在 - ERPC_ERR_REC_CACHE_FULL, // 接收缓存满 +typedef struct erpc_cache_t +{ + u8 state; + erpc_msg_t msg; +} erpc_cache_t; +typedef enum erpc_msg_type +{ + ERPC_MSG_TYPE_REQUEST = 0, + ERPC_MSG_TYPE_ACK, + ERPC_MSG_TYPE_RESPONSE, +}erpc_msg_type; +typedef enum erpc_cache_state +{ + CACHE_FREE = 0, + // 占用 + CACHE_IN_USE, + // 发送cache + CACHE_WAIT_SEND, + CACHE_SEND_OK, + CACHE_SEND_HW_ERR, + // 接收cache + CACHE_GET_DATA, // 发现数据 + CACHE_GET_MSG, // 发现完整消息 + CACHE_REC_ACK, // 收到ACK + CACHE_GET_RESP, // 收到RESP数据包 + CACHE_WAIT_HANDLE, // 等待处理 +} erpc_cache_state; +typedef enum erpc_error +{ + ERPC_OK = 0, + // 发送REQ + ERPC_ERR_NO_FREE_SEND_CACHE, // 没有空闲的发送缓存 + ERPC_ERR_SEND_TIMEOUT, // 发送REQ超时 + ERPC_ERR_SEND_ACK_TIMEOUT, // 发送REQ成功,但是没有收到ACK + ERPC_ERR_SEND_PORT_IS_INUSE, // 发送失败,端口已被占用 + ERPC_ERR_SEND_HW_ERR, // 发送失败,硬件错误 + // 接收REQ + ERPC_ERR_NO_CMD_RETURN, // 发生REQ成功,但是没有收到RESP包 } erpc_error; -typedef void (*erpc_sleep)(u32 tick); +typedef struct erpc_hw_t +{ + u8 local_id; + void (*lock)(void); + void (*unlock)(void); + void (*sleep)(u32 ms); + u32 (*send)(u8 *data, u16 len); + erpc_cache_t send_cache[ERPC_MSG_CACHE_SIZE]; + erpc_cache_t recv_cache[ERPC_MSG_CACHE_SIZE]; + list_t handler_list; +} erpc_hw_t; -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(); // 处理接受到的指令,业务层面处理 -extern erpc_sleep erpc_sleep_tick; +typedef struct handler_list_t +{ + u16 port; + void (*handle)(erpc_hw_t *hw, erpc_cache_t *cache, u8 *data, u16 len); +} handler_list_t; -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); +#define CHECK_DEAL(condition, error) \ + if ((condition)) \ + return error; /** - * 单纯发送消息 + * 内核函数,需要手动sleep */ -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); +void send_core(erpc_hw_t *hw); +void recv_core(erpc_hw_t *hw); +void recv_handle(erpc_hw_t *hw); /** - * 广播消息 + * 用户函数 */ -u32 erpc_boardcast(u16 port, u8 *data, u16 len); +u32 send_request(erpc_hw_t *hw, u8 dest_id, u16 port, u8 *data, u16 len, u16 timeout, u8 retry); +u32 send_request_wait_response(erpc_hw_t *hw, u8 dest_id, u16 port, u8 *data_out, u16 len_out, u8 *data_in, u16 *len_in, u16 send_timeout, u16 recv_timeout, u8 retry); +u32 send_response(erpc_hw_t *hw, erpc_cache_t *cache, u8 *data, u16 len, u16 timeout, u8 retry); +u32 write_rec_cache(erpc_hw_t *hw, u8 *data, u16 len); +/** + * 注册处理函数 + */ +#define EXPORT_ERPC_HANDLE(hw, _port, _handle) \ + static handler_list_t _A##_handle = \ + { \ + .port = _port,\ +.handle = _handle,\ +};\ +EXPORT_LIST_NODE(hw.list,_A##_handle); - -#endif /* ERPC_CORE_H_ */ \ No newline at end of file +#endif /* _ERPC_CORE_H_ */ \ No newline at end of file diff --git a/erpc_net.c b/erpc_net.c deleted file mode 100644 index 3c9b91f..0000000 --- a/erpc_net.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "erpc_net.h" -#include "erpc_core.h" - diff --git a/erpc_net.h b/erpc_net.h deleted file mode 100644 index 3d38351..0000000 --- a/erpc_net.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "erpc_core.h" - -u32 erpc_find_all(); \ No newline at end of file diff --git a/erpc_port_self.c b/erpc_port_self.c new file mode 100644 index 0000000..372a0d3 --- /dev/null +++ b/erpc_port_self.c @@ -0,0 +1,104 @@ +#include "erpc_core.h" + +#include +#include + +HANDLE hMutex; + +static void lock() +{ + WaitForSingleObject(hMutex, INFINITE); +} + +static void unlock() +{ + ReleaseMutex(hMutex); +} +static void sleep(u32 ms) +{ + Sleep(ms); +} +extern erpc_hw_t port_self; +static u32 erpc_send(u8 *data, u16 len) +{ + write_rec_cache(&port_self,data,len); +} +erpc_hw_t port_self = { + .lock = lock, + .unlock = unlock, + .sleep = sleep, + .local_id = 0x12, + .send = erpc_send, +}; + + +static void test1(){ + +} +DWORD WINAPI fun(LPVOID lpParam) +{ + UNUSED(lpParam); + while (1) + { + Sleep(1000); + } +} +DWORD WINAPI send_thread(LPVOID lpParam) +{ + UNUSED(lpParam); + while (1) + { + send_core(&port_self); + Sleep(1); + } +} +DWORD WINAPI recv_thread(LPVOID lpParam) +{ + UNUSED(lpParam); + while (1) + { + recv_core(&port_self); + Sleep(1); + } +} + +DWORD WINAPI recv_handle_thread(LPVOID lpParam) +{ + UNUSED(lpParam); + while (1) + { + recv_handle(&port_self); + Sleep(1); + } +} + +int main() +{ + hMutex = CreateMutex(NULL, FALSE, TEXT("MyMutex")); + + if (hMutex == NULL) + { + printf("CreateMutex error: %d\n", GetLastError()); + return 1; + } + + HANDLE hThreads[4]; + + hThreads[0] = CreateThread(NULL, 0, fun, NULL, 0, NULL); + hThreads[1] = CreateThread(NULL, 0, send_thread, NULL, 0, NULL); + hThreads[2] = CreateThread(NULL, 0, recv_thread, NULL, 0, NULL); + hThreads[3] = CreateThread(NULL, 0, recv_handle_thread, NULL, 0, NULL); + // 等待所有线程完成 + WaitForMultipleObjects(4, hThreads, TRUE, INFINITE); + + // 关闭线程句柄 + for (int i = 0; i < 4; i++) + { + CloseHandle(hThreads[i]); + } + + // 关闭Mutex句柄 + CloseHandle(hMutex); + + return 0; +} diff --git a/erpc设计文档.md b/erpc设计文档.md deleted file mode 100644 index f7d5498..0000000 --- a/erpc设计文档.md +++ /dev/null @@ -1,39 +0,0 @@ - -## 协议设计 - -### 指令通讯 -1. 指令发送方法:
- 采用send-ack模式,即主机发送指令后,等待目标设备的ack确认,确认后才认为指令发送成功。 -2. notify-noreply模式:
- 接口:
- ```c - u32 erpc_sand(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len) - ``` - 描述:
- 主机对目标设备发送一条指令,并不期待回复。其本质就是发送一次指令。 - ![](./picture/1.jpg) -3. notify-reply模式:
- 接口:
- ```c - //主机: - 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); - - ``` - 描述:
- 本质由2条指令组成。
- 主机发送req指令,从机直接回复。主机开始等待从机指令。
- 从机处理完成后,向主机发送rep指令,并附带回复数据。
- 主机收到rep指令后,开始等待rep指令的ack确认。
- ![](./picture/2.jpg) -4. 指令工作在单线程模式下:
- 指令发送后,等待ack确认,直到确认后才认为指令发送成功。如果确认超时,则认为指令发送失败。 - 可以在上述的接口中发现 cmd 并不定义为cmd,而是用了port的称呼。port的取值范围为0~65535,可以用来表示不同的指令。
- -4. 多device通讯方法:
- 每个port工作是单线程的,这就意味着,如果有多个device需要同时发送指令,则需要多线程或多进程。也就意味着需要定义不同的port号,来区分不同的线程,哪怕他是相同的指令。
- 例如:节点0x03中挂在了3个电机,需要这3个电机同时运动,此时理论上指令是相同的,但是device不同的。通讯库没有做device id的区分。为此需要将port号划分为cmd + device id的形式。cmd相同的指令,device id不同,这样就可以实现多device通讯。
- u16(port) = u8(cmd) + u8(device_id);
- 这样一个cmd号需要链接到多个port上。此时的cmd可叫做cmd组 - ![](./picture/3.jpg) \ No newline at end of file diff --git a/list.c b/list.c index 392318c..2638010 100644 --- a/list.c +++ b/list.c @@ -1,90 +1,86 @@ #include "list.h" -#include "stdio.h" -#include "stdlib.h" -#include "config.h" -list_t *list_create(void *data) -{ - list_t *node = (list_t *)malloc(sizeof(list_t)); - if (node == NULL) - { - return NULL; - } - node->data = data; - node->next = NULL; - return node; -} +#include +#include -list_t *list_append(list_t *head, void *data) +int list_node_add(list_t *list, void *data) { - list_t *node = list_create(data); - if (node == NULL) + list_node_t *new_node = (list_node_t *)malloc(sizeof(list_node_t)); + if (new_node == NULL) { - return NULL; + return LIST_ERR_MALLOC_FAILED; } - if (head == NULL) + new_node->data = data; + new_node->next = NULL; + if (*list == NULL) { - return NULL; + *list = new_node; } else { - list_t *tail = head; - while (tail->next != NULL) + list_node_t *node = *list; + while (node->next != NULL) { - tail = tail->next; + node = node->next; } - tail->next = node; + node->next = new_node; } - return head; -} -void list_print(list_t *head) -{ - list_t *node = head; - while (node != NULL) - { - ERPC_DEBUG("%p\n", node->data); - node = node->next; - } + return LIST_OK; } - -/** - * Destroy a list and all its nodes. - * @param head The head of the list. - */ -void list_destroy(list_t *head) +int list_node_remove(list_t *list, void *data) { - list_t *node = head; - while (node != NULL) + if (*list == NULL) { - list_t *next = node->next; - free(node); - node = next; + return LIST_ERR_LIST_IS_NULL; } -} -/** - * Delete a node from the list. - * @param head The head of the list. - */ -void list_delete(list_t *head, void *data) -{ - list_t *node = head; - list_t *prev = NULL; + list_node_t *node = *list; + list_node_t *prev = NULL; while (node != NULL) { if (node->data == data) { if (prev == NULL) { - head = node->next; + if (node->next != NULL) + { + *list = node->next; + } + else + { + *list = NULL; + } } else { - prev->next = node->next; + if (node->next != NULL) + { + prev->next = node->next; + } + else + { + prev->next = NULL; + } } free(node); - return; + return LIST_OK; } prev = node; node = node->next; } + return 0; +} +int list_size(list_t *list) +{ + if (*list == NULL) + { + return -1; + } + int size = 0; + list_node_t *node = *list; + while (node != NULL) + { + size++; + node = node->next; + } + return size; } diff --git a/list.h b/list.h index 786051e..d5877fb 100644 --- a/list.h +++ b/list.h @@ -1,17 +1,47 @@ -#ifndef _LIST_H_ -#define _LIST_H_ +#ifndef LIST_H +#define LIST_H +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + typedef struct list_node_t + { + void *data; + struct list_node_t *next; + } list_node_t; + typedef list_node_t *list_t; + typedef enum list_error + { + LIST_OK = 0, + LIST_ERR_LIST_IS_NULL = 1, + LIST_ERR_MALLOC_FAILED, + } list_error; + /** + * @brief 创建一个节点,如果list为NULL,则创建一个空链表,否则创建一个节点并添加到链表尾部 + * @param list 链表指针 + * @param data 数据指针 + */ + int list_node_add(list_t *list, void *data); + /** + * @brief 从链表中删除节点 + * @param list 链表指针 + * @param data 数据指针 + */ + int list_node_remove(list_t *list, void *data); + int list_size(list_t *list); -typedef struct list_t { - void *data; - struct list_t *next; -} list_t; - -list_t *list_create(void *data); -list_t *list_append(list_t *head, void *data); -void list_print(list_t *head); -void list_destroy(list_t *head); -void list_delete(list_t *head, void *data); - - -#endif /* _LIST_H_ */ \ No newline at end of file +/** + * @param list 链表 + * @param data 要添加的数据不要取地址,在宏定义里面自动取地址 + * @warning 这种方式增加节点,会导致无法确定节点添加的先后顺序,更换编译环境后可能会影响编译效率 + */ +#define EXPORT_LIST_NODE(list, data) \ + int __attribute__((constructor)) export_list_node_##list_##data(void) \ + { \ + return list_node_add(&list, (void *)&data); \ + } +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // LIST_H diff --git a/makefile b/makefile index 158c108..90c8dfa 100644 --- a/makefile +++ b/makefile @@ -7,7 +7,7 @@ CFLAGS = -Wall -Wextra -std=c11 -g BUILD_DIR = build # 源文件 SRCS = erpc_core.c \ - port_self.c \ + erpc_port_self.c \ crc16.c\ list.c diff --git a/picture/1.jpg b/picture/1.jpg deleted file mode 100644 index 1ec3a88..0000000 Binary files a/picture/1.jpg and /dev/null differ diff --git a/picture/2.jpg b/picture/2.jpg deleted file mode 100644 index 3984c81..0000000 Binary files a/picture/2.jpg and /dev/null differ diff --git a/picture/3.jpg b/picture/3.jpg deleted file mode 100644 index 1a8a900..0000000 Binary files a/picture/3.jpg and /dev/null differ diff --git a/port_self.c b/port_self.c deleted file mode 100644 index 5c752d1..0000000 --- a/port_self.c +++ /dev/null @@ -1,208 +0,0 @@ - -// #ifndef WINDOWS -// #error "This file is for Windows only" -// #endif - -#include "erpc_core.h" -#include "windows.h" -#include -u32 hellworld(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len) -{ - ERPC_DEBUG("Hello World:\n"); - ERPC_DEBUG("len = %d, msg :%s\n", len, data); - // 防止编译警告 - UNUSED(hw); - UNUSED(src_id); - UNUSED(dest_id); - UNUSED(port); - UNUSED(data); - UNUSED(len); - return 0; -} -u32 hello_cat(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len) -{ - ERPC_DEBUG("Hello Cat!\n"); - // 防止编译警告 - UNUSED(hw); - UNUSED(src_id); - UNUSED(dest_id); - UNUSED(port); - UNUSED(data); - UNUSED(len); - return 0; -} - - - -u32 hello_dog(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len) -{ - ERPC_DEBUG("Hello Dog!\n"); - // 防止编译警告 - u8 data_out[10] = "12345"; - u32 ret = erpc_replay(hw, dest_id, port, data_out, sizeof(data_out)); - ERPC_DEBUG("erpc_replay ret:%d\n", ret); - // 防止编译警告 - UNUSED(ret); - UNUSED(hw); - UNUSED(src_id); - UNUSED(dest_id); - UNUSED(port); - UNUSED(data); - UNUSED(len); - return 0; -} -erpc_cmd_list_t erpc_cmd_list[] = { - {.cmd = 0x01, hellworld}, - {.cmd = 0x02, hello_cat}, - {.cmd = 0x03, hello_dog}, -}; - -HANDLE deal_lock; -HANDLE send_lock; - -static void deal_lock_h() -{ - WaitForSingleObject(deal_lock, INFINITE); -} - -static void deal_unlock_h() -{ - ReleaseMutex(deal_lock); -} -static void send_lock_h() -{ - WaitForSingleObject(send_lock, INFINITE); -} - -static void send_unlock_h() -{ - ReleaseMutex(send_lock); -} -u8 data[300]; -static u8 data_write(u8 *data, u16 len) -{ - erpc_set_rev_cahce(0, data, len); - return 0; -} - -erpc_hw_cfg_t self_hw_cfg = { - .ord = 0, - .deal_lock = deal_lock_h, - .deal_unlock = deal_unlock_h, - .send_lock = send_lock_h, - .send_unlock = send_unlock_h, - .local_id = 0x01, - .write = data_write, -}; -void erpc_cmd_config() -{ - for (int i = 0; i < (int)sizeof(erpc_cmd_list) / (int)sizeof(erpc_cmd_list[0]); i++) - { - erpc_add_cmd_list(&self_hw_cfg, &erpc_cmd_list[i]); - } -} -void sys_sleep(u32 ms) -{ - Sleep(ms); -} - -DWORD WINAPI send_task(LPVOID lpParam) -{ - UNUSED(lpParam); - while (1) - { - erpc_send_deal_core(); - } -} -DWORD WINAPI rev_package_task(LPVOID lpParam) -{ - UNUSED(lpParam); - - while (1) - { - // ERPC_DEBUG("rev_task\n"); - erpc_rev_package_core(); - erpc_rev_deal_core(); - } -} - -DWORD WINAPI rev_deal_task(LPVOID lpParam) -{ - UNUSED(lpParam); - - while (1) - { - // ERPC_DEBUG("rev_task\n"); - erpc_rev_package_core(); - erpc_rev_deal_core(); - } -} - -DWORD WINAPI test_task(LPVOID lpParam) -{ - UNUSED(lpParam); - ERPC_DEBUG("test_task\n"); - while (1) - { - // ERPC_DEBUG("[test_task]send\n"); - char msg[] = "miao miao miao\n"; - u32 ret = erpc_send(self_hw_cfg.ord, self_hw_cfg.local_id, 0x01, (u8 *)msg, sizeof(msg)); - ERPC_DEBUG("[test_task]send ret:%d\n", ret); - ret = erpc_send(self_hw_cfg.ord, self_hw_cfg.local_id, 0x02, NULL, 0); - ERPC_DEBUG("[test_task]send ret:%d\n", ret); - u16 reply_len = 30; - u8 data[reply_len]; - ret = erpc_send_wait_reply(self_hw_cfg.ord, self_hw_cfg.local_id, 0x03, NULL, 0, data, &reply_len, 1000); - ERPC_DEBUG("[test_task]send ret:%d\n", ret); - for (int i = 0; i < reply_len; i++) - { - ERPC_DEBUG("%c", data[i]); - } - ERPC_DEBUG("\n"); - - UNUSED(ret); - sys_sleep(1000); - } -} - -int main(int argc, char *argv[]) -{ - UNUSED(argc); - UNUSED(argv); - u32 ret = 0; - ERPC_DEBUG("erpc_port_self start\n"); - ret = erpc_hw_add(&self_hw_cfg); - ERPC_DEBUG("erpc_hw_add ret:%d\n", ret); - CHECK_IF_ERROR(ret, 0); - erpc_cmd_config(); - ERPC_DEBUG("erpc_cmd_config ret:%d\n", ret); - erpc_sleep_tick = sys_sleep; - - HANDLE threadHandle[4]; - deal_lock = CreateMutex(NULL, FALSE, NULL); - if (deal_lock == NULL) - { - ERPC_DEBUG("创建互斥锁失败\n"); - return 1; - } - send_lock = CreateMutex(NULL, FALSE, NULL); - if (send_lock == NULL) - { - ERPC_DEBUG("创建互斥锁失败\n"); - return 1; - } - threadHandle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)send_task, NULL, 0, NULL); - threadHandle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)rev_package_task, NULL, 0, NULL); - threadHandle[3] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)rev_deal_task, NULL, 0, NULL); - threadHandle[4] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_task, NULL, 0, NULL); - - WaitForSingleObject(threadHandle[0], INFINITE); - WaitForSingleObject(threadHandle[1], INFINITE); - WaitForSingleObject(threadHandle[2], INFINITE); - WaitForSingleObject(threadHandle[3], INFINITE); - CloseHandle(threadHandle[0]); - CloseHandle(threadHandle[1]); - CloseHandle(threadHandle[2]); - CloseHandle(threadHandle[3]); - return 0; -} \ No newline at end of file diff --git a/port_self.exe b/port_self.exe index d6c9988..76558d0 100644 Binary files a/port_self.exe and b/port_self.exe differ diff --git a/port_self.h b/port_self.h deleted file mode 100644 index e69de29..0000000 diff --git a/port_uart_master.c b/port_uart_master.c deleted file mode 100644 index e69de29..0000000 diff --git a/spi_port.c b/spi_port.c deleted file mode 100644 index e2c613d..0000000 --- a/spi_port.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "spi_port.h" - - diff --git a/spi_port.h b/spi_port.h deleted file mode 100644 index d6fb834..0000000 --- a/spi_port.h +++ /dev/null @@ -1 +0,0 @@ -#include "config.h" \ No newline at end of file diff --git a/unit_test.c b/unit_test.c deleted file mode 100644 index 2bf60ca..0000000 --- a/unit_test.c +++ /dev/null @@ -1,2 +0,0 @@ -#include "erpc_core.h" - diff --git a/架构.drawio b/架构.drawio deleted file mode 100644 index c2f7795..0000000 --- a/架构.drawio +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -