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..a95a303 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,7 +20,8 @@ "windows.h": "c", "string.h": "c", "stdio.h": "c", - "stdlib.h": "c" + "stdlib.h": "c", + "algorithm": "c" }, "makefile.launchConfigurations": [ { diff --git a/build/crc16.o b/build/crc16.o deleted file mode 100644 index 2af0e39..0000000 Binary files a/build/crc16.o and /dev/null differ diff --git a/build/erpc_core.o b/build/erpc_core.o deleted file mode 100644 index bd19ae2..0000000 Binary files a/build/erpc_core.o and /dev/null differ diff --git a/build/list.o b/build/list.o deleted file mode 100644 index f195381..0000000 Binary files a/build/list.o and /dev/null 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..a7c6e96 100644 --- a/config.h +++ b/config.h @@ -10,5 +10,6 @@ #define UNUSED(x) (void)(x) #define ERPC_DEBUG(...) printf(__VA_ARGS__) + // #define ERPC_DEBUG(...) #endif /* _CONFIG_H_ */ \ No newline at end of file diff --git a/crc16.c b/crc16.c index fd32d26..33abe60 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,16 @@ 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); +/** + * @brief 计算CRC16校验码 + * @param buf 待计算的数据 + * @param crc 初始CRC值 ,一般为0 + * @param len 待计算的数据长度 + */ +u16 crc16(u8 *buf, u16 crc, u32 len) +{ + u32 counter; + for (counter = 0; counter < (int)len; counter++) + crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *buf++) & 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 diff --git a/crc16.h b/crc16.h index adb86fb..9eb3634 100644 --- a/crc16.h +++ b/crc16.h @@ -8,10 +8,7 @@ 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(u8 *buf,u16 crc, u32 len); #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/erpc_core.c b/erpc_core.c index 05fb2ee..46ce1d5 100644 --- a/erpc_core.c +++ b/erpc_core.c @@ -1,614 +1,314 @@ #include "erpc_core.h" - +#include #include "crc16.h" - /** - * 操作系统相关 + * @brief 获取空闲的接受缓存 */ - -erpc_sleep erpc_sleep_tick = NULL; - -static list_t erpc_hw; -void clean_cache(erpc_hw_cfg_t *hw) +erpc_packet_cache_t *erpc_hw_get_free_rec_cache(erpc_hardware_t *hw) { - 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; - } -} -/** - * 注册 hardware 设备 - * 线程不安全 - */ -u32 erpc_hw_add(erpc_hw_cfg_t *hw) -{ - 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) + for (int i = 0; i < ERPC_HW_CACHE_SIZE; i++) { - return ERPC_ERR_HW_EXIST; + if (hw->recv_cache->state == ERPC_CACHE_STA_FREE) + { + return hw->recv_cache + i; + } } - 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) +/** + * @brief 获取空闲的发送缓存对应的空闲数据地址 + * 这个接口主要用于DMA方式接收数据 + */ +u8 *erpc_get_hw_free_rec_data_addr(erpc_hardware_t *hw) { - 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_packet_cache_t *cache = erpc_hw_get_free_rec_cache(hw); + if (cache == NULL) { - // ERPC_DEBUG("find send cache %d\n", i); - cache_ord = i; - break; + return NULL; } - } + return (u8 *)&cache->package; +} - 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) - { +/** + * @brief 获取空闲的发送缓存 + */ +erpc_packet_cache_t *erpc_hw_get_free_send_cache(erpc_hardware_t *hw) +{ + for (int i = 0; i < ERPC_HW_CACHE_SIZE; i++) + { + if (hw->send_cache->state == ERPC_CACHE_STA_FREE) + { + return hw->send_cache + i; + } + } + return NULL; +} + +/** + * @brief 设置包信息 + */ +void erpc_set_package(erpc_package_t *package, u8 src_id, u8 dest_id, u8 type, u16 port, u8 *data, u16 len) +{ + package->head.src_id = src_id; + package->head.dest_id = dest_id; + package->head.type = type; + package->head.port = port; + package->head.len = len; + if (data != NULL && len > 0) + { + for (int i = 0; i < len; i++) + { + package->data[i] = data[i]; + } + } + // 计算crc + u16 crc = 0; + crc = crc16((u8 *)&package->head, crc, sizeof(erpc_package_head_t)); + if (data != NULL && len > 0) + { + crc = crc16(package->data, crc, len); + } + package->crc = crc; +} + +#define FUN_WAIT_ACK(time_out, hw, send_cache, error) \ + while (timeout) \ + { \ + if (send_cache->state == ERPC_CACHE_SEND_GET_ACK) \ + { \ + break; \ + } \ + CHECK_RETURN_DO(send_cache->state == ERPC_CACHE_HW_SEND_ERR, ERPC_ERR_HW_SEND_FAIL, send_cache->state = ERPC_CACHE_STA_FREE); \ + CHECK_RETURN_DO(send_cache->state == ERPC_CACHE_ERR_NO_RESP, ERPC_ERR_DEST_NO_RESP, send_cache->state = ERPC_CACHE_STA_FREE); \ + timeout--; \ + hw->sleep(1); \ + } \ + send_cache->state = ERPC_CACHE_STA_FREE; \ + CHECK_RETURN(timeout == 0, error); +/** + * @brief 发送请求包并等待从机回复 + */ +u32 erpc_send_and_wait_resp(erpc_hardware_t *hw, u8 dest_id, u16 port, u8 *data, u16 len, u8 *resp_data, u16 *resp_len, u32 timeout) +{ + if (len > ERPC_DATA_MAX_LEN) + { + return ERPC_ERR_DATA_LEN_OVERFLOW; + } + erpc_packet_cache_t *send_cache = erpc_hw_get_free_send_cache(hw); + CHECK_RETURN(send_cache == NULL, ERPC_ERR_SEND_CACHE_FULL); + // 发送request包 + erpc_set_package(&send_cache->package, hw->local_id, dest_id, ERPC_PKG_TYPE_REQUEST, port, data, len); + send_cache->state = ERPC_CACHE_WAIT_SEND; + // 等待ack包 + FUN_WAIT_ACK(timeout, hw, send_cache, ERPC_ERR_SEND_TIMEOUT); + // 等待response包 + while (timeout) + { + // 寻找response包 + erpc_packet_cache_t *recv_cache = NULL; + for (int i = 0; i < ERPC_HW_CACHE_SIZE; i++) + { + if (hw->recv_cache[i].state != ERPC_CACHE_RESP_DATA) + { + continue; + } + if (hw->recv_cache[i].package.head.port != port) + { + continue; + } + if (hw->recv_cache[i].package.head.src_id != dest_id) + { + continue; + } + if (hw->recv_cache[i].package.head.type != ERPC_PKG_TYPE_RESPONSE) + { + continue; + } + recv_cache = hw->recv_cache + i; + } + // 接收到response包 + if (recv_cache != NULL) + { + u16 max_len = *resp_len; + if (max_len > recv_cache->package.head.len) + { + max_len = recv_cache->package.head.len; + } + + for (int i = 0; i < max_len; i++) + { + resp_data[i] = recv_cache->package.data[i]; + } + *resp_len = max_len; + recv_cache->state = ERPC_CACHE_STA_FREE; + break; + } + timeout--; + hw->sleep(1); + } + CHECK_RETURN(timeout == 0, ERPC_ERR_SEND_TIMEOUT); + return 0; +} +/** + * @brief 发送response包 + */ +u32 erpc_resp(erpc_hardware_t *hw, u8 dest_id, u16 port, u8 *data, u16 len, u32 timeout) +{ + if (len > ERPC_DATA_MAX_LEN) + { + return ERPC_ERR_DATA_LEN_OVERFLOW; + } + erpc_packet_cache_t *send_cache = erpc_hw_get_free_send_cache(hw); + CHECK_RETURN(send_cache == NULL, ERPC_ERR_SEND_CACHE_FULL); + // 发送response包 + erpc_set_package(&send_cache->package, hw->local_id, dest_id, ERPC_PKG_TYPE_RESPONSE, port, data, len); + FUN_WAIT_ACK(timeout, hw, send_cache, ERPC_ERR_SEND_TIMEOUT); + return 0; +} + +u32 erpc_send_ack(erpc_hardware_t *hw, erpc_package_t *rec_package, u32 timeout) +{ + erpc_packet_cache_t *send_cache = erpc_hw_get_free_send_cache(hw); + CHECK_RETURN(send_cache == NULL, ERPC_ERR_SEND_CACHE_FULL); + // 发送ack包 + erpc_set_package(&send_cache->package, hw->local_id, rec_package->head.src_id, ERPC_PKG_TYPE_ACK, rec_package->head.port, NULL, 0); + FUN_WAIT_ACK(timeout, hw, send_cache, ERPC_ERR_SEND_TIMEOUT); + return 0; +} + +u32 erpc_data_out_core(erpc_hardware_t *hw) +{ + for (int i = 0; i < ERPC_HW_CACHE_SIZE; i++) + { + u32 ret = 0; + switch (hw->send_cache[i].state) + { + case ERPC_CACHE_STA_FREE: + break; + case ERPC_CACHE_WAIT_SEND: + hw->send_cache[i].retry_count = 0; + hw->send_cache[i].state = ERPC_CACHE_SEND_ONCE; + ret = hw->send((u8 *)&hw->send_cache[i].package, hw->send_cache[i].package.head.len + sizeof(erpc_package_head_t)); + if (ret) + { + hw->send_cache[i].state = ERPC_CACHE_HW_SEND_ERR; + } + break; + case ERPC_CACHE_SEND_REPEAT: + case ERPC_CACHE_SEND_ONCE: + hw->send_cache[i].timeout--; + if (hw->send_cache[i].timeout == 0) + { + if (hw->send_cache[i].retry_count < ERPC_SEND_RETRY_COUNT) + { + hw->send_cache[i].retry_count++; + hw->send_cache[i].state = ERPC_CACHE_SEND_REPEAT; + ret = hw->send((u8 *)&hw->send_cache[i].package, hw->send_cache[i].package.head.len + sizeof(erpc_package_head_t)); + if (ret) + { + hw->send_cache[i].state = ERPC_CACHE_HW_SEND_ERR; + } + } + else + { + hw->send_cache[i].state = ERPC_CACHE_ERR_NO_RESP; + } + } + break; + default: + break; + } + } + hw->sleep(1); + return 0; +} +/** + * @brief 手动写入接收缓存 + */ +void erpc_write_recv_cache(erpc_hardware_t *hw, u8 *data, u16 len) +{ + erpc_packet_cache_t *recv_cache = erpc_hw_get_free_rec_cache(hw); + if (recv_cache == NULL) + { + return; + } + recv_cache->state = ERPC_CACHE_REV_PACKAGE; for (int i = 0; i < len; i++) { - cmd->data[i] = data[i]; + recv_cache->package.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) +u32 erpc_data_in_core(erpc_hardware_t *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; - u8 cache_ord = 255; - // 查找可用的发送缓存 - for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) + for (int i = 0; i < ERPC_HW_CACHE_SIZE; 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; - } -} - -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_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++) - { - 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) + u32 ret = 0; + switch (hw->recv_cache[i].state) { - *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); - 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; - } - } - { // 多线程下,抢占处理权限 - 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) + case ERPC_CACHE_STA_FREE: + break; + case ERPC_CACHE_REV_PACKAGE: + hw->recv_cache[i].retry_count = 0; + while (hw->recv_cache[i].retry_count < ERPC_SEND_RETRY_COUNT) { - 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; + ret = erpc_send_ack(hw, &hw->recv_cache[i].package, ERPC_ACK_TIMEOUT); + if (ret == 0) + { + hw->recv_cache[i].state = ERPC_CACHE_RESP_ACK; + break; + } + else + { + hw->recv_cache[i].retry_count++; + } } - cmd_list = cmd_list->next; - } + break; + default: + break; } - // 处理完成 丢弃缓存 , 无论是否执行指令,都需要把数据包丢弃 - hw->rec_cache[j].state = ERPC_CMD_NO_ERROR; - } } - list = list->next; - } - if (erpc_sleep_tick != NULL) - { - erpc_sleep_tick(1); - } + hw->sleep(1); + return 0; } + +u32 erpc_deal_core(erpc_hardware_t *hw) +{ + for (int i = 0; i < ERPC_HW_CACHE_SIZE; i++) + { + if (hw->send_cache[i].state != ERPC_CACHE_RESP_ACK) + { + continue; + } + if (hw->lock != NULL && hw->unlock != NULL) + { + hw->lock(); + } + if (hw->send_cache[i].state != ERPC_CACHE_RESP_ACK) + { + if (hw->unlock != NULL) + { + hw->unlock(); + } + continue; + } + hw->send_cache[i].state = ERPC_CACHE_WAIT_DEAL; + if (hw->unlock != NULL) + { + hw->unlock(); + } + // 处理接收到的包 + erpc_handle_list_t *handle_list = hw->handle_list; + while (handle_list != NULL) + { + if (handle_list->port == hw->send_cache[i].package.head.port) + { + handle_list->handle(hw, hw->send_cache[i].package.head.src_id, hw->send_cache[i].package.head.port); + break; + } + handle_list++; + } + hw->send_cache[i].state = ERPC_CACHE_STA_FREE; + } + hw->sleep(1); + return 0; +} \ No newline at end of file diff --git a/erpc_core.h b/erpc_core.h index 0f19aaf..d092de9 100644 --- a/erpc_core.h +++ b/erpc_core.h @@ -1,145 +1,108 @@ -#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" -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_VERSION_MAJOR 0 +#define ERPC_VERSION_MINOR 0 +#define ERPC_VERSION_PATCH 1 -// 广播ID -#define ERPC_BOARDCAST_ID 0xff +#define ERPC_HW_CACHE_SIZE 10 // erpc 硬件缓存大小,单位为包 +#define ERPC_SEND_ONCE_TIMEOUT 30 // ERPC_数据包发送超时时间,单位为tick +#define ERPC_SEND_RETRY_COUNT 3 // ERPC_数据包重发次数 +#define ERPC_ACK_TIMEOUT ERPC_SEND_ONCE_TIMEOUT // ERPC_ack超时时间,单位为tick +typedef struct erpc_package_head_t +{ + u8 dest_id; + u8 src_id; + u16 port; + u8 type; + u16 len; +} erpc_package_head_t; +// crc16 只能保护256字节的有效数据,所以这里限制最大数据长度为256-sizeof(erpc_package_head_t) +#define ERPC_DATA_MAX_LEN (256 - sizeof(erpc_package_head_t)) +typedef struct erpc_package_t +{ + erpc_package_head_t head; + u16 crc; + u8 data[ERPC_DATA_MAX_LEN]; +} erpc_package_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; +typedef struct erpc_packet_cache_t +{ + u8 state; + u8 retry_count; + u8 timeout; + erpc_package_t package; +} erpc_packet_cache_t; -#define MAX_CMD_LEN (256 - sizeof(erpc_cmd_head_t)) // crc16最大支持256字节 +typedef enum cache_state +{ + ERPC_CACHE_STA_FREE = 0, // 空闲状态 + ERPC_CACHE_WAIT_SEND, // data包等待发送 + ERPC_CACHE_SEND_ONCE, // 已经发送过一次,等待ack + ERPC_CACHE_SEND_REPEAT, // data包多次发送 + ERPC_CACHE_SEND_GET_ACK, // data包发送完成,得到ack + ERPC_CACHE_HW_SEND_ERR, // 硬件发送失败 + ERPC_CACHE_ERR_NO_RESP, // dest 无响应 + ERPC_CACHE_RESP_DATA, // 收到响应包 -typedef struct erpc_cmd_def_t { - erpc_cmd_head_t head; - u8 crc_16[2]; - u8 data[MAX_CMD_LEN]; -} erpc_cmd_def_t; + ERPC_CACHE_REV_PACKAGE, // 收到数据包,但是还没有进行处理 + ERPC_CACHE_RESP_ACK, // 接收到数据包,正在回复ack + ERPC_CACHE_WAIT_DEAL, // 等待处理线程处理数据,处理线程已经获取到处理权限 +} cache_state; -#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 enum erpc_package_type +{ + ERPC_PKG_TYPE_REQUEST = 0, + ERPC_PKG_TYPE_RESPONSE, + ERPC_PKG_TYPE_ACK, +} erpc_package_type; +typedef enum erpc_transport_error +{ + ERPC_ERR_SEND_CACHE_FULL = 1, + ERPC_ERR_SEND_TIMEOUT, + ERPC_ERR_DATA_LEN_OVERFLOW, + ERPC_ERR_HW_SEND_FAIL, + ERPC_ERR_DEST_NO_RESP, +} erpc_transport_state; -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, // 接收缓存满 -} erpc_error; -typedef void (*erpc_sleep)(u32 tick); - -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; - -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); +typedef struct erpc_handle_list_t +{ + u16 port; + void (*handle)(void *hw, u8 src_id, u16 port); +} erpc_handle_list_t; /** - * 单纯发送消息 + * 硬件层实现 */ -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); +typedef struct erpc_hardware_t +{ + erpc_packet_cache_t send_cache[ERPC_HW_CACHE_SIZE]; + erpc_packet_cache_t recv_cache[ERPC_HW_CACHE_SIZE]; + u8 local_id; // hardware 节点ID + u32 (*send)(u8 *data, u32 len); // 需要在内部实现lock功能,确保send函数是原子操作 + u32 (*sleep)(u32 ms); // 睡眠函数 + void (*lock)(void); // 锁函数 + void (*unlock)(void); // 解锁函数 + erpc_handle_list_t *handle_list; // 处理函数列表 +} erpc_hardware_t; -/** - * 广播消息 - */ -u32 erpc_boardcast(u16 port, u8 *data, u16 len); +#define CHECK_RETURN(condition, ret) \ + if (condition) \ + { \ + return ret; \ + } +#define CHECK_RETURN_DO(condition, ret, handle) \ + if (condition) \ + { \ + handle; \ + return ret; \ + } +u32 erpc_send_and_wait_resp(erpc_hardware_t *hw, u8 dest_id, u16 port, u8 *data, u16 len, u8 *resp_data, u16 *resp_len, u32 timeout); +u32 erpc_resp(erpc_hardware_t *hw, u8 dest_id, u16 port, u8 *data, u16 len, u32 timeout); -#endif /* ERPC_CORE_H_ */ \ No newline at end of file +u32 erpc_data_out_core(erpc_hardware_t *hw); +void erpc_write_recv_cache(erpc_hardware_t *hw, u8 *data, u16 len); +u32 erpc_data_in_core(erpc_hardware_t *hw); +u32 erpc_deal_core(erpc_hardware_t *hw); +#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..f05ddf6 --- /dev/null +++ b/erpc_port_self.c @@ -0,0 +1,7 @@ +#include "erpc_core.h" +#include + +int main() +{ + return 0; +} \ No newline at end of file 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 deleted file mode 100644 index 392318c..0000000 --- a/list.c +++ /dev/null @@ -1,90 +0,0 @@ -#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; -} - -list_t *list_append(list_t *head, void *data) -{ - list_t *node = list_create(data); - if (node == NULL) - { - return NULL; - } - if (head == NULL) - { - return NULL; - } - else - { - list_t *tail = head; - while (tail->next != NULL) - { - tail = tail->next; - } - tail->next = 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; - } -} - -/** - * Destroy a list and all its nodes. - * @param head The head of the list. - */ -void list_destroy(list_t *head) -{ - list_t *node = head; - while (node != NULL) - { - list_t *next = node->next; - free(node); - node = next; - } -} -/** - * 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; - while (node != NULL) - { - if (node->data == data) - { - if (prev == NULL) - { - head = node->next; - } - else - { - prev->next = node->next; - } - free(node); - return; - } - prev = node; - node = node->next; - } -} diff --git a/list.h b/list.h deleted file mode 100644 index 786051e..0000000 --- a/list.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _LIST_H_ -#define _LIST_H_ - - -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 diff --git a/makefile b/makefile index 158c108..259c754 100644 --- a/makefile +++ b/makefile @@ -1,36 +1,30 @@ -# Makefile for the mutex example project - -# 指定编译器 +# 定义编译器 CC = gcc -# 指定编译选项 -CFLAGS = -Wall -Wextra -std=c11 -g -BUILD_DIR = build -# 源文件 -SRCS = erpc_core.c \ - port_self.c \ - crc16.c\ - list.c +INCLUDE_PATH = ./ -# 目标文件 -OBJS = $(SRCS:.c=.o) +# 用户可以指定输出文件夹 +OUTPUT_DIR = ./build -# 可执行文件 -Target = port_self.exe +# 查找所有的 .c 文件和对应的 .h 文件 +SOURCES = $(wildcard $(INCLUDE_PATH)/*.c) +HEADERS = $(wildcard $(INCLUDE_PATH)/*.h) +OBJECTS = $(patsubst %.c,$(OUTPUT_DIR)/%.o,$(SOURCES)) + +# 定义最终可执行文件的路径 +TARGET = $(OUTPUT_DIR)/program # 默认目标 -all: $(Target) +all: $(TARGET) -# 链接目标 -$(Target): $(OBJS) - $(CC) -o $@ $(addprefix $(BUILD_DIR)/, $^) -# 编译源文件 -%.o: %.c - $(CC) $(CFLAGS) -c $< -o $(BUILD_DIR)/$@ +# 定义每个目标文件的依赖关系 +$(OUTPUT_DIR)/%.o: %.c $(HEADERS) + $(CC) $(CFLAGS) -c $< -o $@ -# 清理目标 +# 生成可执行文件 +$(TARGET): $(OBJECTS) + $(CC) -o $(TARGET) $(OBJECTS) + +# 清理生成的文件 clean: - rm -f $(OBJS) $(TARGET) - -# 伪目标 -.PHONY: all clean + rm -rf $(OUTPUT_DIR)/* $(TARGET) 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 deleted file mode 100644 index d6c9988..0000000 Binary files a/port_self.exe and /dev/null 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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -