diff --git a/.vscode/settings.json b/.vscode/settings.json index 474cf6ded..de3f17652 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -134,7 +134,9 @@ "irq.h": "c", "irq_sender.h": "c", "u_irq_sender.h": "c", - "u_env.h": "c" + "u_env.h": "c", + "stddef.h": "c", + "u_rpc.h": "c" }, "cortex-debug.showRTOS": false, } \ No newline at end of file diff --git a/mkrtos_knl/inc/knl/prot.h b/mkrtos_knl/inc/knl/prot.h index 43486ba31..557dafbfa 100755 --- a/mkrtos_knl/inc/knl/prot.h +++ b/mkrtos_knl/inc/knl/prot.h @@ -26,6 +26,7 @@ #define FACTORY_FUNC_MAX (IRQ_PROT + 1) #define FACTORY_PORT_END FACTORY_FUNC_MAX +#define MSG_TAG_KNL_ERR 0x8 typedef struct msg_tag { union diff --git a/mkrtos_knl/knl/ipc.c b/mkrtos_knl/knl/ipc.c index 439578819..1679fb0a9 100755 --- a/mkrtos_knl/knl/ipc.c +++ b/mkrtos_knl/knl/ipc.c @@ -179,7 +179,7 @@ __check: { if (add_wait_unlock(ipc, &ipc->wait_send, th, timeout.send_timeout, &ipc->lock, status) < 0) { - return msg_tag_init4(0, 0, 0, -EWTIMEDOUT); + return msg_tag_init4(MSG_TAG_KNL_ERR, 0, 0, -EWTIMEDOUT); } goto __check; } @@ -189,7 +189,7 @@ __check: { //!< 拷贝失败 spinlock_set(&ipc->lock, status); - return msg_tag_init4(0, 0, 0, ret); + return msg_tag_init4(MSG_TAG_KNL_ERR, 0, 0, ret); } ipc->svr_th->msg.tag = tag; thread_ready(ipc->svr_th, TRUE); //!< 直接唤醒接受者 @@ -198,7 +198,7 @@ __check: if (add_wait_unlock(ipc, &ipc->recv_send, th, timeout.recv_timeout, &ipc->lock, status) < 0) { ipc->last_cli_th = NULL; - return msg_tag_init4(0, 0, 0, -ERTIMEDOUT); + return msg_tag_init4(MSG_TAG_KNL_ERR, 0, 0, -ERTIMEDOUT); } spinlock_set(&ipc->lock, status); diff --git a/mkrtos_user/lib/mlibc/include/stddef.h b/mkrtos_user/lib/mlibc/include/stddef.h index f25b86396..2202f73c7 100644 --- a/mkrtos_user/lib/mlibc/include/stddef.h +++ b/mkrtos_user/lib/mlibc/include/stddef.h @@ -6,8 +6,10 @@ #elif defined(__cplusplus) #define NULL 0L #else +#ifndef NULL #define NULL ((void*)0) #endif +#endif #define __NEED_ptrdiff_t #define __NEED_size_t diff --git a/mkrtos_user/lib/sys/inc/u_err.h b/mkrtos_user/lib/sys/inc/u_err.h new file mode 100644 index 000000000..777603af8 --- /dev/null +++ b/mkrtos_user/lib/sys/inc/u_err.h @@ -0,0 +1,3 @@ +#pragma once + +#define ETOLONG 1024 diff --git a/mkrtos_user/lib/sys/inc/u_prot.h b/mkrtos_user/lib/sys/inc/u_prot.h index 0d4884700..b3739372f 100644 --- a/mkrtos_user/lib/sys/inc/u_prot.h +++ b/mkrtos_user/lib/sys/inc/u_prot.h @@ -14,12 +14,15 @@ #define THREAD_MAIN THREAD_PROT #define TASK_THIS TASK_PROT + +#define MSG_TAG_KNL_ERR 0x8 + typedef union msg_tag { umword_t raw; struct { - umword_t flags : 4; + umword_t flags : 4; // 3bit:代表错误由内核报告 umword_t msg_buf_len : 5; umword_t map_buf_len : 2; umword_t prot : WORD_BITS - 12; @@ -29,6 +32,8 @@ typedef union msg_tag #define msg_tag_init(r) \ ((msg_tag_t){.raw = (r)}) +#define msg_tag_is_knl_err(tag) (!!((tag).flags & MSG_TAG_KNL_ERR)) //!< 内核错误 + #define msg_tag_init4(fg, msg_words, buf_words, p) ((msg_tag_t){ \ .flags = (fg), \ .msg_buf_len = (msg_words), \ diff --git a/mkrtos_user/lib/sys/inc/u_thread.h b/mkrtos_user/lib/sys/inc/u_thread.h index 53d3c25ab..57bf066d9 100644 --- a/mkrtos_user/lib/sys/inc/u_thread.h +++ b/mkrtos_user/lib/sys/inc/u_thread.h @@ -1,7 +1,7 @@ #pragma once #include "u_types.h" - +#include "u_prot.h" msg_tag_t thread_msg_buf_set(obj_handler_t obj, void *msg); msg_tag_t thread_msg_buf_get(obj_handler_t obj, umword_t *msg, umword_t *len); msg_tag_t thread_exec_regs(obj_handler_t obj, umword_t pc, umword_t sp, umword_t ram, umword_t cp_stack); diff --git a/mkrtos_user/lib/sys_util/inc/u_rpc.h b/mkrtos_user/lib/sys_util/inc/u_rpc.h new file mode 100644 index 000000000..b6665fff0 --- /dev/null +++ b/mkrtos_user/lib/sys_util/inc/u_rpc.h @@ -0,0 +1,316 @@ +#pragma once + +#include "u_types.h" +#include "u_thread.h" +#include "u_err.h" +#include "u_prot.h" +#include "u_ipc.h" +#include "u_task.h" +#include +#include + +#define RPC_TYPE_DEF(type) \ + typedef struct rpc_##type \ + { \ + type data; \ + } rpc_##type##_t + +static inline size_t rpc_align(size_t size, size_t align) +{ + return ALIGN(size, align); +} +static inline void rpc_memcpy(void *dst, void *src, size_t size) +{ + char *_dst = dst; + char *_src = src; + + while (size--) + { + *_dst = *_src; + } +} +#define RPC_CLI_MSG_TO_BUF(data_type, len_type) \ + static inline int rpc_cli_msg_to_buf_##data_type(data_type *d, uint8_t *buf, len_type len) \ + { \ + if (sizeof(d->data) + rpc_align(len, __alignof(d->data)) >= IPC_MSG_SIZE) \ + { \ + return -ETOLONG; \ + } \ + len = rpc_align(len, __alignof(d->data)); \ + *((typeof(d->data) *)(buf + len)) = d->data; \ + return sizeof(d->data) + rpc_align(len, __alignof(d->data)); \ + } +#define RPC_CLI_MSG_TO_BUF_WITHOUT_IMPL(data_type, len_type) \ + static inline int rpc_cli_msg_to_buf_##data_type(data_type *d, uint8_t *buf, len_type len) + +#define RPC_CLI_BUF_TO_MSG(data_type, len_type) \ + static inline int rpc_cli_buf_to_msg_##data_type(data_type *d, uint8_t *buf, len_type len, len_type max) \ + { \ + if (sizeof(d->data) + rpc_align(len, __alignof(d->data)) >= max) \ + { \ + return -ETOLONG; \ + } \ + len = rpc_align(len, __alignof(d->data)); \ + d->data = *((typeof(d->data) *)(buf + len)); \ + return sizeof(d->data) + rpc_align(len, __alignof(d->data)); \ + } +#define RPC_CLI_BUF_TOMSG_WITHOUT_IMPL(data_type, len_type) \ + static inline int rpc_cli_buf_to_msg_##data_type(data_type *d, uint8_t *buf, len_type len, len_type max) + +#define RPC_TYPE_DEF_ALL(type) \ + RPC_TYPE_DEF(type); \ + RPC_CLI_MSG_TO_BUF(rpc_##type##_t, int) \ + RPC_CLI_BUF_TO_MSG(rpc_##type##_t, int) + +RPC_TYPE_DEF_ALL(int) //!< 定义所有的 + +//!< 数组定义 +#define RPC_ARRAY_TYPE_DEF(len_type, data_type, length) \ + typedef struct rpc_array_##len_type##_##data_type##_##length \ + { \ + len_type len; \ + data_type data[length]; \ + } rpc_array_##len_type##_##data_type##_##length##_t + +RPC_ARRAY_TYPE_DEF(uint32_t, uint8_t, 32); +RPC_CLI_MSG_TO_BUF_WITHOUT_IMPL(rpc_array_uint32_t_uint8_t_32_t, int) +{ + if (rpc_align(d->len, __alignof(d->len) + sizeof(d->len)) >= IPC_MSG_SIZE) + { + return -ETOLONG; + } + len = rpc_align(len, __alignof(d->len)); + *((typeof(d->len) *)(&buf[len])) = d->len; + if (rpc_align(d->len, __alignof(d->data[0]) + d->len * sizeof(d->data[0])) >= IPC_MSG_SIZE) + { + return -ETOLONG; + } + len += sizeof(d->len); + len = rpc_align(len, __alignof(d->data[0])); + for (int i = 0; i < d->len * sizeof(d->data[0]); i++) + { + buf[i + len] = ((uint8_t *)(d->data))[i]; + } + len += d->len * sizeof(d->data[0]); + return len; +} +RPC_CLI_BUF_TOMSG_WITHOUT_IMPL(rpc_array_uint32_t_uint8_t_32_t, int) +{ + if (rpc_align(d->len, __alignof(d->len) + sizeof(d->len)) >= max) + { + return -ETOLONG; + } + len = rpc_align(len, __alignof(d->len)); + d->len = *((typeof(d->len) *)(&buf[len])); + if (rpc_align(d->len, __alignof(d->data[0]) + d->len * sizeof(d->data[0])) >= max) + { + return -ETOLONG; + } + len += sizeof(d->len); + len = rpc_align(len, __alignof(d->data[0])); + for (int i = 0; i < d->len * sizeof(d->data[0]); i++) + { + ((uint8_t *)(d->data))[i] = buf[i + len]; + } + len += d->len * sizeof(d->data[0]); + return len; +} +//!< end + +//!< ref数组定义 +#define RPC_REF_ARRAY_TYPE_DEF(len_type, data_type, length) \ + typedef struct rpc_ref_array_##len_type##_##data_type##_##length \ + { \ + len_type len; \ + data_type *data; \ + } rpc_ref_array_##len_type##_##data_type##_##length##_t + +RPC_REF_ARRAY_TYPE_DEF(uint32_t, uint8_t, 32); +RPC_CLI_MSG_TO_BUF_WITHOUT_IMPL(rpc_ref_array_uint32_t_uint8_t_32_t, int) +{ + if (rpc_align(d->len, __alignof(d->len) + sizeof(d->len)) >= IPC_MSG_SIZE) + { + return -ETOLONG; + } + len = rpc_align(len, __alignof(d->len)); + *((typeof(d->len) *)(&buf[len])) = d->len; + if (rpc_align(d->len, __alignof(d->data[0]) + d->len * sizeof(d->data[0])) >= IPC_MSG_SIZE) + { + return -ETOLONG; + } + len += sizeof(d->len); + len = rpc_align(len, __alignof(d->data[0])); + for (int i = 0; i < d->len * sizeof(d->data[0]); i++) + { + buf[i + len] = ((uint8_t *)(d->data))[i]; + } + len += d->len * sizeof(d->data[0]); + return len; +} +RPC_CLI_BUF_TOMSG_WITHOUT_IMPL(rpc_ref_array_uint32_t_uint8_t_32_t, int) +{ + if (rpc_align(d->len, __alignof(d->len) + sizeof(d->len)) >= max) + { + return -ETOLONG; + } + len = rpc_align(len, __alignof(d->len)); + d->len = *((typeof(d->len) *)(&buf[len])); + if (rpc_align(d->len, __alignof(d->data[0]) + d->len * sizeof(d->data[0])) >= max) + { + return -ETOLONG; + } + len += sizeof(d->len); + len = rpc_align(len, __alignof(d->data[0])); + for (int i = 0; i < d->len * sizeof(d->data[0]); i++) + { + ((uint8_t *)(d->data))[i] = buf[i + len]; + } + len += d->len * sizeof(d->data[0]); + return len; +} +//!< end + +//!< 映射类型定义 +RPC_TYPE_DEF(obj_handler_t); +RPC_CLI_MSG_TO_BUF_WITHOUT_IMPL(rpc_obj_handler_t_t, int) +{ + if (sizeof(d->data) + rpc_align(len, __alignof(d->data)) >= IPC_MSG_SIZE) + { + return -ETOLONG; + } + len = rpc_align(len, __alignof(d->data)); + *((umword_t *)(buf + len)) = vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, d->data).raw; + return sizeof(d->data) + rpc_align(len, __alignof(d->data)); +} +//!< end + +#define RPC_DIR_IN 1 +#define RPC_DIR_OUT 2 +#define RPC_DIR_INOUT 4 + +#define RPC_TYPE_DATA 1 +#define RPC_TYPE_BUF 2 + +#define RPC_CLI_MSG_TO_BUF_IN(rpc_type, var_type, var, dir, buf, off) \ + do \ + { \ + if (rpc_type == RPC_TYPE_DATA) \ + { \ + if (dir == RPC_DIR_IN || dir == RPC_DIR_INOUT) \ + { \ + int ret = rpc_cli_msg_to_buf_##var_type(var, (uint8_t *)(buf), off); \ + if (ret < 0) \ + { \ + return msg_tag_init4(0, 0, 0, ret); \ + } \ + off = ret; \ + } \ + } \ + } while (0) + +#define RPC_CLI_BUF_TO_MSG_OUT(rpc_type, var_type, var, dir, buf, off, max) \ + do \ + { \ + if (rpc_type == RPC_TYPE_DATA) \ + { \ + if (dir == RPC_DIR_OUT || dir == RPC_DIR_INOUT) \ + { \ + int ret = rpc_cli_buf_to_msg_##var_type(var, (uint8_t *)(buf), off, max); \ + if (ret < 0) \ + { \ + return msg_tag_init4(0, 0, 0, ret); \ + } \ + off = ret; \ + } \ + } \ + } while (0) + +#define PRC_CLI_FILL_BUF(rpc_type, var_type, var, dir, buf, off) \ + do \ + { \ + if (rpc_type == RPC_TYPE_BUF) \ + { \ + if (dir == RPC_DIR_IN || dir == RPC_DIR_INOUT) \ + { \ + int ret = rpc_cli_msg_to_buf_##var_type(var, (uint8_t *)(buf), off); \ + if (ret < 0) \ + { \ + return msg_tag_init4(0, 0, 0, ret); \ + } \ + off = ret; \ + } \ + } \ + } while (0) + +#define RPC_GENERATION_CALL1(struct_type, op, func_name, type0, dir0, rpc_type0, name0) \ + msg_tag_t struct_type##_##func_name##_call(obj_handler_t hd, type0 *var0) \ + { \ + void *buf; \ + ipc_msg_t *msg_ipc; \ + \ + thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL); \ + msg_ipc = (ipc_msg_t *)buf; \ + \ + int off = 0; \ + int ret = -1; \ + int op_val = op; \ + /*拷贝op*/ \ + rpc_memcpy(msg_ipc->msg_buf, &op_val, sizeof(op_val)); \ + off += rpc_align(sizeof(op_val), __alignof(op)); \ + \ + RPC_CLI_MSG_TO_BUF_IN(rpc_type0, type0, var0, dir0, (uint8_t *)msg_ipc->msg_buf, off); \ + PRC_CLI_FILL_BUF(rpc_type0, type0, var0, dir0, (uint8_t *)msg_ipc->msg_buf, off); \ + msg_tag_t tag = ipc_call(hd, msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), 0, 0), \ + ipc_timeout_create2(0, 0)); \ + \ + if (msg_tag_get_val(tag)) \ + { \ + return tag; \ + } /*拷贝返回的数据*/ \ + off = 0; \ + RPC_CLI_BUF_TO_MSG_OUT(rpc_type0, type0, var0, dir0, (uint8_t *)msg_ipc->msg_buf, off, tag.msg_buf_len *WORD_BYTES); \ + return tag; \ + } +// #define RPC_GENERATION_DISPATCH1(struct_type, op, func_name, \ +// type0, dir0, rpc_type0, name0) +// msg_tag_t tt_dispatch(msg_tag_t tag, ipc_msg_t *ipc_msg) +// { +// type0 var0; + + +// } +#define RPC_GENERATION_CALL2(struct_type, op, func_name, \ + type0, dir0, rpc_type0, name0, \ + type1, dir1, rpc_type1, name1) \ + msg_tag_t struct_type##_##func_name##_call(obj_handler_t hd, type0 *var0, type1 *var1) \ + { \ + void *buf; \ + ipc_msg_t *msg_ipc; \ + \ + thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL); \ + msg_ipc = (ipc_msg_t *)buf; \ + \ + int off = 0; \ + int off_buf = 0; \ + int ret = -1; \ + int op_val = op; \ + /*拷贝op*/ \ + rpc_memcpy(msg_ipc->msg_buf, &op_val, sizeof(op_val)); \ + off += rpc_align(sizeof(op_val), __alignof(op)); \ + \ + RPC_CLI_MSG_TO_BUF_IN(rpc_type0, type0, var0, dir0, (uint8_t *)msg_ipc->msg_buf, off); \ + PRC_CLI_FILL_BUF(rpc_type0, type0, var0, dir0, (uint8_t *)msg_ipc->msg_buf, off_buf); \ + RPC_CLI_MSG_TO_BUF_IN(rpc_type1, type1, var1, dir1, (uint8_t *)msg_ipc->msg_buf, off); \ + PRC_CLI_FILL_BUF(rpc_type1, type1, var1, dir1, (uint8_t *)msg_ipc->msg_buf, off_buf); \ + msg_tag_t tag = ipc_call(hd, msg_tag_init4(0, ROUND_UP(off, WORD_BYTES), 0, 0), \ + ipc_timeout_create2(0, 0)); \ + \ + if (msg_tag_get_val(tag)) \ + { \ + return tag; \ + } /*拷贝返回的数据*/ \ + off = 0; \ + RPC_CLI_BUF_TO_MSG_OUT(rpc_type0, type0, var0, dir0, (uint8_t *)msg_ipc->msg_buf, off, tag.msg_buf_len *WORD_BYTES); \ + RPC_CLI_BUF_TO_MSG_OUT(rpc_type1, type1, var1, dir1, (uint8_t *)msg_ipc->msg_buf, off, tag.msg_buf_len *WORD_BYTES); \ + return tag; \ + } diff --git a/mkrtos_user/lib/sys_util/src/u_rpc.c b/mkrtos_user/lib/sys_util/src/u_rpc.c new file mode 100644 index 000000000..beab1421f --- /dev/null +++ b/mkrtos_user/lib/sys_util/src/u_rpc.c @@ -0,0 +1,4 @@ + +#include "u_rpc.h" + + diff --git a/mkrtos_user/server/fs/fatfs/main.c b/mkrtos_user/server/fs/fatfs/main.c index ab39aba2b..e96ba8fb8 100644 --- a/mkrtos_user/server/fs/fatfs/main.c +++ b/mkrtos_user/server/fs/fatfs/main.c @@ -8,6 +8,7 @@ static MKFS_PARM defopt = {FM_ANY, 0, 0, 0}; int main(int args, char *argv[]) { FRESULT res = f_mount(&fs, "0:", 1); + if (res != FR_OK) { res = f_mkfs("0:", &defopt, buff, 512); // 第三个参数可以设置成NULL,默认使用heap memory diff --git a/mkrtos_user/server/shell/src/main.c b/mkrtos_user/server/shell/src/main.c index f58b4fd41..6a0910627 100644 --- a/mkrtos_user/server/shell/src/main.c +++ b/mkrtos_user/server/shell/src/main.c @@ -10,6 +10,7 @@ #include "u_hd_man.h" #include "u_ns.h" #include "test.h" +#include "u_rpc.h" #include #include #include @@ -53,6 +54,7 @@ int main(int argc, char *args[]) malloc_test(); irq_test(); #endif + rpc_test(); ns_test(); task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); ulog_write_str(u_get_global_env()->log_hd, "Error.\n"); diff --git a/mkrtos_user/server/shell/src/rpc_test.c b/mkrtos_user/server/shell/src/rpc_test.c new file mode 100644 index 000000000..8fe4e71ae --- /dev/null +++ b/mkrtos_user/server/shell/src/rpc_test.c @@ -0,0 +1,23 @@ + +#include "u_rpc.h" +typedef struct test_svr +{ + +} test_svr_t; + +RPC_GENERATION_CALL1(test_svr_t, 0, register, rpc_int_t, RPC_DIR_IN, RPC_TYPE_BUF, var0) +RPC_GENERATION_CALL2(test_svr_t, 1, query, + rpc_ref_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, var0, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, var1) + +#include +void rpc_test(void) +{ + rpc_int_t var0 = {.data = 1}; + msg_tag_t tag = test_svr_t_register_call(15, &var0); + + rpc_ref_array_uint32_t_uint8_t_32_t str_tst = { + .data = "test", + .len = strlen("test") + 1}; + + test_svr_t_query_call(15, &str_tst, &var0); +} \ No newline at end of file diff --git a/mkrtos_user/server/shell/src/test.h b/mkrtos_user/server/shell/src/test.h index 606e25d2c..ef5d0ade0 100644 --- a/mkrtos_user/server/shell/src/test.h +++ b/mkrtos_user/server/shell/src/test.h @@ -1,3 +1,4 @@ #pragma once void irq_test(void); +void rpc_test(void); \ No newline at end of file