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)
- ```
- 描述:
- 主机对目标设备发送一条指令,并不期待回复。其本质就是发送一次指令。
- 
-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确认。
- 
-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组
- 
\ 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 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-