fix(add): 新增resp功能,并增加架构说明
This commit is contained in:
parent
c31caa0e72
commit
45aa9278fe
|
@ -0,0 +1,16 @@
|
||||||
|
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.17 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.17">
|
||||||
|
<diagram name="第 1 页" id="iJ2ThG75liGc15h7RsxG">
|
||||||
|
<mxGraphModel dx="1036" dy="614" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0" />
|
||||||
|
<mxCell id="1" parent="0" />
|
||||||
|
<mxCell id="KNYXeKKRTsCmKzyxKpLt-1" value="host" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="60" y="280" width="90" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="KNYXeKKRTsCmKzyxKpLt-2" value="slave" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="270" y="280" width="90" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "(gdb) Launch",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/port_self.exe", //只改这里
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": true,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// "preLaunchTask": "build_111" //可以新增一条
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -28,5 +28,6 @@
|
||||||
"binaryPath": "d:\\WORK\\erpc\\port_self.exe",
|
"binaryPath": "d:\\WORK\\erpc\\port_self.exe",
|
||||||
"binaryArgs": []
|
"binaryArgs": []
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"cmake.ignoreCMakeListsMissing": true
|
||||||
}
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "cppbuild",
|
||||||
|
"label": "build_111",
|
||||||
|
"command": "make",
|
||||||
|
"args": [
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${fileDirname}"
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"detail": "调试器生成的任务。"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "2.0.0"
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3
config.h
3
config.h
|
@ -8,4 +8,7 @@
|
||||||
#define u16 unsigned short
|
#define u16 unsigned short
|
||||||
#define u32 unsigned int
|
#define u32 unsigned int
|
||||||
|
|
||||||
|
#define UNUSED(x) (void)(x)
|
||||||
|
#define ERPC_DEBUG(...) printf(__VA_ARGS__)
|
||||||
|
// #define ERPC_DEBUG(...)
|
||||||
#endif /* _CONFIG_H_ */
|
#endif /* _CONFIG_H_ */
|
14
crc16.c
14
crc16.c
|
@ -31,13 +31,13 @@ static const uint16_t crc16tab[256] = {
|
||||||
0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
|
0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
|
||||||
0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
|
0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
|
||||||
|
|
||||||
uint16_t crc16(const unsigned char *buf, size_t len) {
|
// uint16_t crc16(const unsigned char *buf, size_t len) {
|
||||||
int counter;
|
// int counter;
|
||||||
uint16_t crc = 0;
|
// uint16_t crc = 0;
|
||||||
for (counter = 0; counter < len; counter++)
|
// for (counter = 0; counter < (int)len; counter++)
|
||||||
crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *buf++) & 0x00FF];
|
// crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *buf++) & 0x00FF];
|
||||||
return crc;
|
// return crc;
|
||||||
}
|
// }
|
||||||
|
|
||||||
u16 cmd_cal_crc16(erpc_cmd_def_t *cmd) {
|
u16 cmd_cal_crc16(erpc_cmd_def_t *cmd) {
|
||||||
u16 crc = 0;
|
u16 crc = 0;
|
||||||
|
|
292
erpc_core.c
292
erpc_core.c
|
@ -9,11 +9,14 @@
|
||||||
erpc_sleep erpc_sleep_tick = NULL;
|
erpc_sleep erpc_sleep_tick = NULL;
|
||||||
|
|
||||||
static list_t erpc_hw;
|
static list_t erpc_hw;
|
||||||
void clean_cache(erpc_hw_cfg_t *hw) {
|
void clean_cache(erpc_hw_cfg_t *hw)
|
||||||
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) {
|
{
|
||||||
|
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++)
|
||||||
|
{
|
||||||
hw->rec_cache->state = ERPC_CMD_NO_ERROR;
|
hw->rec_cache->state = ERPC_CMD_NO_ERROR;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) {
|
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
|
||||||
|
{
|
||||||
hw->send_cache[i].state = ERPC_CMD_NO_ERROR;
|
hw->send_cache[i].state = ERPC_CMD_NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,29 +24,35 @@ void clean_cache(erpc_hw_cfg_t *hw) {
|
||||||
* 注册 hardware 设备
|
* 注册 hardware 设备
|
||||||
* 线程不安全
|
* 线程不安全
|
||||||
*/
|
*/
|
||||||
u32 erpc_hw_add(erpc_hw_cfg_t *hw) {
|
u32 erpc_hw_add(erpc_hw_cfg_t *hw)
|
||||||
|
{
|
||||||
list_t *list = &erpc_hw;
|
list_t *list = &erpc_hw;
|
||||||
if (list->data == NULL) {
|
if (list->data == NULL)
|
||||||
|
{
|
||||||
list->data = (void *)hw;
|
list->data = (void *)hw;
|
||||||
clean_cache(hw);
|
clean_cache(hw);
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
list_t *list_node = malloc(sizeof(list_t));
|
list_t *list_node = malloc(sizeof(list_t));
|
||||||
if (list_node == NULL) {
|
if (list_node == NULL)
|
||||||
|
{
|
||||||
return ERPC_ERR_MALLOC_ERROR;
|
return ERPC_ERR_MALLOC_ERROR;
|
||||||
}
|
}
|
||||||
list_node->data = (void *)hw;
|
list_node->data = (void *)hw;
|
||||||
u8 hw_ord = hw->ord;
|
u8 hw_ord = hw->ord;
|
||||||
// 检查hw是否已经存在
|
// 检查hw是否已经存在
|
||||||
while (list != NULL) {
|
while (list != NULL)
|
||||||
|
{
|
||||||
erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
|
erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
|
||||||
if (hw_cfg->ord == hw_ord) {
|
if (hw_cfg->ord == hw_ord)
|
||||||
|
{
|
||||||
return ERPC_ERR_HW_EXIST;
|
return ERPC_ERR_HW_EXIST;
|
||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
list_t *result = list_append(&erpc_hw, hw);
|
list_t *result = list_append(&erpc_hw, hw);
|
||||||
if (result == NULL) {
|
if (result == NULL)
|
||||||
|
{
|
||||||
return ERPC_ERR_MALLOC_ERROR;
|
return ERPC_ERR_MALLOC_ERROR;
|
||||||
}
|
}
|
||||||
clean_cache(hw);
|
clean_cache(hw);
|
||||||
|
@ -53,14 +62,17 @@ u32 erpc_hw_add(erpc_hw_cfg_t *hw) {
|
||||||
* 注册命令列表
|
* 注册命令列表
|
||||||
* 线程不安全
|
* 线程不安全
|
||||||
*/
|
*/
|
||||||
u32 erpc_add_cmd_list(erpc_hw_cfg_t *hw, erpc_cmd_list_t *cmd_list) {
|
u32 erpc_add_cmd_list(erpc_hw_cfg_t *hw, erpc_cmd_list_t *cmd_list)
|
||||||
|
{
|
||||||
list_t *list = &hw->cmd_list;
|
list_t *list = &hw->cmd_list;
|
||||||
if (list->data == NULL) {
|
if (list->data == NULL)
|
||||||
|
{
|
||||||
list->data = (void *)cmd_list;
|
list->data = (void *)cmd_list;
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
list = list_append(&hw->cmd_list, cmd_list);
|
list = list_append(&hw->cmd_list, cmd_list);
|
||||||
if (list == NULL) {
|
if (list == NULL)
|
||||||
|
{
|
||||||
return ERPC_ERR_MALLOC_ERROR;
|
return ERPC_ERR_MALLOC_ERROR;
|
||||||
}
|
}
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
|
@ -69,14 +81,18 @@ u32 erpc_add_cmd_list(erpc_hw_cfg_t *hw, erpc_cmd_list_t *cmd_list) {
|
||||||
* 移除 hardware 设备
|
* 移除 hardware 设备
|
||||||
* 线程不安全
|
* 线程不安全
|
||||||
*/
|
*/
|
||||||
u32 erpc_hw_remove(u8 hw) {
|
u32 erpc_hw_remove(u8 hw)
|
||||||
|
{
|
||||||
list_t *list = &erpc_hw;
|
list_t *list = &erpc_hw;
|
||||||
if (list->data == NULL) {
|
if (list->data == NULL)
|
||||||
|
{
|
||||||
return ERPC_ERR_NOFOND_HW;
|
return ERPC_ERR_NOFOND_HW;
|
||||||
}
|
}
|
||||||
while (list != NULL) {
|
while (list != NULL)
|
||||||
|
{
|
||||||
erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
|
erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
|
||||||
if (hw_cfg->ord == hw) {
|
if (hw_cfg->ord == hw)
|
||||||
|
{
|
||||||
list_delete(&erpc_hw, list);
|
list_delete(&erpc_hw, list);
|
||||||
free(list);
|
free(list);
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
|
@ -88,27 +104,34 @@ u32 erpc_hw_remove(u8 hw) {
|
||||||
/**
|
/**
|
||||||
* 获取 hardware 设备
|
* 获取 hardware 设备
|
||||||
*/
|
*/
|
||||||
erpc_hw_cfg_t *erpc_hw_get(u8 hw) {
|
erpc_hw_cfg_t *erpc_hw_get(u8 hw)
|
||||||
|
{
|
||||||
list_t *list = &erpc_hw;
|
list_t *list = &erpc_hw;
|
||||||
if (list->data == NULL) {
|
if (list->data == NULL)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
while (list != NULL) {
|
while (list != NULL)
|
||||||
|
{
|
||||||
erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
|
erpc_hw_cfg_t *hw_cfg = (erpc_hw_cfg_t *)list->data;
|
||||||
if (hw_cfg->ord == hw) {
|
if (hw_cfg->ord == hw)
|
||||||
|
{
|
||||||
return hw_cfg;
|
return hw_cfg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
u32 erpc_send_base(erpc_hw_cfg_t *hw_cfg, u8 dest_id, u16 port, u8 package_type,
|
u32 erpc_send_base(erpc_hw_cfg_t *hw_cfg, u8 dest_id, u16 port, u8 package_type,
|
||||||
u8 *data, u16 len) {
|
u8 *data, u16 len)
|
||||||
|
{
|
||||||
CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
|
CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
|
||||||
u8 cache_ord = 255;
|
u8 cache_ord = 255;
|
||||||
// 查找可用的发送缓存
|
// 查找可用的发送缓存
|
||||||
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) {
|
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
|
||||||
if (hw_cfg->send_cache[i].state == ERPC_CMD_NO_ERROR) {
|
{
|
||||||
printf("find send cache %d\n", i);
|
if (hw_cfg->send_cache[i].state == ERPC_CMD_NO_ERROR)
|
||||||
|
{
|
||||||
|
ERPC_DEBUG("find send cache %d\n", i);
|
||||||
cache_ord = i;
|
cache_ord = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -122,13 +145,19 @@ u32 erpc_send_base(erpc_hw_cfg_t *hw_cfg, u8 dest_id, u16 port, u8 package_type,
|
||||||
cmd->head.dest_id = dest_id;
|
cmd->head.dest_id = dest_id;
|
||||||
cmd->head.port = port;
|
cmd->head.port = port;
|
||||||
cmd->head.msg_len = len;
|
cmd->head.msg_len = len;
|
||||||
if (data != NULL) {
|
if (data == NULL)
|
||||||
|
{
|
||||||
cmd->head.msg_len = 0;
|
cmd->head.msg_len = 0;
|
||||||
|
len = 0;
|
||||||
}
|
}
|
||||||
cmd->head.type = package_type;
|
cmd->head.type = package_type;
|
||||||
cmd->head.src_id = hw_cfg->local_id;
|
cmd->head.src_id = hw_cfg->local_id;
|
||||||
if (len > 0 && data != NULL) {
|
if (len > 0 && data != NULL)
|
||||||
memcpy(cmd->data, data, len);
|
{
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
cmd->data[i] = data[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 计算校验和
|
// 计算校验和
|
||||||
cmd_cal_crc16(cmd);
|
cmd_cal_crc16(cmd);
|
||||||
|
@ -137,29 +166,37 @@ u32 erpc_send_base(erpc_hw_cfg_t *hw_cfg, u8 dest_id, u16 port, u8 package_type,
|
||||||
hw_cfg->send_cache[cache_ord].state = ERPC_CMD_WAIT_SEND;
|
hw_cfg->send_cache[cache_ord].state = ERPC_CMD_WAIT_SEND;
|
||||||
// 等待数据发送完成
|
// 等待数据发送完成
|
||||||
int wait_time = CMD_TIMEOUT;
|
int wait_time = CMD_TIMEOUT;
|
||||||
while (wait_time > 0) {
|
while (wait_time > 0)
|
||||||
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_OK) {
|
{
|
||||||
|
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_OK)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_DEST_BUSY) {
|
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_DEST_BUSY)
|
||||||
|
{
|
||||||
return ERPC_ERR_DEST_BUSY;
|
return ERPC_ERR_DEST_BUSY;
|
||||||
}
|
}
|
||||||
if (erpc_sleep_tick != NULL) {
|
if (erpc_sleep_tick != NULL)
|
||||||
|
{
|
||||||
erpc_sleep_tick(1);
|
erpc_sleep_tick(1);
|
||||||
}
|
}
|
||||||
wait_time--;
|
wait_time--;
|
||||||
}
|
}
|
||||||
u32 ret = ERPC_NO_ERROR;
|
u32 ret = ERPC_NO_ERROR;
|
||||||
do {
|
do
|
||||||
if (wait_time == 0) {
|
{
|
||||||
|
if (wait_time == 0)
|
||||||
|
{
|
||||||
ret = ERPC_ERR_SEND_TIMEOUT;
|
ret = ERPC_ERR_SEND_TIMEOUT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_ONCE) {
|
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_ONCE)
|
||||||
|
{
|
||||||
ret = ERPC_ERR_DEST_NO_RESPONSE;
|
ret = ERPC_ERR_DEST_NO_RESPONSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_REPEAT) {
|
if (hw_cfg->send_cache[cache_ord].state == ERPC_CMD_SEND_REPEAT)
|
||||||
|
{
|
||||||
ret = ERPC_ERR_DEST_NO_RESPONSE;
|
ret = ERPC_ERR_DEST_NO_RESPONSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -167,7 +204,8 @@ u32 erpc_send_base(erpc_hw_cfg_t *hw_cfg, u8 dest_id, u16 port, u8 package_type,
|
||||||
hw_cfg->send_cache[cache_ord].state = ERPC_CMD_NO_ERROR;
|
hw_cfg->send_cache[cache_ord].state = ERPC_CMD_NO_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len) {
|
u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len)
|
||||||
|
{
|
||||||
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
|
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
|
||||||
u32 ret =
|
u32 ret =
|
||||||
erpc_send_base(hw_cfg, dest_id, port, PACKAGE_TYPE_CMD_REQ, data, len);
|
erpc_send_base(hw_cfg, dest_id, port, PACKAGE_TYPE_CMD_REQ, data, len);
|
||||||
|
@ -175,30 +213,42 @@ u32 erpc_send(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 erpc_wait_resp_package(u8 hw, u8 dest_id, u16 port, u8 *reply_data,
|
u32 erpc_wait_resp_package(u8 hw, u8 dest_id, u16 port, u8 *reply_data,
|
||||||
u16 *reply_len, u32 time_out) {
|
u16 *reply_len, u32 time_out)
|
||||||
|
{
|
||||||
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
|
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
|
||||||
CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
|
CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
|
||||||
while (time_out > 0) {
|
while (time_out > 0)
|
||||||
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) {
|
{
|
||||||
|
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++)
|
||||||
|
{
|
||||||
erpc_data_cache_t *rec_cahce = &hw_cfg->rec_cache[i];
|
erpc_data_cache_t *rec_cahce = &hw_cfg->rec_cache[i];
|
||||||
if (rec_cahce->state != ERPC_CMD_RESP_OK) {
|
if (rec_cahce->state != ERPC_CMD_RESP_OK)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&rec_cahce->data[0];
|
erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&rec_cahce->data[0];
|
||||||
if (cmd->head.port != port) {
|
if (cmd->head.port != port)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cmd->head.src_id != dest_id) {
|
if (cmd->head.src_id != dest_id)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (reply_data != NULL) {
|
if (reply_data != NULL)
|
||||||
memccpy(reply_data, cmd->data, 0, cmd->head.msg_len);
|
{
|
||||||
|
// memccpy(reply_data, cmd->data, 0, cmd->head.msg_len);
|
||||||
|
memcpy(reply_data, cmd->data, cmd->head.msg_len);
|
||||||
|
if (reply_len != NULL)
|
||||||
|
{
|
||||||
*reply_len = cmd->head.msg_len;
|
*reply_len = cmd->head.msg_len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
rec_cahce->state = ERPC_CMD_NO_ERROR;
|
rec_cahce->state = ERPC_CMD_NO_ERROR;
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
if (erpc_sleep_tick != NULL) {
|
if (erpc_sleep_tick != NULL)
|
||||||
|
{
|
||||||
erpc_sleep_tick(1);
|
erpc_sleep_tick(1);
|
||||||
}
|
}
|
||||||
time_out--;
|
time_out--;
|
||||||
|
@ -207,29 +257,34 @@ u32 erpc_wait_resp_package(u8 hw, u8 dest_id, u16 port, u8 *reply_data,
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
u32 erpc_send_wait_reply(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) {
|
u8 *reply_data, u16 *reply_len, u32 timeout)
|
||||||
|
{
|
||||||
u32 ret = erpc_send(hw, dest_id, port, data, len);
|
u32 ret = erpc_send(hw, dest_id, port, data, len);
|
||||||
if (reply_len != NULL) {
|
if (reply_len != NULL)
|
||||||
|
{
|
||||||
*reply_len = 0;
|
*reply_len = 0;
|
||||||
}
|
}
|
||||||
CHECK_IF_ERROR(ret != ERPC_NO_ERROR, ret);
|
CHECK_IF_ERROR(ret != ERPC_NO_ERROR, ret);
|
||||||
printf("send ok\n");
|
|
||||||
ret =
|
ret =
|
||||||
erpc_wait_resp_package(hw, dest_id, port, reply_data, reply_len, timeout);
|
erpc_wait_resp_package(hw, dest_id, port, reply_data, reply_len, timeout);
|
||||||
CHECK_IF_ERROR(ret != ERPC_NO_ERROR, ret);
|
CHECK_IF_ERROR(ret != ERPC_NO_ERROR, ret);
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
u32 erpc_replay(u8 hw, u8 dest_id, u16 port, u8 *data_out, u16 len) {
|
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);
|
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
|
||||||
u32 ret = erpc_send_base(hw_cfg, dest_id, port, PACKAGE_TYPE_CMD_REPEAT,
|
u32 ret = erpc_send_base(hw_cfg, dest_id, port, PACKAGE_TYPE_CMD_RESP,
|
||||||
data_out, len);
|
data_out, len);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 erpc_send_data(erpc_hw_cfg_t *hw) {
|
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) {
|
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
|
||||||
|
{
|
||||||
|
if (hw->send_cache[i].state == ERPC_CMD_WAIT_SEND)
|
||||||
|
{
|
||||||
erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
|
erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
|
||||||
u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd->head.msg_len;
|
u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd->head.msg_len;
|
||||||
hw->send_lock();
|
hw->send_lock();
|
||||||
|
@ -242,12 +297,16 @@ u32 erpc_send_data(erpc_hw_cfg_t *hw) {
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 erpc_rev_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
|
u32 erpc_rev_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
|
||||||
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) {
|
{
|
||||||
|
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
|
||||||
|
{
|
||||||
if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE ||
|
if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE ||
|
||||||
hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT) {
|
hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT)
|
||||||
|
{
|
||||||
erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
|
erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
|
||||||
if (cmd_rev->head.port == cmd_send->head.port) {
|
if (cmd_rev->head.port == cmd_send->head.port)
|
||||||
|
{
|
||||||
hw->send_cache[i].state = ERPC_CMD_SEND_OK;
|
hw->send_cache[i].state = ERPC_CMD_SEND_OK;
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -255,7 +314,8 @@ u32 erpc_rev_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
|
||||||
}
|
}
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
u32 erpc_rev_resp_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
|
u32 erpc_rev_resp_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
|
||||||
|
{
|
||||||
erpc_cmd_def_t cmd_send;
|
erpc_cmd_def_t cmd_send;
|
||||||
cmd_send.head.dest_id = cmd_rev->head.src_id;
|
cmd_send.head.dest_id = cmd_rev->head.src_id;
|
||||||
cmd_send.head.port = cmd_rev->head.port;
|
cmd_send.head.port = cmd_rev->head.port;
|
||||||
|
@ -271,12 +331,16 @@ u32 erpc_rev_resp_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
// 重发数据包
|
// 重发数据包
|
||||||
u32 erpc_rev_repeat_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
|
u32 erpc_rev_repeat_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
|
||||||
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++) {
|
{
|
||||||
|
for (int i = 0; i < MAX_SEND_CMD_CACHE_NUM; i++)
|
||||||
|
{
|
||||||
if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE ||
|
if (hw->send_cache[i].state == ERPC_CMD_SEND_ONCE ||
|
||||||
hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT) {
|
hw->send_cache[i].state == ERPC_CMD_SEND_REPEAT)
|
||||||
|
{
|
||||||
erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
|
erpc_cmd_def_t *cmd_send = (erpc_cmd_def_t *)&hw->send_cache[i].data[0];
|
||||||
if (cmd_rev->head.port == cmd_send->head.port) {
|
if (cmd_rev->head.port == cmd_send->head.port)
|
||||||
|
{
|
||||||
u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd_send->head.msg_len;
|
u32 len = sizeof(erpc_cmd_head_t) + 2 + cmd_send->head.msg_len;
|
||||||
hw->send_lock();
|
hw->send_lock();
|
||||||
u32 ret = hw->write((u8 *)hw->send_cache[i].data, len);
|
u32 ret = hw->write((u8 *)hw->send_cache[i].data, len);
|
||||||
|
@ -289,7 +353,8 @@ u32 erpc_rev_repeat_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
|
||||||
}
|
}
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
u32 erpc_send_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
|
u32 erpc_send_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev)
|
||||||
|
{
|
||||||
erpc_cmd_def_t cmd_send;
|
erpc_cmd_def_t cmd_send;
|
||||||
cmd_send.head.dest_id = cmd_rev->head.src_id;
|
cmd_send.head.dest_id = cmd_rev->head.src_id;
|
||||||
cmd_send.head.port = cmd_rev->head.port;
|
cmd_send.head.port = cmd_rev->head.port;
|
||||||
|
@ -305,44 +370,56 @@ u32 erpc_send_ack_package(erpc_hw_cfg_t *hw, erpc_cmd_def_t *cmd_rev) {
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 erpc_rev_package(erpc_hw_cfg_t *hw) {
|
u32 erpc_rev_package(erpc_hw_cfg_t *hw)
|
||||||
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) {
|
{
|
||||||
if (hw->rec_cache[i].state == ERPC_CMD_WAIT_SERVER_DEAL) {
|
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++)
|
||||||
|
{
|
||||||
|
if (hw->rec_cache[i].state == ERPC_CMD_WAIT_SERVER_DEAL)
|
||||||
|
{
|
||||||
|
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];
|
erpc_cmd_def_t *cmd = (erpc_cmd_def_t *)&hw->rec_cache[i].data[0];
|
||||||
// 检查crc
|
// 检查crc
|
||||||
u8 crc_result = cmd_check_crc16(cmd);
|
u8 crc_result = cmd_check_crc16(cmd);
|
||||||
// 丢弃错误数据包
|
// 丢弃错误数据包
|
||||||
if (crc_result) {
|
if (crc_result)
|
||||||
|
{
|
||||||
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
|
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 丢弃不是本地数据包
|
// 丢弃不是本地数据包
|
||||||
if (cmd->head.dest_id != hw->local_id) {
|
if (cmd->head.dest_id != hw->local_id)
|
||||||
|
{
|
||||||
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
|
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 处理数据包
|
// 处理数据包
|
||||||
switch (cmd->head.type) {
|
switch (cmd->head.type)
|
||||||
|
{
|
||||||
case PACKAGE_TYPE_CMD_REQ:
|
case PACKAGE_TYPE_CMD_REQ:
|
||||||
printf("{REQ}\n");
|
ERPC_DEBUG("{REQ}\n");
|
||||||
erpc_send_ack_package(hw, cmd);
|
erpc_send_ack_package(hw, cmd);
|
||||||
hw->rec_cache[i].state = ERPC_CMD_WAIT_TASK_DEAL;
|
hw->rec_cache[i].state = ERPC_CMD_WAIT_TASK_DEAL;
|
||||||
break;
|
break;
|
||||||
case PACKAGE_TYPE_CMD_REQ_ACK:
|
case PACKAGE_TYPE_CMD_REQ_ACK:
|
||||||
case PACKAGE_TYPE_CMD_RESP_ACK:
|
ERPC_DEBUG("{ACK}\n");
|
||||||
printf("{ACK}\n");
|
|
||||||
erpc_rev_ack_package(hw, cmd);
|
erpc_rev_ack_package(hw, cmd);
|
||||||
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
|
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKAGE_TYPE_CMD_REPEAT:
|
case PACKAGE_TYPE_CMD_REPEAT:
|
||||||
erpc_rev_repeat_package(hw, cmd);
|
erpc_rev_repeat_package(hw, cmd);
|
||||||
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
|
hw->rec_cache[i].state = ERPC_CMD_NO_ERROR;
|
||||||
break;
|
break;
|
||||||
case PACKAGE_TYPE_CMD_RESP:
|
case PACKAGE_TYPE_CMD_RESP:
|
||||||
printf("{RESP}\n");
|
ERPC_DEBUG("{RESP}\n");
|
||||||
erpc_rev_resp_package(hw, cmd);
|
erpc_rev_resp_package(hw, cmd);
|
||||||
hw->rec_cache[i].state = ERPC_CMD_RESP_OK;
|
hw->rec_cache[i].state = ERPC_CMD_RESP_OK;
|
||||||
break;
|
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:
|
default:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -351,23 +428,29 @@ u32 erpc_rev_package(erpc_hw_cfg_t *hw) {
|
||||||
}
|
}
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
}
|
}
|
||||||
void erpc_rev_package_core() {
|
void erpc_rev_package_core()
|
||||||
|
{
|
||||||
list_t *list = &erpc_hw;
|
list_t *list = &erpc_hw;
|
||||||
if (list->data == NULL) {
|
if (list->data == NULL)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (list != NULL) {
|
while (list != NULL)
|
||||||
|
{
|
||||||
erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
|
erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
|
||||||
erpc_rev_package(hw);
|
erpc_rev_package(hw);
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len) {
|
u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len)
|
||||||
|
{
|
||||||
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
|
erpc_hw_cfg_t *hw_cfg = erpc_hw_get(hw);
|
||||||
CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
|
CHECK_IF_ERROR(hw_cfg == NULL, ERPC_ERR_NOFOND_HW);
|
||||||
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++) {
|
for (int i = 0; i < MAX_REC_CMD_CACHE_NUM; i++)
|
||||||
if (hw_cfg->rec_cache[i].state == ERPC_CMD_NO_ERROR) {
|
{
|
||||||
printf("set rev cache %d\r\n", 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);
|
memcpy(hw_cfg->rec_cache[i].data, data, len);
|
||||||
hw_cfg->rec_cache[i].state = ERPC_CMD_WAIT_SERVER_DEAL;
|
hw_cfg->rec_cache[i].state = ERPC_CMD_WAIT_SERVER_DEAL;
|
||||||
return ERPC_NO_ERROR;
|
return ERPC_NO_ERROR;
|
||||||
|
@ -375,40 +458,52 @@ u32 erpc_set_rev_cahce(u8 hw, u8 *data, u16 len) {
|
||||||
}
|
}
|
||||||
return ERPC_ERR_REC_CACHE_FULL;
|
return ERPC_ERR_REC_CACHE_FULL;
|
||||||
}
|
}
|
||||||
void erpc_send_deal_core() {
|
void erpc_send_deal_core()
|
||||||
|
{
|
||||||
list_t *list = &erpc_hw;
|
list_t *list = &erpc_hw;
|
||||||
if (list->data == NULL) {
|
if (list->data == NULL)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (list != NULL) {
|
while (list != NULL)
|
||||||
|
{
|
||||||
erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
|
erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
|
||||||
erpc_send_data(hw);
|
erpc_send_data(hw);
|
||||||
}
|
}
|
||||||
if (erpc_sleep_tick != NULL) {
|
if (erpc_sleep_tick != NULL)
|
||||||
|
{
|
||||||
erpc_sleep_tick(1);
|
erpc_sleep_tick(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void erpc_rev_deal_core() {
|
void erpc_rev_deal_core()
|
||||||
|
{
|
||||||
list_t *list = &erpc_hw;
|
list_t *list = &erpc_hw;
|
||||||
if (list->data == NULL) {
|
if (list->data == NULL)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (list != NULL) {
|
while (list != NULL)
|
||||||
|
{
|
||||||
erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
|
erpc_hw_cfg_t *hw = (erpc_hw_cfg_t *)list->data;
|
||||||
{ // 遍历接收缓存
|
{ // 遍历接收缓存
|
||||||
for (int j = 0; j < MAX_REC_CMD_CACHE_NUM; j++) {
|
for (int j = 0; j < MAX_REC_CMD_CACHE_NUM; j++)
|
||||||
|
{
|
||||||
{ // 发现等待处理的数据包
|
{ // 发现等待处理的数据包
|
||||||
if (hw->rec_cache[j].state != ERPC_CMD_WAIT_TASK_DEAL) {
|
if (hw->rec_cache[j].state != ERPC_CMD_WAIT_TASK_DEAL)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ // 多线程下,抢占处理权限
|
{ // 多线程下,抢占处理权限
|
||||||
hw->deal_lock();
|
hw->deal_lock();
|
||||||
if (hw->rec_cache[j].state == ERPC_CMD_WAIT_TASK_DEAL) {
|
if (hw->rec_cache[j].state == ERPC_CMD_WAIT_TASK_DEAL)
|
||||||
|
{
|
||||||
// 获取指令的处理权限
|
// 获取指令的处理权限
|
||||||
hw->rec_cache[j].state = ERPC_CMD_WAIT_TASK_DEAL_FINISH;
|
hw->rec_cache[j].state = ERPC_CMD_WAIT_TASK_DEAL_FINISH;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// 已经有线程抢先执行了
|
// 已经有线程抢先执行了
|
||||||
hw->deal_unlock();
|
hw->deal_unlock();
|
||||||
continue;
|
continue;
|
||||||
|
@ -419,15 +514,19 @@ void erpc_rev_deal_core() {
|
||||||
// 搜索指令列表
|
// 搜索指令列表
|
||||||
list_t *cmd_list = &hw->cmd_list;
|
list_t *cmd_list = &hw->cmd_list;
|
||||||
// 链表是空的
|
// 链表是空的
|
||||||
if (cmd_list->data == NULL) {
|
if (cmd_list->data == NULL)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 获取指令指针
|
// 获取指令指针
|
||||||
erpc_cmd_def_t *cmd_def = (erpc_cmd_def_t *)hw->rec_cache[j].data;
|
erpc_cmd_def_t *cmd_def = (erpc_cmd_def_t *)hw->rec_cache[j].data;
|
||||||
while (cmd_list != NULL) { // 搜索指令列表
|
while (cmd_list != NULL)
|
||||||
|
{ // 搜索指令列表
|
||||||
erpc_cmd_list_t *cmd_obj = (erpc_cmd_list_t *)cmd_list->data;
|
erpc_cmd_list_t *cmd_obj = (erpc_cmd_list_t *)cmd_list->data;
|
||||||
if (cmd_obj->cmd == cmd_def->head.port) {
|
if (cmd_obj->cmd == cmd_def->head.port)
|
||||||
if (cmd_obj->handle != NULL) {
|
{
|
||||||
|
if (cmd_obj->handle != NULL)
|
||||||
|
{
|
||||||
// 指令调用
|
// 指令调用
|
||||||
cmd_obj->handle(hw->ord, cmd_def->head.src_id,
|
cmd_obj->handle(hw->ord, cmd_def->head.src_id,
|
||||||
cmd_def->head.dest_id, cmd_def->head.port,
|
cmd_def->head.dest_id, cmd_def->head.port,
|
||||||
|
@ -445,7 +544,8 @@ void erpc_rev_deal_core() {
|
||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
if (erpc_sleep_tick != NULL) {
|
if (erpc_sleep_tick != NULL)
|
||||||
|
{
|
||||||
erpc_sleep_tick(1);
|
erpc_sleep_tick(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -31,13 +31,14 @@ typedef struct erpc_cmd_head_t {
|
||||||
u8 msg_len;
|
u8 msg_len;
|
||||||
} erpc_cmd_head_t;
|
} erpc_cmd_head_t;
|
||||||
|
|
||||||
|
#define MAX_CMD_LEN (256 - sizeof(erpc_cmd_head_t)) // crc16最大支持256字节
|
||||||
|
|
||||||
typedef struct erpc_cmd_def_t {
|
typedef struct erpc_cmd_def_t {
|
||||||
erpc_cmd_head_t head;
|
erpc_cmd_head_t head;
|
||||||
u8 crc_16[2];
|
u8 crc_16[2];
|
||||||
u8 *data;
|
u8 data[MAX_CMD_LEN];
|
||||||
} erpc_cmd_def_t;
|
} erpc_cmd_def_t;
|
||||||
|
|
||||||
#define MAX_CMD_LEN (256 - sizeof(erpc_cmd_head_t)) // crc16最大支持256字节
|
|
||||||
#define CMD_MAX_RETRY 5 // 最大重发次数
|
#define CMD_MAX_RETRY 5 // 最大重发次数
|
||||||
#define CMD_TIMEOUT 30 // 超时时间 tick
|
#define CMD_TIMEOUT 30 // 超时时间 tick
|
||||||
#define MAX_REC_CMD_CACHE_NUM \
|
#define MAX_REC_CMD_CACHE_NUM \
|
||||||
|
|
BIN
erpc_core.o
BIN
erpc_core.o
Binary file not shown.
38
erpc设计文档.md
38
erpc设计文档.md
|
@ -1 +1,39 @@
|
||||||
|
|
||||||
|
## 协议设计
|
||||||
|
|
||||||
|
### 指令通讯
|
||||||
|
1. 指令发送方法:<br>
|
||||||
|
采用send-ack模式,即主机发送指令后,等待目标设备的ack确认,确认后才认为指令发送成功。
|
||||||
|
2. notify-noreply模式:<br>
|
||||||
|
接口:<br>
|
||||||
|
```c
|
||||||
|
u32 erpc_sand(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len)
|
||||||
|
```
|
||||||
|
描述:<br>
|
||||||
|
主机对目标设备发送一条指令,并不期待回复。其本质就是发送一次指令。
|
||||||
|
![](./picture/1.jpg)
|
||||||
|
3. notify-reply模式:<br>
|
||||||
|
接口:<br>
|
||||||
|
```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);
|
||||||
|
|
||||||
|
```
|
||||||
|
描述:<br>
|
||||||
|
本质由2条指令组成。<br>
|
||||||
|
主机发送req指令,从机直接回复。主机开始等待从机指令。<br>
|
||||||
|
从机处理完成后,向主机发送rep指令,并附带回复数据。<br>
|
||||||
|
主机收到rep指令后,开始等待rep指令的ack确认。<br>
|
||||||
|
![](./picture/2.jpg)
|
||||||
|
4. 指令工作在单线程模式下:<br>
|
||||||
|
指令发送后,等待ack确认,直到确认后才认为指令发送成功。如果确认超时,则认为指令发送失败。
|
||||||
|
可以在上述的接口中发现 cmd 并不定义为cmd,而是用了port的称呼。port的取值范围为0~65535,可以用来表示不同的指令。<br>
|
||||||
|
|
||||||
|
4. 多device通讯方法:<br>
|
||||||
|
每个port工作是单线程的,这就意味着,如果有多个device需要同时发送指令,则需要多线程或多进程。也就意味着需要定义不同的port号,来区分不同的线程,哪怕他是相同的指令。<br>
|
||||||
|
例如:节点0x03中挂在了3个电机,需要这3个电机同时运动,此时理论上指令是相同的,但是device不同的。通讯库没有做device id的区分。为此需要将port号划分为cmd + device id的形式。cmd相同的指令,device id不同,这样就可以实现多device通讯。<br>
|
||||||
|
u16(port) = u8(cmd) + u8(device_id);<br>
|
||||||
|
这样一个cmd号需要链接到多个port上。此时的cmd可叫做cmd组
|
||||||
|
![](./picture/3.jpg)
|
5
list.c
5
list.c
|
@ -1,6 +1,7 @@
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "config.h"
|
||||||
list_t *list_create(void *data)
|
list_t *list_create(void *data)
|
||||||
{
|
{
|
||||||
list_t *node = (list_t *)malloc(sizeof(list_t));
|
list_t *node = (list_t *)malloc(sizeof(list_t));
|
||||||
|
@ -41,7 +42,7 @@ void list_print(list_t *head)
|
||||||
list_t *node = head;
|
list_t *node = head;
|
||||||
while (node != NULL)
|
while (node != NULL)
|
||||||
{
|
{
|
||||||
printf("%p\n", node->data);
|
ERPC_DEBUG("%p\n", node->data);
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
8
makefile
8
makefile
|
@ -3,8 +3,8 @@
|
||||||
# 指定编译器
|
# 指定编译器
|
||||||
CC = gcc
|
CC = gcc
|
||||||
# 指定编译选项
|
# 指定编译选项
|
||||||
CFLAGS = -Wall -Wextra -std=c11
|
CFLAGS = -Wall -Wextra -std=c11 -g
|
||||||
|
BUILD_DIR = build
|
||||||
# 源文件
|
# 源文件
|
||||||
SRCS = erpc_core.c \
|
SRCS = erpc_core.c \
|
||||||
port_self.c \
|
port_self.c \
|
||||||
|
@ -22,11 +22,11 @@ all: $(Target)
|
||||||
|
|
||||||
# 链接目标
|
# 链接目标
|
||||||
$(Target): $(OBJS)
|
$(Target): $(OBJS)
|
||||||
$(CC) -o $@ $^
|
$(CC) -o $@ $(addprefix $(BUILD_DIR)/, $^)
|
||||||
|
|
||||||
# 编译源文件
|
# 编译源文件
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $(BUILD_DIR)/$@
|
||||||
|
|
||||||
# 清理目标
|
# 清理目标
|
||||||
clean:
|
clean:
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
77
port_self.c
77
port_self.c
|
@ -6,20 +6,48 @@
|
||||||
#include "erpc_core.h"
|
#include "erpc_core.h"
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
void hellworld()
|
u32 hellworld(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len)
|
||||||
{
|
{
|
||||||
printf("Hello World!\n");
|
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;
|
||||||
}
|
}
|
||||||
void hello_cat()
|
u32 hello_cat(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len)
|
||||||
{
|
{
|
||||||
printf("Hello Cat!\n");
|
ERPC_DEBUG("Hello Cat!\n");
|
||||||
|
// 防止编译警告
|
||||||
|
UNUSED(hw);
|
||||||
|
UNUSED(src_id);
|
||||||
|
UNUSED(dest_id);
|
||||||
|
UNUSED(port);
|
||||||
|
UNUSED(data);
|
||||||
|
UNUSED(len);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hello_dog(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len)
|
u32 hello_dog(u8 hw, u8 src_id, u8 dest_id, u16 port, u8 *data, u16 len)
|
||||||
{
|
{
|
||||||
printf("Hello Dog!\n");
|
ERPC_DEBUG("Hello Dog!\n");
|
||||||
|
// 防止编译警告
|
||||||
u8 data_out[10] = "12345";
|
u8 data_out[10] = "12345";
|
||||||
erpc_replay(hw, dest_id, port, data_out, sizeof(data_out));
|
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[] = {
|
erpc_cmd_list_t erpc_cmd_list[] = {
|
||||||
{.cmd = 0x01, hellworld},
|
{.cmd = 0x01, hellworld},
|
||||||
|
@ -49,7 +77,7 @@ static void send_unlock_h()
|
||||||
ReleaseMutex(send_lock);
|
ReleaseMutex(send_lock);
|
||||||
}
|
}
|
||||||
u8 data[300];
|
u8 data[300];
|
||||||
static u8 data_write(u8 *data, u32 len)
|
static u8 data_write(u8 *data, u16 len)
|
||||||
{
|
{
|
||||||
erpc_set_rev_cahce(0, data, len);
|
erpc_set_rev_cahce(0, data, len);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -66,7 +94,7 @@ erpc_hw_cfg_t self_hw_cfg = {
|
||||||
};
|
};
|
||||||
void erpc_cmd_config()
|
void erpc_cmd_config()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < sizeof(erpc_cmd_list) / sizeof(erpc_cmd_list[0]); i++)
|
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]);
|
erpc_add_cmd_list(&self_hw_cfg, &erpc_cmd_list[i]);
|
||||||
}
|
}
|
||||||
|
@ -78,6 +106,7 @@ void sys_sleep(u32 ms)
|
||||||
|
|
||||||
DWORD WINAPI send_task(LPVOID lpParam)
|
DWORD WINAPI send_task(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
|
UNUSED(lpParam);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
erpc_send_deal_core();
|
erpc_send_deal_core();
|
||||||
|
@ -85,10 +114,11 @@ DWORD WINAPI send_task(LPVOID lpParam)
|
||||||
}
|
}
|
||||||
DWORD WINAPI rev_task(LPVOID lpParam)
|
DWORD WINAPI rev_task(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
|
UNUSED(lpParam);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
// printf("rev_task\n");
|
// ERPC_DEBUG("rev_task\n");
|
||||||
erpc_rev_package_core();
|
erpc_rev_package_core();
|
||||||
erpc_rev_deal_core();
|
erpc_rev_deal_core();
|
||||||
}
|
}
|
||||||
|
@ -96,42 +126,47 @@ DWORD WINAPI rev_task(LPVOID lpParam)
|
||||||
|
|
||||||
DWORD WINAPI test_task(LPVOID lpParam)
|
DWORD WINAPI test_task(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
printf("test_task\n");
|
UNUSED(lpParam);
|
||||||
|
ERPC_DEBUG("test_task\n");
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
// printf("[test_task]send\n");
|
// ERPC_DEBUG("[test_task]send\n");
|
||||||
u32 ret = erpc_send(self_hw_cfg.ord, self_hw_cfg.local_id, 0x01, NULL, 0);
|
char msg[] = "miao miao miao\n";
|
||||||
printf("[test_task]send ret:%d\n", ret);
|
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);
|
ret = erpc_send(self_hw_cfg.ord, self_hw_cfg.local_id, 0x02, NULL, 0);
|
||||||
printf("[test_task]send ret:%d\n", ret);
|
ERPC_DEBUG("[test_task]send ret:%d\n", ret);
|
||||||
ret = erpc_send_wait_reply(self_hw_cfg.ord, self_hw_cfg.local_id, 0x03, NULL, 0, data, NULL, 1000);
|
ret = erpc_send_wait_reply(self_hw_cfg.ord, self_hw_cfg.local_id, 0x03, NULL, 0, data, NULL, 1000);
|
||||||
printf("[test_task]send ret:%d\n", ret);
|
ERPC_DEBUG("[test_task]send ret:%d\n", ret);
|
||||||
|
UNUSED(ret);
|
||||||
sys_sleep(1000);
|
sys_sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
UNUSED(argc);
|
||||||
|
UNUSED(argv);
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
printf("erpc_port_self start\n");
|
ERPC_DEBUG("erpc_port_self start\n");
|
||||||
ret = erpc_hw_add(&self_hw_cfg);
|
ret = erpc_hw_add(&self_hw_cfg);
|
||||||
printf("erpc_hw_add ret:%d\n", ret);
|
ERPC_DEBUG("erpc_hw_add ret:%d\n", ret);
|
||||||
CHECK_IF_ERROR(ret, 0);
|
CHECK_IF_ERROR(ret, 0);
|
||||||
erpc_cmd_config();
|
erpc_cmd_config();
|
||||||
printf("erpc_cmd_config ret:%d\n", ret);
|
ERPC_DEBUG("erpc_cmd_config ret:%d\n", ret);
|
||||||
erpc_sleep_tick = sys_sleep;
|
erpc_sleep_tick = sys_sleep;
|
||||||
|
|
||||||
HANDLE threadHandle[3];
|
HANDLE threadHandle[3];
|
||||||
deal_lock = CreateMutex(NULL, FALSE, NULL);
|
deal_lock = CreateMutex(NULL, FALSE, NULL);
|
||||||
if (deal_lock == NULL)
|
if (deal_lock == NULL)
|
||||||
{
|
{
|
||||||
printf("创建互斥锁失败,错误代码:%d\n", GetLastError());
|
ERPC_DEBUG("创建互斥锁失败\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
send_lock = CreateMutex(NULL, FALSE, NULL);
|
send_lock = CreateMutex(NULL, FALSE, NULL);
|
||||||
if (send_lock == NULL)
|
if (send_lock == NULL)
|
||||||
{
|
{
|
||||||
printf("创建互斥锁失败,错误代码:%d\n", GetLastError());
|
ERPC_DEBUG("创建互斥锁失败\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
threadHandle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)send_task, NULL, 0, NULL);
|
threadHandle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)send_task, NULL, 0, NULL);
|
||||||
|
|
BIN
port_self.exe
BIN
port_self.exe
Binary file not shown.
BIN
port_self.o
BIN
port_self.o
Binary file not shown.
|
@ -0,0 +1,45 @@
|
||||||
|
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.17 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.17">
|
||||||
|
<diagram name="第 1 页" id="iJ2ThG75liGc15h7RsxG">
|
||||||
|
<mxGraphModel dx="1050" dy="629" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0" />
|
||||||
|
<mxCell id="1" parent="0" />
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="EQYeASZG-p6UUSDICV0d-19" target="EQYeASZG-p6UUSDICV0d-23">
|
||||||
|
<mxGeometry relative="1" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-19" value="port1" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="151" y="392" width="120" height="60" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="EQYeASZG-p6UUSDICV0d-20" target="EQYeASZG-p6UUSDICV0d-23">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="410" y="550" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-20" value="port2" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="151" y="490" width="120" height="60" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-27" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="EQYeASZG-p6UUSDICV0d-21" target="EQYeASZG-p6UUSDICV0d-23">
|
||||||
|
<mxGeometry relative="1" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-21" value="..." style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="151" y="583" width="120" height="60" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="EQYeASZG-p6UUSDICV0d-22" target="EQYeASZG-p6UUSDICV0d-23">
|
||||||
|
<mxGeometry relative="1" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-22" value="portn" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="151" y="680" width="120" height="60" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="EQYeASZG-p6UUSDICV0d-23" target="EQYeASZG-p6UUSDICV0d-24">
|
||||||
|
<mxGeometry relative="1" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-23" value="cmd组" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="414" y="530" width="120" height="60" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="EQYeASZG-p6UUSDICV0d-24" value="相同的处理函数" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="630" y="530" width="120" height="60" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
Loading…
Reference in New Issue