diff --git a/.vscode/settings.json b/.vscode/settings.json index 595278d10..58c6b3ba4 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -267,7 +267,9 @@ "system_error": "c", "__dirent.h": "c", "shell_fs.h": "c", - "shell_passthrough.h": "c" + "shell_passthrough.h": "c", + "u_slist.h": "c", + "atomic": "c" }, "cortex-debug.showRTOS": false, "cortex-debug.variableUseNaturalFormat": false, diff --git a/mkrtos_user/lib/letter-shell/demo/mkrtos/CMakeLists.txt b/mkrtos_user/lib/letter-shell/demo/mkrtos/CMakeLists.txt index 613b486a3..9df368fb3 100644 --- a/mkrtos_user/lib/letter-shell/demo/mkrtos/CMakeLists.txt +++ b/mkrtos_user/lib/letter-shell/demo/mkrtos/CMakeLists.txt @@ -10,12 +10,13 @@ set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS}) add_library(LetterShell # main.c shell_port.c + shell_fs_ext.c # shell_cpp.cpp ../../src/shell.c ../../src/shell_companion.c ../../src/shell_ext.c ../../src/shell_cmd_list.c - ../../extensions/fs_support/shell_fs.c + # ../../extensions/fs_support/shell_fs.c ../../extensions/log/log.c # ../../extensions/telnet/telnetd.c ../../extensions/shell_enhance/shell_passthrough.c diff --git a/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_fs_ext.c b/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_fs_ext.c new file mode 100644 index 000000000..2e6cba927 --- /dev/null +++ b/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_fs_ext.c @@ -0,0 +1,31 @@ +#include "shell.h" +#include +#include +#include +#include +#include +#include +#include +int ls(int argc, char *agrv[]) +{ + DIR *dir; + struct dirent *ptr; + int i; + if (argc < 2) + { + return -1; + } + + dir = opendir(agrv[1]); + if (!dir) + { + return 0; + } + while ((ptr = readdir(dir)) != NULL) + { + printf("%s \n", ptr->d_name); + } + closedir(dir); + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), ls, ls, ls command); diff --git a/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_port.c b/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_port.c index 91e8f68a0..e8f893a04 100644 --- a/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_port.c +++ b/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_port.c @@ -28,7 +28,7 @@ static Shell shell; static ShellFs shellFs; static char shellBuffer[256]; -static char shellPathBuffer[128] = "/mnt/"; +// static char shellPathBuffer[128] = "/"; /** * @brief 用户shell写 @@ -96,15 +96,15 @@ size_t userShellListDir(char *path, char *buffer, size_t maxLen) */ void userShellInit(void) { - shellFs.getcwd = getcwd; - shellFs.chdir = chdir; - shellFs.listdir = userShellListDir; - shellFsInit(&shellFs, shellPathBuffer, sizeof(shellPathBuffer)); + // shellFs.getcwd = getcwd; + // shellFs.chdir = chdir; + // shellFs.listdir = userShellListDir; + // shellFsInit(&shellFs, shellPathBuffer, sizeof(shellPathBuffer)); shell.write = userShellWrite; shell.read = userShellRead; - shellSetPath(&shell, shellPathBuffer); + // shellSetPath(&shell, shellPathBuffer); shellInit(&shell, shellBuffer, sizeof(shellBuffer)); - shellCompanionAdd(&shell, SHELL_COMPANION_ID_FS, &shellFs); + // shellCompanionAdd(&shell, SHELL_COMPANION_ID_FS, &shellFs); while (1) { diff --git a/mkrtos_user/lib/letter-shell/src/shell_cfg.h b/mkrtos_user/lib/letter-shell/src/shell_cfg.h index d29ab7ae2..0018dcd3b 100644 --- a/mkrtos_user/lib/letter-shell/src/shell_cfg.h +++ b/mkrtos_user/lib/letter-shell/src/shell_cfg.h @@ -39,7 +39,7 @@ * @brief 是否使用shell伴生对象 * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 */ -#define SHELL_USING_COMPANION 1 +#define SHELL_USING_COMPANION 0 #endif /** SHELL_USING_COMPANION */ #ifndef SHELL_SUPPORT_END_LINE diff --git a/mkrtos_user/lib/sys/inc/u_util.h b/mkrtos_user/lib/sys/inc/u_util.h index 7916741db..46301e472 100644 --- a/mkrtos_user/lib/sys/inc/u_util.h +++ b/mkrtos_user/lib/sys/inc/u_util.h @@ -11,5 +11,8 @@ #define ROUND_UP(a, b) ROUND(a, b) //!< a除b向上取整数 #define ROUND_DOWN(a, b) ((a) / (b)) //!< a/b向下取整 +#define container_of(ptr, type, member) \ + ((type *)(((umword_t)(ptr)) - ((umword_t)(&(((type *)0)->member))))) + #define ATTR_ALIGN(a) __attribute__((aligned(a))) #define AUTO_CALL(prio) __attribute__((constructor(prio))) \ No newline at end of file diff --git a/mkrtos_user/lib/sys_svr/inc/ns_cli.h b/mkrtos_user/lib/sys_svr/inc/ns_cli.h index c27afb795..cbcc1ac6f 100644 --- a/mkrtos_user/lib/sys_svr/inc/ns_cli.h +++ b/mkrtos_user/lib/sys_svr/inc/ns_cli.h @@ -1,6 +1,7 @@ #pragma once #include "u_types.h" +#include "ns_types.h" -int ns_register(const char *path, obj_handler_t svr_hd); +int ns_register(const char *path, obj_handler_t svr_hd, enum node_type type); int ns_query(const char *path, obj_handler_t *svr_hd); diff --git a/mkrtos_user/lib/sys_svr/inc/ns_svr.h b/mkrtos_user/lib/sys_svr/inc/ns_svr.h index 5fcb75020..af1f7cf19 100644 --- a/mkrtos_user/lib/sys_svr/inc/ns_svr.h +++ b/mkrtos_user/lib/sys_svr/inc/ns_svr.h @@ -6,5 +6,5 @@ #include "ns_types.h" void ns_init(ns_t *ns); -int namespace_register(const char *path, obj_handler_t hd); +int namespace_register(const char *path, obj_handler_t hd, int type); int namespace_query(const char *path, obj_handler_t *hd); diff --git a/mkrtos_user/lib/sys_svr/inc/ns_types.h b/mkrtos_user/lib/sys_svr/inc/ns_types.h index b7525c327..efc5eaa51 100644 --- a/mkrtos_user/lib/sys_svr/inc/ns_types.h +++ b/mkrtos_user/lib/sys_svr/inc/ns_types.h @@ -1,22 +1,33 @@ #pragma once #include "u_types.h" #include "u_rpc_svr.h" +#include "u_slist.h" #define NAMESPACE_PATH_LEN 32 #define NAMESAPCE_NR 8 -/** - * @brief 非常简单的方式实现路径管理 - * - */ -typedef struct namespace_entry +enum node_type { - char path[NAMESPACE_PATH_LEN]; //!< 服务的路径名 - obj_handler_t hd; //!< 服务的fd -} namespace_entry_t; + MOUNT_NODE, + FILE_NODE, + DIR_NODE, +}; +typedef struct ns_node +{ + struct ns_node *parent; + char node_name[NAMESPACE_PATH_LEN]; + enum node_type type; + union + { + obj_handler_t node_hd; + slist_head_t sub_dir; + }; + slist_head_t node; + int ref; +} ns_node_t; typedef struct ns { rpc_svr_obj_t svr; - namespace_entry_t ne_list[NAMESAPCE_NR]; //!< 服务列表 + ns_node_t root_node; obj_handler_t hd; //!< 存储临时用于映射的hd } ns_t; \ No newline at end of file diff --git a/mkrtos_user/lib/sys_svr/src/fs_cli.c b/mkrtos_user/lib/sys_svr/src/fs_cli.c index 10e2c89e1..6a170120d 100644 --- a/mkrtos_user/lib/sys_svr/src/fs_cli.c +++ b/mkrtos_user/lib/sys_svr/src/fs_cli.c @@ -10,6 +10,7 @@ #include #include +/*open*/ RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_OPEN, open, rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path, rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags, @@ -43,6 +44,7 @@ sd_t fs_open(const char *path, int flags, int mode) return mk_sd_init2(hd, msg_tag_get_val(tag)).raw; } +/*read*/ RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_READ, read, rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd, rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_OUT, RPC_TYPE_DATA, buf, @@ -85,6 +87,7 @@ int fs_read(sd_t _fd, void *buf, size_t len) return rlen; } +/*write*/ RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_WRITE, write, rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd, rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, buf, @@ -126,6 +129,7 @@ int fs_write(sd_t _fd, void *buf, size_t len) return wlen; } +/*close*/ RPC_GENERATION_CALL1(fs_t, FS_PROT, FS_CLOSE, close, rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd) int fs_close(sd_t _fd) @@ -145,6 +149,7 @@ int fs_close(sd_t _fd) return msg_tag_get_val(tag); } +/*lseek*/ RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_LSEEK, lseek, rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd, rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, offs, @@ -173,6 +178,7 @@ int fs_lseek(sd_t _fd, int offs, int whence) return msg_tag_get_val(tag); } +/*readdir*/ RPC_GENERATION_CALL2(fs_t, FS_PROT, FS_READDIR, readdir, rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd, rpc_dirent_t_t, rpc_dirent_t_t, RPC_DIR_OUT, RPC_TYPE_DATA, dir) diff --git a/mkrtos_user/lib/sys_svr/src/ns_cli.c b/mkrtos_user/lib/sys_svr/src/ns_cli.c index 86d86850f..62313496f 100644 --- a/mkrtos_user/lib/sys_svr/src/ns_cli.c +++ b/mkrtos_user/lib/sys_svr/src/ns_cli.c @@ -68,15 +68,16 @@ static bool_t reg_hd(const char *path, obj_handler_t hd, int split_inx) return FALSE; } -RPC_GENERATION_CALL2(ns_t, NS_PROT, NS_REGISTER_OP, register, +RPC_GENERATION_CALL3(ns_t, NS_PROT, NS_REGISTER_OP, register, rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path, - rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd) + rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd, + rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, type) RPC_GENERATION_CALL2(ns_t, NS_PROT, NS_QUERY_OP, query, rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path, rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_INOUT, RPC_TYPE_BUF, cli_hd) -int ns_register(const char *path, obj_handler_t svr_hd) +int ns_register(const char *path, obj_handler_t svr_hd, enum node_type type) { assert(path); @@ -87,8 +88,11 @@ int ns_register(const char *path, obj_handler_t svr_hd) rpc_obj_handler_t_t rpc_svr_hd = { .data = svr_hd, }; + rpc_int_t rpc_type = { + .data = type, + }; - msg_tag_t tag = ns_t_register_call(u_get_global_env()->ns_hd, &rpc_path, &rpc_svr_hd); + msg_tag_t tag = ns_t_register_call(u_get_global_env()->ns_hd, &rpc_path, &rpc_svr_hd, &rpc_type); return msg_tag_get_val(tag); } diff --git a/mkrtos_user/lib/sys_svr/src/ns_svr.c b/mkrtos_user/lib/sys_svr/src/ns_svr.c index 0be034149..4bbf936f9 100644 --- a/mkrtos_user/lib/sys_svr/src/ns_svr.c +++ b/mkrtos_user/lib/sys_svr/src/ns_svr.c @@ -7,13 +7,14 @@ #include "u_hd_man.h" #include -RPC_GENERATION_OP2(ns_t, NS_PROT, NS_REGISTER_OP, register, +RPC_GENERATION_OP3(ns_t, NS_PROT, NS_REGISTER_OP, register, rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path, - rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd) + rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd, + rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, type) { path->data[path->len - 1] = 0; - int ret = namespace_register((char *)(path->data), obj->hd); + int ret = namespace_register((char *)(path->data), obj->hd, type->data); if (ret >= 0) { printf("register [%s] success.\n", (char *)(path->data)); @@ -24,9 +25,10 @@ RPC_GENERATION_OP2(ns_t, NS_PROT, NS_REGISTER_OP, register, } return ret; } -RPC_GENERATION_DISPATCH2(ns_t, NS_PROT, NS_REGISTER_OP, register, +RPC_GENERATION_DISPATCH3(ns_t, NS_PROT, NS_REGISTER_OP, register, rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path, - rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd) + rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd, + rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, type) RPC_GENERATION_OP2(ns_t, NS_PROT, NS_QUERY_OP, query, rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path, @@ -54,9 +56,5 @@ RPC_DISPATCH2(ns_t, NS_PROT, typeof(NS_REGISTER_OP), NS_REGISTER_OP, register, N void ns_init(ns_t *ns) { rpc_svr_obj_init(&ns->svr, rpc_ns_t_dispatch, NS_PROT); - for (int i = 0; i < NAMESAPCE_NR; i++) - { - ns->ne_list[i].hd = HANDLER_INVALID; - } ns->hd = HANDLER_INVALID; } diff --git a/mkrtos_user/lib/util/inc/u_slist.h b/mkrtos_user/lib/util/inc/u_slist.h index 287c5c5d0..dcaf6525f 100755 --- a/mkrtos_user/lib/util/inc/u_slist.h +++ b/mkrtos_user/lib/util/inc/u_slist.h @@ -1,4 +1,6 @@ #pragma once + +#include /** * @brief 循环双向链表 */ diff --git a/mkrtos_user/server/drv/mr_drv/src/main.c b/mkrtos_user/server/drv/mr_drv/src/main.c index c0854b582..16c921c10 100644 --- a/mkrtos_user/server/drv/mr_drv/src/main.c +++ b/mkrtos_user/server/drv/mr_drv/src/main.c @@ -9,7 +9,7 @@ #include int main(int argc, char *args[]) { - ns_register("/dev", drv_svr_init()); + ns_register("/dev", drv_svr_init(), MOUNT_NODE); mr_auto_init(); printf("mr drv start success...\n"); drv_svr_loop(); diff --git a/mkrtos_user/server/fs/fatfs/main.c b/mkrtos_user/server/fs/fatfs/main.c index a387bcf9d..7907c3d37 100644 --- a/mkrtos_user/server/fs/fatfs/main.c +++ b/mkrtos_user/server/fs/fatfs/main.c @@ -21,7 +21,7 @@ int main(int args, char *argv[]) ret = rpc_meta_init(THREAD_MAIN, &hd); assert(ret >= 0); fs_svr_init(); - ns_register("/mnt", hd); + ns_register("/mnt", hd, MOUNT_NODE); FRESULT res = f_mount(&fs, "0:", 1); diff --git a/mkrtos_user/server/init/CMakeLists.txt b/mkrtos_user/server/init/CMakeLists.txt index 5713fcd29..2a59729a3 100644 --- a/mkrtos_user/server/init/CMakeLists.txt +++ b/mkrtos_user/server/init/CMakeLists.txt @@ -26,6 +26,8 @@ target_include_directories( ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cpio + ${CMAKE_SOURCE_DIR}/mkrtos_user/server/init/src + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/arm/ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/generic ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/src/internal diff --git a/mkrtos_user/server/init/src/file_desc.c b/mkrtos_user/server/init/src/file_desc.c new file mode 100644 index 000000000..f67d1a3e5 --- /dev/null +++ b/mkrtos_user/server/init/src/file_desc.c @@ -0,0 +1,32 @@ +#include "file_desc.h" + +file_desc_t *fd_alloc(ns_node_t *node) +{ + for (int i = 0; i < FILE_DESC_NR; i++) + { + if (fd_list[i].node == NULL) + { + fd_list[i].node = node; + fd_list[i].node_iter = NULL; + return &fd_list[i]; + } + } + return NULL; +} +file_desc_t *fd_get(int fd) +{ + if (fd < 0 || fd >= FILE_DESC_NR) + { + return NULL; + } + return &fd_list[fd]; +} +void fd_free(int fd) +{ + if (fd < 0 || fd >= FILE_DESC_NR) + { + return; + } + fd_list[fd].node = NULL; + fd_list[fd].node_iter = NULL; +} diff --git a/mkrtos_user/server/init/src/file_desc.h b/mkrtos_user/server/init/src/file_desc.h new file mode 100644 index 000000000..c5e2ba9e4 --- /dev/null +++ b/mkrtos_user/server/init/src/file_desc.h @@ -0,0 +1,15 @@ +#pragma once +#include + +#define FILE_DESC_NR 32 + +typedef struct file_desc +{ + ns_node_t *node; + ns_node_t *node_iter; +} file_desc_t; + +static file_desc_t fd_list[FILE_DESC_NR]; +file_desc_t *fd_alloc(ns_node_t *node); +file_desc_t *fd_get(int fd); +void fd_free(int fd); diff --git a/mkrtos_user/server/init/src/init.cfg b/mkrtos_user/server/init/src/init.cfg index fe41441e7..bdb173d51 100644 --- a/mkrtos_user/server/init/src/init.cfg +++ b/mkrtos_user/server/init/src/init.cfg @@ -3,4 +3,5 @@ # mr_drv # hello # rtthread_drv +fatfs sh diff --git a/mkrtos_user/server/init/src/main.c b/mkrtos_user/server/init/src/main.c index 8e89836c8..fb3baef85 100644 --- a/mkrtos_user/server/init/src/main.c +++ b/mkrtos_user/server/init/src/main.c @@ -1,12 +1,12 @@ /** * @file main.c * @author ATShining (1358745329@qq.com) - * @brief + * @brief * @version 0.1 * @date 2023-11-28 - * + * * @copyright Copyright (c) 2023 - * + * */ #include "u_log.h" #include "u_prot.h" @@ -52,6 +52,7 @@ static void test(void) ipc_obj_test(); pthread_cond_lock_test(); pthread_lock_test(); + ns_test(); #endif } int main(int argc, char *args[]) @@ -60,13 +61,14 @@ int main(int argc, char *args[]) uenv_t *env; ulog_write_str(LOG_PROT, "init..\n"); - test(); env = u_get_global_env(); rpc_meta_init(THREAD_MAIN, &env->ns_hd); - namespace_init(); + namespace_init(env->ns_hd); pm_init(); console_init(); + test(); + ret = parse_cfg(DEFAULT_INIT_CFG, env); printf("run app num is %d.\n", ret); namespace_pre_alloc_map_fd(); diff --git a/mkrtos_user/server/init/src/namespace.c b/mkrtos_user/server/init/src/namespace.c index e722cf4e1..374703de6 100644 --- a/mkrtos_user/server/init/src/namespace.c +++ b/mkrtos_user/server/init/src/namespace.c @@ -17,36 +17,380 @@ #include "u_ipc.h" #include "ns_types.h" #include "ns_svr.h" +#include "fs_svr.h" #include "namespace.h" #include "u_rpc_svr.h" +#include "file_desc.h" +#include +#include static ns_t ns; -void namespace_init(void) +static fs_t ns_fs; +int ns_reg(const char *path, obj_handler_t hd, enum node_type type); + +static ns_node_t *node_init(ns_node_t *new_node, ns_node_t *parent, const char *name, obj_handler_t hd, enum node_type type) { - ns_init(&ns); - meta_reg_svr_obj(&ns.svr, NS_PROT); - printf("ns svr init...\n"); + strncpy(new_node->node_name, name, sizeof(new_node->node_name)); + new_node->node_name[sizeof(new_node->node_name) - 1] = 0; + new_node->ref = 1; + new_node->type = type; + new_node->parent = parent; + if (parent) + { + parent->ref++; //! 父目录的引用计数+1 + } + slist_init(&new_node->node); + if (type == DIR_NODE) + { + slist_init(&new_node->sub_dir); + } + else + { + new_node->node_hd = hd; + } + return new_node; +} +/** + * @brief Create a node object + * + * @param dir + * @param name + * @param hd + * @param typef + * @return ns_node_t* + */ +static ns_node_t *create_node(ns_node_t *parent, const char *name, obj_handler_t hd, enum node_type type) +{ + ns_node_t *new_node = malloc(sizeof(*new_node)); + + if (new_node == NULL) + { + return NULL; + } + node_init(new_node, parent, name, hd, type); + return new_node; +} +/** + * @brief 路径分割 + * + * @param name + * @return int + */ +static int path_split(const char *name) +{ + int i = -1; + + for (i = 0; name[i]; i++) + { + if (name[i] == '/') + { + break; + } + } + return i; +} +/** + * @brief 找到某个节点 + * + * @param dir + * @param name + * @param ret_inx + * @return ns_node_t* + */ +static ns_node_t *node_lookup(ns_node_t *dir, const char *name, size_t *ret_inx) +{ + int inx = -1; + int find_inx = 0; + int r_inx = 0; + ns_node_t *node = NULL; + bool_t find = FALSE; + + if (dir->type != DIR_NODE) + { + return NULL; + } + if (name[0] == 0) + { + return dir; + } + if (name[0] == '/') + { + node = dir; + find_inx++; + r_inx++; + find = TRUE; + } + + while (1) + { + ns_node_t *pos; + + inx = path_split(name + find_inx); + if (inx <= 0) + { + break; + } + slist_foreach(pos, &(node->sub_dir), node) + { + if (strncmp(name + find_inx, pos->node_name, inx) != 0) + { + continue; + } + switch (pos->type) + { + case DIR_NODE: + { + // dir + node = pos; + r_inx += inx; + find = TRUE; + } + break; + case FILE_NODE: + case MOUNT_NODE: + { + find = TRUE; + r_inx += inx; + node = pos; + goto end; + } + break; + } + } + find_inx += inx; + } +end: + if (!find) + { + return NULL; + } + if (ret_inx) + { + *ret_inx = r_inx; + } + return node; +} +/** + * @brief 释放一个节点 + * + * @param node + */ +int ns_node_free(ns_node_t *node) +{ + if (!node) + { + return 0; + } + if (node->ref == 1) + { + //!< 父级目录的引用计数-1 + ns_node_free(node->parent); + } + node->ref--; + if (node->ref <= 0) + { + switch (node->type) + { + case DIR_NODE: + assert(slist_is_empty(&node->sub_dir)); + break; + case FILE_NODE: + case MOUNT_NODE: + handler_free_umap(node->node_hd); + break; + default: + break; + } + if (slist_in_list(&node->node)) + { + slist_del(&node->node); + } + free(node); + } + return node->ref; +} +int fs_svr_open(const char *path, int flags, int mode) +{ + ns_node_t *node; + size_t ret_inx; + int len; + +again: + node = node_lookup(&ns.root_node, path, &ret_inx); + if (!node) + { + return -ENOENT; + } + len = strlen(path); + if (len != ret_inx) + { + if (flags & O_CREAT) + { + int ret = ns_reg(path, 0, DIR_NODE); + + if (ret < 0) + { + return ret; + } + goto again; + } + return -ENOENT; + } + file_desc_t *fd_p = fd_alloc(node); + + if (!fd_p) + { + return -ENOMEM; + } + node->ref++; + return 0; +} +int fs_svr_readdir(int fd, dirent_t *dir) +{ + bool_t is_dec_ref = 0; + file_desc_t *fdp = fd_get(fd); + + if (!fdp) + { + return -ENOENT; + } + if (fdp->node_iter == (void *)((umword_t)(-1))) + { + return -ENOENT; + } + if (fdp->node_iter == NULL) + { + // 首次迭代 + if (slist_is_empty(&fdp->node->sub_dir)) + { + return -ENOENT; + } + // 获得第一个节点 + fdp->node_iter = container_of(slist_first(&fdp->node->sub_dir), ns_node_t, node); + fdp->node_iter->ref++; + } + + // 拷贝数据 + dir->d_type = fdp->node_iter->type == FILE_NODE ? DT_CHR : DT_DIR; + dir->d_reclen = sizeof(*dir); + strncpy(dir->d_name, fdp->node_iter->node_name, sizeof(dir->d_name)); + dir->d_name[sizeof(dir->d_name) - 1] = 0; + dir->d_ino = 0; + slist_head_t *next = fdp->node_iter->node.next; + + ns_node_free(fdp->node_iter); + if (next == &fdp->node->sub_dir) + { + // 到达结尾 + fdp->node_iter = (void *)((umword_t)(-1)); + return sizeof(*dir); + } + else + { + ns_node_t *next_n = container_of(next, ns_node_t, node); + + fdp->node_iter = next_n; + next_n->ref++; + } + return sizeof(*dir); +} +void fs_svr_close(int fd) +{ + file_desc_t *fdp = fd_get(fd); + + if (!fdp) + { + return; + } + if (fdp->node_iter && fdp->node_iter != (void *)(-1)) + { + // 最后一个迭代的节点需要删除 + ns_node_free(fdp->node_iter); + } + ns_node_free(fdp->node); + fd_free(fd); +} +int fs_svr_unlink(char *path) +{ + ns_node_t *node; + int ret_inx; + + node = node_lookup(&ns.root_node, path, &ret_inx); + if (node && ret_inx == strlen(path)) + { + if (node->ref == 1) + { + ns_node_free(node); + } + } + else + { + return -ENOENT; + } + + return 0; } -static int namespace_alloc(const char *path, obj_handler_t hd) +static int find_path(const char *name) { - for (int i = 0; i < NAMESAPCE_NR; i++) + int len = strlen(name); + + for (int i = len; i >= 0; i--) { - if (ns.ne_list[i].hd == HANDLER_INVALID) + if (name[i] == '/') { - ns.ne_list[i].hd = hd; - strncpy(ns.ne_list[i].path, path, NAMESPACE_PATH_LEN); - ns.ne_list[i].path[NAMESPACE_PATH_LEN - 1] = 0; - return i; + return i + 1; } } return -1; } - -enum ns_op +/** + * @brief 注册一个节点 + * + * @param path + * @param hd + * @return int + */ +int ns_reg(const char *path, obj_handler_t hd, enum node_type type) { - OP_REGISTER, - OP_QUERY, -}; + size_t ret_inx; + ns_node_t *new_node; + ns_node_t *node; + + node = node_lookup(&ns.root_node, path, &ret_inx); + if (node && ret_inx == strlen(path)) + { + handler_free_umap(hd); + return -EEXIST; + } + int inx = find_path(path); + + if (ret_inx != inx) + { + handler_free_umap(hd); + return -ENOENT; + } + new_node = create_node(node, path + inx, hd, type); + if (!new_node) + { + handler_free_umap(hd); + return -ENOMEM; + } + + slist_add_append(&node->sub_dir, &new_node->node); + + return 0; +} +static obj_handler_t ns_hd; +void namespace_init(obj_handler_t ipc_hd) +{ + ns_init(&ns); + fs_init(&ns_fs); + meta_reg_svr_obj(&ns.svr, NS_PROT); + meta_reg_svr_obj(&ns_fs.svr, FS_PROT); + node_init(&ns.root_node, NULL, "", 0, DIR_NODE); + ns_hd = ipc_hd; + printf("ns svr init...\n"); +} /** * @brief 注册一个obj @@ -55,15 +399,18 @@ enum ns_op * @param hd 注册的hd * @return int */ -int namespace_register(const char *path, obj_handler_t hd) +int namespace_register(const char *path, obj_handler_t hd, int type) { - if (namespace_alloc(path, hd) < 0) + if (type == DIR_NODE) { - return -1; + handler_free_umap(hd); + namespace_pre_alloc_map_fd(); + return -ECANCELED; } + int ret = ns_reg(path, hd, type); // TODO:增加类型支持 printf("register svr, name is %s, hd is %d\n", path, hd); namespace_pre_alloc_map_fd(); - return 0; + return ret; } /** * @brief 申请一个obj @@ -74,25 +421,28 @@ int namespace_register(const char *path, obj_handler_t hd) */ int namespace_query(const char *path, obj_handler_t *hd) { - for (int i = 0; i < NAMESAPCE_NR; i++) + assert(hd); + size_t ret_inx; + ns_node_t *new_node; + ns_node_t *node; + + if (path[0] == '/' && path[1] == 0) { - if (ns.ne_list[i].hd != HANDLER_INVALID) - { - char *split_str = strstr(path, ns.ne_list[i].path); - if (split_str && (split_str == path)) - { - msg_tag_t tag = task_obj_valid(TASK_THIS, ns.ne_list[i].hd); - if (msg_tag_get_val(tag) != 1) - { - // 对象变为无效,删除该条记录 - ns.ne_list[i].hd = HANDLER_INVALID; - } - *hd = ns.ne_list[i].hd; - return (int)(strlen(ns.ne_list[i].path)); - } - } + *hd = ns_hd; + return 0; } - return -1; + + node = node_lookup(&ns.root_node, path, &ret_inx); + if (node && ret_inx == strlen(path)) + { + return -EEXIST; + } + if (node->type == DIR_NODE) + { + return -ENOENT; + } + *hd = node->node_hd; + return ret_inx; } int namespace_pre_alloc_map_fd(void) { @@ -113,3 +463,36 @@ void namespace_loop(void) { rpc_loop(); } + + +int fs_svr_read(int fd, void *buf, size_t len) +{ + return -ENOSYS; +} +int fs_svr_write(int fd, void *buf, size_t len) +{ + return -ENOSYS; +} +int fs_svr_lseek(int fd, int offs, int whence) +{ + return -ENOSYS; +} +int fs_svr_ftruncate(int fd, off_t off) +{ + return -ENOSYS; +} +void fs_svr_sync(int fd) +{ +} +int fs_svr_mkdir(char *path) +{ + return -ENOSYS; +} +int fs_svr_renmae(char *oldname, char *newname) +{ + return -ENOSYS; +} +int fs_svr_fstat(int fd, stat_t *stat) +{ + return -ENOSYS; +} diff --git a/mkrtos_user/server/init/src/namespace.h b/mkrtos_user/server/init/src/namespace.h index 8a33593f1..a6fb4409c 100644 --- a/mkrtos_user/server/init/src/namespace.h +++ b/mkrtos_user/server/init/src/namespace.h @@ -1,19 +1,23 @@ /** * @file namespace.h * @author ATShining (1358745329@qq.com) - * @brief + * @brief * @version 0.1 * @date 2023-11-28 - * + * * @copyright Copyright (c) 2023 - * + * */ #pragma once #include "u_types.h" #include "u_prot.h" - -void namespace_init(void); -int namespace_register(const char *path, obj_handler_t hd); +enum ns_op +{ + OP_REGISTER, + OP_QUERY, +}; +void namespace_init(obj_handler_t ipc_hd); +int namespace_register(const char *path, obj_handler_t hd, int type); int namespace_query(const char *path, obj_handler_t *hd); int namespace_pre_alloc_map_fd(void); void namespace_loop(void); diff --git a/mkrtos_user/server/init/src/test/ns_test.c b/mkrtos_user/server/init/src/test/ns_test.c new file mode 100644 index 000000000..155dee5de --- /dev/null +++ b/mkrtos_user/server/init/src/test/ns_test.c @@ -0,0 +1,64 @@ + +#include "namespace.h" +#include "u_rpc.h" +#include "ns_types.h" +#include +#include +#include +int fs_svr_open(const char *path, int flags, int mode); +int fs_svr_readdir(int fd, dirent_t *dir); +void fs_svr_close(int fd); +int fs_svr_unlink(char *path); +int ns_reg(const char *path, obj_handler_t hd, enum node_type type); + +void ns_test(void) +{ + int ret; + ret = ns_reg("/", 0, FILE_NODE); + assert(ret < 0); + ret = ns_reg("/test", 0, FILE_NODE); + assert(ret >= 0); + ret = ns_reg("/test", 0, FILE_NODE); + assert(ret < 0); + ret = ns_reg("/test1", 0, DIR_NODE); + assert(ret >= 0); + ret = ns_reg("/test2", 0, MOUNT_NODE); + assert(ret >= 0); + + int fd; + + { + fd = fs_svr_open("/c", O_CREAT, 0); + assert(fd >= 0); + fs_svr_close(fd); + } + { + fd = fs_svr_open("/", 0, 0); + assert(fd >= 0); + dirent_t dir; + while (fs_svr_readdir(fd, &dir) >= 0) + { + printf("%s\n", dir.d_name); + } + fs_svr_close(fd); + } + + ret = fs_svr_unlink("/test"); + assert(ret >= 0); + ret = fs_svr_unlink("/test1"); + assert(ret >= 0); + ret = fs_svr_unlink("/test2"); + assert(ret >= 0); + ret = fs_svr_unlink("/c"); + assert(ret >= 0); + { + fd = fs_svr_open("/", 0, 0); + assert(fd >= 0); + dirent_t dir; + while (fs_svr_readdir(fd, &dir) >= 0) + { + printf("%s\n", dir.d_name); + } + fs_svr_close(fd); + } +} diff --git a/mkrtos_user/server/init/src/test/test.h b/mkrtos_user/server/init/src/test/test.h index b04438989..37882958c 100644 --- a/mkrtos_user/server/init/src/test/test.h +++ b/mkrtos_user/server/init/src/test/test.h @@ -1,6 +1,5 @@ #pragma once -// TODO:修改为init call void mm_test(void); void ulog_test(void); void factory_test(void); @@ -17,3 +16,4 @@ void kobj_create_press_test(void); void sleep_tick(int tick); void pthread_lock_test(void); int pthread_cond_lock_test(void); +void ns_test(void); diff --git a/mkrtos_user/server/test/test/ns_test.c b/mkrtos_user/server/test/test/ns_test.c index d9f836232..e142dd9b9 100644 --- a/mkrtos_user/server/test/test/ns_test.c +++ b/mkrtos_user/server/test/test/ns_test.c @@ -20,7 +20,7 @@ void ns_test(void) assert(tmp_ipc_hd != HANDLER_INVALID); msg_tag_t tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(0, 0, tmp_ipc_hd)); - assert(ns_register("shell", tmp_ipc_hd) >= 0); + assert(ns_register("shell", tmp_ipc_hd, FILE_NODE) >= 0); obj_handler_t rcv_ipc_hd; assert(ns_query("shell", &rcv_ipc_hd) >= 0); diff --git a/setting.cmake b/setting.cmake index 1df03a5f7..7a36a30f9 100755 --- a/setting.cmake +++ b/setting.cmake @@ -27,7 +27,7 @@ set(CMAKE_C_FLAGS "-mcpu=${MKRTOS_ARCH} -mthumb -O0 -g3 -lc -lrdimon -msoft-floa -fno-stack-protector -Wl,--gc-sections \ " CACHE STRING "" FORCE) -set(CMAKE_CXX_FLAGS "-mcpu=${MKRTOS_ARCH}-mthumb -mno-thumb-interwork -D=MKRTOS \ +set(CMAKE_CXX_FLAGS "-mcpu=${MKRTOS_ARCH} -mthumb -mno-thumb-interwork -D=MKRTOS \ -mfix-cortex-m3-ldrd -Os -g3 -std=c++11 \ -fmessage-length=0 -Xlinker --print-map -Wall -W -fno-stack-protector -g \ -mfloat-abi=soft -lc -lrdimon -u _printf_float \