From 8e4d821a1d15f1ea31072d4014204431321d52a4 Mon Sep 17 00:00:00 2001 From: zhangzheng <1358745329@qq.com> Date: Tue, 25 Feb 2025 13:48:10 +0800 Subject: [PATCH] =?UTF-8?q?u=5Fmalloc=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 4 +- .vscode/settings.json | 3 +- .../libc_backend/src/armv7_8m/mm_backend.c | 9 +- mkrtos_user/lib/util/inc/u_malloc.h | 13 ++ mkrtos_user/lib/util/inc/u_path.h | 3 + mkrtos_user/lib/util/src/u_malloc.c | 149 ++++++++++++++++++ mkrtos_user/lib/util/src/u_path.c | 147 +++++++++++++++++ mkrtos_user/server/init/CMakeLists.txt | 2 +- mkrtos_user/server/init/src/nsfs/ns.c | 9 +- mkrtos_user/server/init/src/nsfs/ns.h | 7 +- .../server/init/src/test/malloc_test.c | 12 ++ 11 files changed, 346 insertions(+), 12 deletions(-) create mode 100644 mkrtos_user/lib/util/inc/u_malloc.h create mode 100644 mkrtos_user/lib/util/inc/u_path.h create mode 100644 mkrtos_user/lib/util/src/u_malloc.c create mode 100644 mkrtos_user/lib/util/src/u_path.c diff --git a/.vscode/launch.json b/.vscode/launch.json index 6ab8b0076..8ae29d750 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -71,8 +71,8 @@ // "miDebuggerPath": "/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/aarch64-none-elf-gdb", // "miDebuggerPath": "/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb", // "miDebuggerPath": "/home/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb", - "miDebuggerPath": "/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb", - // "miDebuggerPath": "/home/zhangzheng/toolchain/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi/bin/arm-none-eabi-gdb", + // "miDebuggerPath": "/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb", + "miDebuggerPath": "/home/zhangzheng/toolchain/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi/bin/arm-none-eabi-gdb", "miDebuggerServerAddress": "127.0.0.1:33333", "MIMode": "gdb", "setupCommands": [ diff --git a/.vscode/settings.json b/.vscode/settings.json index f75ac40f7..25765870a 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -194,7 +194,8 @@ "sockets.h": "c", "socket.h": "c", "net_svr.h": "c", - "inet.h": "c" + "inet.h": "c", + "u_malloc.h": "c" }, "cortex-debug.showRTOS": false, "cortex-debug.variableUseNaturalFormat": true, diff --git a/mkrtos_user/lib/libc_backend/src/armv7_8m/mm_backend.c b/mkrtos_user/lib/libc_backend/src/armv7_8m/mm_backend.c index 4348da9c8..a99740842 100644 --- a/mkrtos_user/lib/libc_backend/src/armv7_8m/mm_backend.c +++ b/mkrtos_user/lib/libc_backend/src/armv7_8m/mm_backend.c @@ -122,6 +122,7 @@ static int _sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_ { return -ENOSYS; } + len = ALIGN(len, MK_PAGE_SIZE); if (prot & PROT_PFS) { msg_tag_t tag; @@ -154,10 +155,10 @@ static int _sys_mmap2(void *start, size_t len, int prot, int flags, int fd, off_ } else { - if (len & (PAGE_SIZE - 1)) - { - return -EINVAL; - } + // if (len & (PAGE_SIZE - 1)) + // { + // return -EINVAL; + // } *addr = (umword_t)mm_page_alloc(len / PAGE_SIZE); } if (*addr == 0) diff --git a/mkrtos_user/lib/util/inc/u_malloc.h b/mkrtos_user/lib/util/inc/u_malloc.h new file mode 100644 index 000000000..0b5f27489 --- /dev/null +++ b/mkrtos_user/lib/util/inc/u_malloc.h @@ -0,0 +1,13 @@ +#pragma once + +struct allocmem +{ + void *ptr; + size_t size; + struct allocmem *next; +}; + +void *u_malloc(size_t size); +void *u_calloc(size_t size, int nmemb); +void u_free(void *ptr); +// void spurge(); diff --git a/mkrtos_user/lib/util/inc/u_path.h b/mkrtos_user/lib/util/inc/u_path.h new file mode 100644 index 000000000..941f2ab7e --- /dev/null +++ b/mkrtos_user/lib/util/inc/u_path.h @@ -0,0 +1,3 @@ +#pragma once + +void u_rel_path_to_abs(const char *cur_path, const char *path, char *new_path); diff --git a/mkrtos_user/lib/util/src/u_malloc.c b/mkrtos_user/lib/util/src/u_malloc.c new file mode 100644 index 000000000..972fb3652 --- /dev/null +++ b/mkrtos_user/lib/util/src/u_malloc.c @@ -0,0 +1,149 @@ +/** + * u_malloc.c: a simple memory allocator for use in MKRTOS. + * 使用缺页模拟申请内存,申请的内存不能用于栈内存。 + */ +#include +#include +#include +#include +#include + +#include + +static struct allocmem *memlocs = NULL; + +static struct allocmem *new_alloc_mem() +{ + struct allocmem *ptr; + if ((ptr = mmap(NULL, sizeof(struct allocmem), PROT_READ | PROT_WRITE | PROT_PFS, MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) == MAP_FAILED) + { + return NULL; + } + else + { + ptr->ptr = NULL; + ptr->size = 0; + ptr->next = NULL; + return ptr; + } +} + +static void free_alloc_mem(struct allocmem *ptr) +{ + if (ptr != NULL) + { + munmap(ptr, sizeof(struct allocmem)); + } +} + +/// Pass a valid pointer (or NULL) to store the resultant into +struct allocmem *insert_end(struct allocmem *ptr, struct allocmem **outVar) +{ + if (ptr == NULL) + { + struct allocmem *outAble = new_alloc_mem(); + if (outVar != NULL) + *outVar = outAble; + return (outAble); + } + else + { + ptr->next = insert_end(ptr->next, outVar); + return ptr; + } +} + +struct allocmem *find(struct allocmem *ptr, void *searchPtr) +{ + if (ptr == NULL) + { + return NULL; + } + if (ptr->ptr == searchPtr) + return ptr; + return find(ptr->next, searchPtr); +} + +struct allocmem *find_and_remove(struct allocmem *ptr, void *searchPtr) +{ + if (ptr == NULL) + { + return NULL; + } + if (ptr->ptr == searchPtr) + { + struct allocmem *nextUp = ptr->next; + free_alloc_mem(ptr); + return nextUp; + } + ptr->next = find_and_remove(ptr->next, searchPtr); + return ptr; +} + +void *u_malloc(size_t size) +{ + struct allocmem *info = NULL; + memlocs = insert_end(memlocs, &info); + if (info == NULL) + { + /// Failed to initialize metadata info + return NULL; + } + void *ptr; + if ((ptr = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_PFS, MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) == MAP_FAILED) + { + /// Failed to make data, revert changes + memlocs = find_and_remove(memlocs, NULL); + } + else + { + /// Got it together + info->ptr = ptr; + info->size = size; + /// Return this precious pointer + return ptr; + } + return NULL; +} + +void *u_calloc(size_t size, int nmemb) +{ + size_t isOverFlow = size * nmemb; + if (size != isOverFlow / nmemb) + { + /// Overflow, dont try + return NULL; + } + void *newPtr = u_malloc(isOverFlow); + if (newPtr == NULL) + { + /// Failed to init + return NULL; + } + /// A character is a byte of data that can be managed + for (size_t loc = 0; loc < isOverFlow; loc++) + { + *(((char *)newPtr) + loc) = 0; + } + return newPtr; +} + +void u_free(void *ptr) +{ + if (ptr == NULL) + return; + struct allocmem *info = find(memlocs, ptr); + if (info == NULL) + return; + munmap(info->ptr, info->size); + memlocs = find_and_remove(memlocs, ptr); +} + +/// Violently Remove Everything +// void spurge() +// { +// while (memlocs) +// { +// sfree(memlocs->ptr); +// } +// } \ No newline at end of file diff --git a/mkrtos_user/lib/util/src/u_path.c b/mkrtos_user/lib/util/src/u_path.c new file mode 100644 index 000000000..f9a326a4d --- /dev/null +++ b/mkrtos_user/lib/util/src/u_path.c @@ -0,0 +1,147 @@ + +#include + +static int path_name_cp(char *dst, const char *src, int src_inx, int *cp_len, int *jmp_len) +{ + int j = 0; + int jmp_cn = 0; + int type = -1; + int last_is_slash = 0; + + while (*src) + { + if (src[0] == '.' && (src_inx == 0 || src[-1] == '/')) + { + if (src[1] == 0) + { + type = 0; + } + else if (src[1] == '.') + { + if (src[2] == '/') + { + type = 1; + } + else if (src[2] == 0) + { + type = 2; + } + } + else if (src[1] == '/') + { + type = 3; + } + } + if (type != -1) + { + break; + } + if (*src != '/' || last_is_slash == 0) + { + *dst = *src; + dst++; + j++; + } + if (*src == '/') + { + last_is_slash = 1; + } + else + { + last_is_slash = 0; + } + src++; + jmp_cn++; + } + dst[j] = 0; + *cp_len = j; + *jmp_len = jmp_cn; + return type; +} +/** + * 相对路径转绝对路径 + * @param cur_path 基路径 + * @param path 相对路径 + * @param new_path 输出的路径 + * @return 输出的路径 + */ +char *u_rel_path_to_abs(const char *cur_path, const char *path, char *new_path) +{ + int t_len = 0; + if (path[0] != '/' || (path[0] == '.' && path[1] == '/')) + { + strcpy(new_path, cur_path); + if (new_path[strlen(new_path) - 1] != '/') + { + strcat(new_path, "/"); + t_len += 1; + } + t_len = strlen(cur_path); + } + for (int i = 0; path[i];) + { + int cp_len; + int jmp_len; + int type = path_name_cp(new_path + t_len, path + i, i, &cp_len, &jmp_len); + + t_len += cp_len; + i += jmp_len; + switch (type) + { + case 0: + i += 1; + break; + case 1: + if (t_len == 0) + { + i += 3; + } + else + { + new_path[--t_len] = 0; + while (t_len > 0) + { + if (new_path[--t_len] == '/') + { + break; + } + } + new_path[t_len] = 0; + i += 3; + } + break; + case 2: + if (t_len == 0) + { + i += 2; + } + else + { + new_path[--t_len] = 0; + while (t_len > 0) + { + if (new_path[--t_len] == '/') + { + break; + } + } + new_path[t_len] = 0; + i += 2; + } + break; + case 3: + i += 2; + break; + default: + goto end; + } + if (t_len == 0) + { + new_path[0] = '/'; + t_len = 1; + } + } +end: + new_path[t_len] = 0; + return new_path; +} diff --git a/mkrtos_user/server/init/CMakeLists.txt b/mkrtos_user/server/init/CMakeLists.txt index a9373a094..871e94f1d 100644 --- a/mkrtos_user/server/init/CMakeLists.txt +++ b/mkrtos_user/server/init/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.13) -file(GLOB deps src/*.c src/*.S src/test/*.c) +file(GLOB deps src/*.c src/*.S src/test/*.c src/nsfs/ns.c src/nsfs/nsfs.c) file(GLOB arch_src src/test/${ARCH_NAME}/*.c src/test/${ARCH_NAME}/*.S) if (NOT $ENV{MKRTOS_TEST_MODE} STREQUAL "normal") diff --git a/mkrtos_user/server/init/src/nsfs/ns.c b/mkrtos_user/server/init/src/nsfs/ns.c index 3e3825b98..ac5fd8b9b 100644 --- a/mkrtos_user/server/init/src/nsfs/ns.c +++ b/mkrtos_user/server/init/src/nsfs/ns.c @@ -5,7 +5,10 @@ #include #include #include "ns.h" - +#ifdef MKRTOS +#include +#include +#endif // 其他进程可以注册节点进来,并且可以注册子节点进来,子节点可以注册更多的子节点进来。 // 可以注册两种节点DUMMY和SVR节点 // 只有DUMMY节点里面可以注册SVR节点 @@ -98,7 +101,11 @@ static ns_node_t *node_create(const char *name, node_type_t type) { ns_node_t *tmp; +#ifdef MKRTOS + tmp = u_calloc(sizeof(ns_node_t), 1); +#else tmp = calloc(sizeof(ns_node_t), 1); +#endif if (!tmp) { return NULL; diff --git a/mkrtos_user/server/init/src/nsfs/ns.h b/mkrtos_user/server/init/src/nsfs/ns.h index da154b103..334b8edaf 100644 --- a/mkrtos_user/server/init/src/nsfs/ns.h +++ b/mkrtos_user/server/init/src/nsfs/ns.h @@ -8,11 +8,12 @@ #endif #define NS_NODE_NAME_LEN 32 - +#ifndef MKRTOS typedef unsigned long obj_handler_t; - #define HANDLER_INVALID ((obj_handler_t)(-1)) - +#else +#include +#endif typedef enum node_type { NODE_TYPE_DUMMY, //!< 虚拟节点,可以有子节点 diff --git a/mkrtos_user/server/init/src/test/malloc_test.c b/mkrtos_user/server/init/src/test/malloc_test.c index 79417cbd4..fc64170f9 100644 --- a/mkrtos_user/server/init/src/test/malloc_test.c +++ b/mkrtos_user/server/init/src/test/malloc_test.c @@ -66,6 +66,17 @@ static void mmap_test(CuTest *cu) } #undef TEST_MEM_SIZE } +#include "u_malloc.h" +static void u_alloc_test(CuTest *cu) +{ + for (int i = 0; i < 1000; i++) + { + void *mem = u_malloc(1024); + CuAssert(cu, "u_malloc failed.\n", mem != NULL); + memset(mem, 0, 1024); + u_free(mem); + } +} static CuSuite suite; CuSuite *malloc_test_suite(void) { @@ -73,5 +84,6 @@ CuSuite *malloc_test_suite(void) SUITE_ADD_TEST(&suite, malloc_test); SUITE_ADD_TEST(&suite, mmap_test); + SUITE_ADD_TEST(&suite, u_alloc_test); return &suite; }