From a1184c8e950a77c8f2272d6413515808b6394f07 Mon Sep 17 00:00:00 2001 From: zhangzheng <1358745329@qq.com> Date: Wed, 5 Feb 2025 14:44:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0cpu=E5=8D=A0=E7=94=A8?= =?UTF-8?q?=E7=8E=87=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 7 +- armv7_8.cmake | 2 +- mkrtos_configs/STM32F205_defconfig | 2 +- mkrtos_knl/arch/cortex-m3/sched_arch.c | 13 +- mkrtos_knl/arch/cortex-m3/thread_armv7m.c | 15 + mkrtos_knl/arch/cortex-m4/thread_armv7m.c | 15 + mkrtos_knl/drivers/stm32f2/systick/systick.c | 6 +- mkrtos_knl/inc/knl/thread.h | 4 + mkrtos_knl/inc/knl/thread_knl.h | 2 + mkrtos_knl/inc/knl/thread_task_arch.h | 1 + mkrtos_knl/knl/share_mem.c | 16 +- mkrtos_knl/knl/sys.c | 2 + mkrtos_knl/knl/thread.c | 305 +++++++++++------- mkrtos_knl/knl/thread_knl.c | 81 ++++- .../letter-shell/demo/mkrtos/shell_fs_ext.c | 13 +- mkrtos_user/lib/mlibc_shared/CMakeLists.txt | 4 +- mkrtos_user/lib/sys/inc/u_sys.h | 7 + mkrtos_user/lib/sys/src/u_sys.c | 1 + mkrtos_user/lib/sys_util/inc/u_rpc_svr.h | 3 + mkrtos_user/lib/sys_util/src/u_app_loader.c | 2 +- mkrtos_user/lib/sys_util/src/u_fast_ipc.c | 13 + mkrtos_user/lib/sys_util/src/u_rpc_svr.c | 14 +- 22 files changed, 372 insertions(+), 156 deletions(-) diff --git a/TODO.md b/TODO.md index 17566cc93..9a8ef653f 100644 --- a/TODO.md +++ b/TODO.md @@ -3,8 +3,13 @@ ## TODO list ### high prio * [x] APPFS 在flash中执行,能够支持app直接运行的文件系统。 -* [x] 完善mpu缺页管理支持。 +* [x] 完善mpu缺页模拟支持,红黑树管理,支持整块或者分块缺页支持。 * [x] 内存管理对象mpu支持完善(在缺页时自动映射)。 +* [x] 一种新的ipc机制(暂时取名fastipc),不切上下文,只切内存,流程更加简单,解决原来ipc优先级问题,以及并发性问题。 +* [ ] 进程管理机制完善,进程状态订阅,进程间信号发送。 +* [ ] 内核信号量对象完善(支持优先级反转,支持超时)。 +* [ ] FPU完善支持,目前版本偶发压栈错误 +* [ ] cpu占用率支持 ### mid prio * [ ] net server support * [x] block driver diff --git a/armv7_8.cmake b/armv7_8.cmake index b20d58fc6..1cc1dd41c 100644 --- a/armv7_8.cmake +++ b/armv7_8.cmake @@ -1,6 +1,6 @@ message("========use armv7_8.cmake") -set(CMAKE_C_FLAGS "-mcpu=${CONFIG_ARCH} -O0 -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -DMKRTOS \ +set(CMAKE_C_FLAGS "-mcpu=${CONFIG_ARCH} -Ofast -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -DMKRTOS \ -std=gnu11 -ffunction-sections -fdata-sections -fno-builtin -u=_printf_float \ -nostartfiles -nodefaultlibs -nostdlib -nostdinc \ -fno-stack-protector -Wl,--gc-section -D__ARM_ARCH_7M__ \ diff --git a/mkrtos_configs/STM32F205_defconfig b/mkrtos_configs/STM32F205_defconfig index 4242f138c..88d91b17b 100644 --- a/mkrtos_configs/STM32F205_defconfig +++ b/mkrtos_configs/STM32F205_defconfig @@ -32,7 +32,7 @@ CONFIG_FD_MAP_ROW_NR=16 # # Sys util config # -CONFIG_USING_SIG=n +CONFIG_USING_SIG=y CONFIG_SIG_THREAD_STACK_SIZE=512 CONFIG_SIG_THREAD_PRIO=3 # end of Sys util config diff --git a/mkrtos_knl/arch/cortex-m3/sched_arch.c b/mkrtos_knl/arch/cortex-m3/sched_arch.c index a28432b4f..983e69ddc 100644 --- a/mkrtos_knl/arch/cortex-m3/sched_arch.c +++ b/mkrtos_knl/arch/cortex-m3/sched_arch.c @@ -4,6 +4,7 @@ #include #include #include +#include /** * @brief 调度函数 * @@ -23,13 +24,21 @@ sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type) assert(next_th->magic == THREAD_MAGIC); - if (sche->sched_reset) + thread_t *cur_th = thread_get_current(); + if (sche->sched_reset == 1) { - thread_t *cur_th = thread_get_current(); cur_th->sp.knl_sp = ksp; cur_th->sp.user_sp = usp; cur_th->sp.sp_type = sp_type; } + else if (sche->sched_reset == 2) + { + cur_th->sp.knl_sp = ksp; + // cur_th->sp.user_sp = usp; + // cur_th->sp.sp_type = sp_type; + } + atomic_inc(&cur_th->time_count); + sche->sched_reset = 1; return &next_th->sp; } diff --git a/mkrtos_knl/arch/cortex-m3/thread_armv7m.c b/mkrtos_knl/arch/cortex-m3/thread_armv7m.c index 9430cb438..b822a6fb1 100644 --- a/mkrtos_knl/arch/cortex-m3/thread_armv7m.c +++ b/mkrtos_knl/arch/cortex-m3/thread_armv7m.c @@ -56,6 +56,21 @@ void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram) cur_th->sp.user_sp = cur_pf; cur_th->sp.sp_type = 0xfffffffd; } +void thread_set_user_pf_noset_knl_sp(thread_t *cur_th, void *pc, void *user_sp, void *ram) +{ + umword_t usp = ((umword_t)(user_sp) & ~0x7UL); + + pf_t *cur_pf = (pf_t *)(usp)-1; // thread_get_pf(cur_th); + + cur_pf->pf_s.xpsr = 0x01000000L; + cur_pf->pf_s.lr = (umword_t)NULL; //!< 线程退出时调用的函数 + cur_pf->pf_s.pc = (umword_t)pc | 0x1; + cur_pf->regs[5] = (umword_t)ram; + + // cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8); + cur_th->sp.user_sp = cur_pf; + cur_th->sp.sp_type = 0xfffffffd; +} void thread_user_pf_restore(thread_t *cur_th, void *user_sp) { cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8); diff --git a/mkrtos_knl/arch/cortex-m4/thread_armv7m.c b/mkrtos_knl/arch/cortex-m4/thread_armv7m.c index c994a2b4f..dc6b32d36 100644 --- a/mkrtos_knl/arch/cortex-m4/thread_armv7m.c +++ b/mkrtos_knl/arch/cortex-m4/thread_armv7m.c @@ -60,6 +60,21 @@ void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram) cur_th->sp.user_sp = cur_pf; cur_th->sp.sp_type = 0xfffffffd; } +void thread_set_user_pf_noset_knl_sp(thread_t *cur_th, void *pc, void *user_sp, void *ram) +{ + umword_t usp = ((umword_t)(user_sp) & ~0x7UL); + + pf_t *cur_pf = (pf_t *)(usp)-1; // thread_get_pf(cur_th); + + cur_pf->pf_s.xpsr = 0x01000000L; + cur_pf->pf_s.lr = (umword_t)NULL; //!< 线程退出时调用的函数 + cur_pf->pf_s.pc = (umword_t)pc | 0x1; + cur_pf->regs[5] = (umword_t)ram; + + // cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8); + cur_th->sp.user_sp = cur_pf; + cur_th->sp.sp_type = 0xfffffffd; +} void thread_user_pf_restore(thread_t *cur_th, void *user_sp) { cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8); diff --git a/mkrtos_knl/drivers/stm32f2/systick/systick.c b/mkrtos_knl/drivers/stm32f2/systick/systick.c index b951e4a4a..fcfb78d43 100755 --- a/mkrtos_knl/drivers/stm32f2/systick/systick.c +++ b/mkrtos_knl/drivers/stm32f2/systick/systick.c @@ -3,6 +3,7 @@ #include "thread.h" #include "futex.h" #include "irq.h" +#include "thread_knl.h" static umword_t sys_tick_cnt; umword_t sys_tick_cnt_get(void) @@ -17,8 +18,9 @@ void SysTick_Handler(void) sys_tick_cnt++; thread_timeout_check(1); futex_timeout_times_tick(); - #if 0 + thread_calc_cpu_usage(); +#if 0 extern void uart_check_timeover(irq_entry_t * irq); uart_check_timeover(irq_get(LOG_INTR_NO)); - #endif +#endif } diff --git a/mkrtos_knl/inc/knl/thread.h b/mkrtos_knl/inc/knl/thread.h index 09ce59662..830d1f592 100755 --- a/mkrtos_knl/inc/knl/thread.h +++ b/mkrtos_knl/inc/knl/thread.h @@ -293,3 +293,7 @@ void thread_timeout_check(ssize_t tick); msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id); int thread_ipc_call(thread_t *to_th, msg_tag_t in_tag, msg_tag_t *ret_tag, ipc_timeout_t timout, umword_t *ret_user_id, bool_t is_call); +bool_t thread_is_knl(thread_t *thread); + +msg_tag_t thread_fast_ipc_replay(entry_frame_t *f); +msg_tag_t thread_fast_ipc_call(thread_t *to_th, entry_frame_t *f, umword_t user_id); diff --git a/mkrtos_knl/inc/knl/thread_knl.h b/mkrtos_knl/inc/knl/thread_knl.h index d6eb5d330..8fc95f0d5 100644 --- a/mkrtos_knl/inc/knl/thread_knl.h +++ b/mkrtos_knl/inc/knl/thread_knl.h @@ -1,5 +1,7 @@ #pragma once #include +void thread_calc_cpu_usage(void); +uint16_t cpu_get_current_usage(void); bool_t task_knl_kill(thread_t *kill_thread, bool_t is_knl); void knl_init_1(void); diff --git a/mkrtos_knl/inc/knl/thread_task_arch.h b/mkrtos_knl/inc/knl/thread_task_arch.h index 1a1b838a5..811d609bd 100644 --- a/mkrtos_knl/inc/knl/thread_task_arch.h +++ b/mkrtos_knl/inc/knl/thread_task_arch.h @@ -2,4 +2,5 @@ void thread_knl_pf_set(thread_t *cur_th, void *pc); void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram); void thread_user_pf_restore(thread_t *cur_th, void *user_sp); +void thread_set_user_pf_noset_knl_sp(thread_t *cur_th, void *pc, void *user_sp, void *ram); void task_knl_init(task_t *knl_tk); diff --git a/mkrtos_knl/knl/share_mem.c b/mkrtos_knl/knl/share_mem.c index 01b2543bc..22516c13a 100644 --- a/mkrtos_knl/knl/share_mem.c +++ b/mkrtos_knl/knl/share_mem.c @@ -175,6 +175,11 @@ static int share_mem_free_pmem(share_mem_t *obj) assert(obj); switch (obj->mem_type) { + case SHARE_MEM_CNT_CMA_CNT: +#if IS_ENABLED(CONFIG_MMU) + /*TODO:support CMA mem.*/ + return -ENOSYS; +#endif case SHARE_MEM_CNT_BUDDY_CNT: #if IS_ENABLED(CONFIG_MMU) mm_limit_free_buddy(obj->lim, obj->mem, obj->size); @@ -182,9 +187,6 @@ static int share_mem_free_pmem(share_mem_t *obj) mm_limit_free_align(obj->lim, obj->mem, obj->size); #endif break; - case SHARE_MEM_CNT_CMA_CNT: - /*TODO:support CMA mem.*/ - return -ENOSYS; case SHARE_MEM_CNT_DPD: { #if IS_ENABLED(CONFIG_MMU) @@ -221,6 +223,11 @@ static int share_mem_alloc_pmem(share_mem_t *obj) } switch (obj->mem_type) { + case SHARE_MEM_CNT_CMA_CNT: +#if IS_ENABLED(CONFIG_MMU) + /*TODO:support CMA mem.*/ + return -ENOSYS; +#endif case SHARE_MEM_CNT_BUDDY_CNT: #if IS_ENABLED(CONFIG_MMU) obj->mem = mm_limit_alloc_buddy(obj->lim, obj->size); @@ -256,9 +263,6 @@ static int share_mem_alloc_pmem(share_mem_t *obj) } memset(obj->mem, 0, obj->size); break; - case SHARE_MEM_CNT_CMA_CNT: - /*TODO:support CMA mem.*/ - return -ENOSYS; case SHARE_MEM_CNT_DPD: { #if IS_ENABLED(CONFIG_MMU) diff --git a/mkrtos_knl/knl/sys.c b/mkrtos_knl/knl/sys.c index a153aa89f..8e633b4aa 100755 --- a/mkrtos_knl/knl/sys.c +++ b/mkrtos_knl/knl/sys.c @@ -26,6 +26,7 @@ #include #include #include +#include typedef struct sys { @@ -97,6 +98,7 @@ static void sys_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, #else f->regs[1] = 0; #endif + f->regs[2] = cpu_get_current_usage(); tag = msg_tag_init4(0, 0, 0, ret); break; } diff --git a/mkrtos_knl/knl/thread.c b/mkrtos_knl/knl/thread.c index 64e7290b6..1a0e35977 100755 --- a/mkrtos_knl/knl/thread.c +++ b/mkrtos_knl/knl/thread.c @@ -36,6 +36,9 @@ #if IS_ENABLED(CONFIG_SMP) #include #endif +#if IS_ENABLED(CONFIG_MPU) +#include +#endif #define TAG "[thread]" enum thread_op @@ -362,9 +365,9 @@ bool_t thread_sched(bool_t is_sche) assert(th->magic == THREAD_MAGIC); if (next_sche == &th->sche) { + atomic_inc(&th->time_count); //!< 线程没有发生变化,则不用切换 cpulock_set(status); - return FALSE; } if (is_sche) @@ -1156,6 +1159,180 @@ end: #endif return ret; } +msg_tag_t thread_fast_ipc_call(thread_t *to_th, entry_frame_t *f, umword_t user_id) +{ + task_t *cur_task = thread_get_current_task(); + thread_t *cur_th = thread_get_current(); + msg_tag_t in_tag = msg_tag_init(f->regs[0]); + int ret; + // 1.需要切换的资源有r9,task,和用户栈 + // 2.在对方进程中被杀死,需要还原当前线程的状态,并返回一个错误 + // 3.多线程访问时,服务端提供一个小的用户线程栈,然后内核到用户部分为临界区域,在服务端重新分配用户栈用,使用新的用户栈。 + // 4.fastipc嵌套访问会有问题,内核必须要提供一个软件上的调用栈。 + // 在嵌套调用时,如果在其它进程中挂掉,如果是当前线程则需要还原 + task_t *to_task = thread_get_bind_task(to_th); + + if (to_task->nofity_point == NULL) + { + printk("task:0x%x, notify point is not set.\n", to_task); + return msg_tag_init4(0, 0, 0, -EIO); + } +_to_unlock: + if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len)) + { + thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/ + preemption(); + goto _to_unlock; + } + mutex_lock(&to_task->nofity_lock); + if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len)) + { + mutex_unlock(&to_task->nofity_lock); + thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/ + preemption(); + goto _to_unlock; + } + umword_t cpu_status = cpulock_lock(); + ref_counter_inc((&to_task->ref_cn)); + //!< 执行目标线程时用的是当前线程的资源,这里还需要备份当前线程的上下文。 + ret = thread_fast_ipc_save(cur_th, to_task, (void *)(to_task->nofity_stack - 4 * 8 /*FIXME:改成宏*/)); //!< 备份栈和usp + if (ret >= 0) + { + ipc_msg_t *dst_ipc = (void *)to_task->nofity_msg_buf; + ipc_msg_t *src_ipc = (void *)cur_th->msg.msg; + ret = ipc_dat_copy_raw(&to_task->obj_space, &cur_task->obj_space, to_task->lim, + dst_ipc, src_ipc, in_tag, FALSE); + if (ret >= 0) + { + dst_ipc->user[2] = task_pid_get(cur_task); // 设置pid + slist_add(&to_task->nofity_theads_head, &cur_th->fast_ipc_node); // 添加到链表中,用于进程关闭时进行释放 + pf_s_t *usr_stask_point = (void *)arch_get_user_sp(); + + if (thread_is_knl(cur_th)) + { + // 如果是内核线程则全部重新设置 + thread_set_user_pf_noset_knl_sp(cur_th, to_task->nofity_point, + (void *)to_task->nofity_stack, (void *)to_task->mm_space.mm_block); + usr_stask_point->rg0[0] = in_tag.raw; + usr_stask_point->rg0[1] = user_id; + usr_stask_point->rg0[2] = f->regs[2]; + usr_stask_point->rg0[3] = f->regs[3]; + + scheduler_get_current()->sched_reset = 2; + } + else + { + usr_stask_point->r12 = 0x12121212; + usr_stask_point->xpsr = 0x01000000L; + usr_stask_point->lr = (umword_t)NULL; //!< 线程退出时调用的函数 + usr_stask_point->pc = (umword_t)(to_task->nofity_point) | 0x1; + + //! 获得内核栈栈顶 + pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1; + // 重新设置r9寄存器 + cur_pf->regs[5] = (umword_t)(to_task->mm_space.mm_block); + + //! 寄存器传参数 + f->regs[0] = in_tag.raw; + f->regs[1] = user_id; + f->regs[2] = f->regs[2]; + f->regs[3] = f->regs[3]; + } + // 切换mpu + mpu_switch_to_task(to_task); + cpulock_set(cpu_status); + if (thread_is_knl(cur_th)) + { + // 内核线程则立刻进行调度 + arch_to_sche(); + preemption(); + } + return in_tag; + } + else + { + ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj); + mutex_unlock(&to_task->nofity_lock); + } + } + else + { + ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj); + mutex_unlock(&to_task->nofity_lock); + } + cpulock_set(cpu_status); + + return msg_tag_init4(0, 0, 0, ret); +} +msg_tag_t thread_fast_ipc_replay(entry_frame_t *f) +{ + task_t *cur_task = thread_get_current_task(); + thread_t *cur_th = thread_get_current(); + msg_tag_t in_tag = msg_tag_init(f->regs[0]); + task_t *old_task = thread_get_bind_task(cur_th); + int ret; + + *(cur_task->nofity_bitmap) &= ~(1 << MIN(f->regs[2], cur_task->nofity_bitmap_len)); //!< 解锁bitmap + slist_del(&cur_th->fast_ipc_node); // 从链表中删除 + + ret = thread_fast_ipc_restore(cur_th); // 还原栈和usp + if (ret < 0) + { + mutex_unlock(&old_task->nofity_lock); + return msg_tag_init4(0, 0, 0, ret); + } + umword_t cpu_status = cpulock_lock(); + + cur_task = thread_get_current_task(); + ipc_msg_t *dst_ipc = (void *)cur_th->msg.msg; + ipc_msg_t *src_ipc = (void *)old_task->nofity_msg_buf; + ret = ipc_dat_copy_raw(&cur_task->obj_space, &old_task->obj_space, cur_task->lim, + dst_ipc, src_ipc, in_tag, TRUE); // copy数据 + // if (ret >=0 ) { + for (int i = 0; i < CONFIG_THREAD_MAP_BUF_LEN; i++) + { + if (i < ret) + { + src_ipc->map_buf[i] = old_task->nofity_map_buf[i]; + old_task->nofity_map_buf[i] = 0; + } + else + { + src_ipc->map_buf[i] = old_task->nofity_map_buf[i]; + } + } + // } + mutex_unlock(&old_task->nofity_lock); + if (thread_is_knl(cur_th)) + { + //! 吧r4-r11留出来 + // memcpy((char *)cur_th->sp.knl_sp - 4 * 8 /*FIXME:*/, (char *)cur_th->sp.knl_sp, 4 * 8); + // memset(cur_th->sp.knl_sp, 0, 4 * 8); + // cur_th->sp.knl_sp = (char *)cur_th->sp.knl_sp - 4 * 8; + cur_th->sp.user_sp = 0x0; + cur_th->sp.sp_type = 0xfffffff9; + scheduler_get_current()->sched_reset = 3; + } + else + { + pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1; + + cur_pf->regs[5] = (umword_t)(cur_task->mm_space.mm_block); // 更新r9寄存器 + } + mpu_switch_to_task(cur_task); // 切换mpu + ref_counter_dec_and_release(&old_task->ref_cn, &old_task->kobj); + if (ret < 0) + { + in_tag = msg_tag_init4(0, 0, 0, ret); + } + cpulock_set(cpu_status); + if (thread_is_knl(cur_th)) + { + arch_to_sche(); + preemption(); + } + return in_tag; +} /** * @brief 执行ipc * @@ -1178,134 +1355,12 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id) { case IPC_FAST_REPLAY: { - msg_tag_t in_tag = msg_tag_init(f->regs[0]); - task_t *old_task = thread_get_bind_task(cur_th); - - - *(cur_task->nofity_bitmap) &= ~(1 << MIN(f->regs[2], cur_task->nofity_bitmap_len)); //!< 解锁bitmap - slist_del(&cur_th->fast_ipc_node);//从链表中删除 - - ret = thread_fast_ipc_restore(cur_th); // 还原栈和usp - if (ret < 0) - { - mutex_unlock(&old_task->nofity_lock); - return msg_tag_init4(0, 0, 0, ret); - } - umword_t cpu_status = cpulock_lock(); - - task_t *cur_task = thread_get_current_task(); - ipc_msg_t *dst_ipc = (void *)cur_th->msg.msg; - ipc_msg_t *src_ipc = (void *)old_task->nofity_msg_buf; - ret = ipc_dat_copy_raw(&cur_task->obj_space, &old_task->obj_space, cur_task->lim, - dst_ipc, src_ipc, in_tag, TRUE); // copy数据 - // if (ret >=0 ) { - for (int i = 0; i < CONFIG_THREAD_MAP_BUF_LEN; i++) - { - if (i < ret) - { - src_ipc->map_buf[i] = old_task->nofity_map_buf[i]; - old_task->nofity_map_buf[i] = 0; - } - else - { - src_ipc->map_buf[i] = old_task->nofity_map_buf[i]; - } - } - // } - mutex_unlock(&old_task->nofity_lock); - pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1; - - cur_pf->regs[5] = (umword_t)(cur_task->mm_space.mm_block); //更新r9寄存器 - extern void mpu_switch_to_task(struct task * tk); - mpu_switch_to_task(cur_task);//切换mpu - ref_counter_dec_and_release(&old_task->ref_cn, &old_task->kobj); - if (ret < 0) - { - in_tag = msg_tag_init4(0, 0, 0, ret); - } - cpulock_set(cpu_status); - return in_tag; + return thread_fast_ipc_replay(f); } break; case IPC_FAST_CALL: { - msg_tag_t in_tag = msg_tag_init(f->regs[0]); - // 1.需要切换的资源有r9,task,和用户栈 - // 2.在对方进程中被杀死,需要还原当前线程的状态,并返回一个错误 - // 3.多线程访问时,服务端提供一个小的用户线程栈,然后内核到用户部分为临界区域,在服务端重新分配用户栈用,使用新的用户栈。 - // 4.fastipc嵌套访问会有问题,内核必须要提供一个软件上的调用栈。 - // 在嵌套调用时,如果在其它进程中挂掉,如果是当前线程则需要还原 - task_t *to_task = thread_get_bind_task(to_th); - - if (to_task->nofity_point == NULL) - { - printk("task:0x%x, notify point is not set.\n", to_task); - return msg_tag_init4(0, 0, 0, -EIO); - } - _to_unlock: - if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len)) - { - thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/ - preemption(); - goto _to_unlock; - } - mutex_lock(&to_task->nofity_lock); - if (GET_LSB(*to_task->nofity_bitmap, to_task->nofity_bitmap_len) == GET_LSB((~0ULL), to_task->nofity_bitmap_len)) - { - mutex_unlock(&to_task->nofity_lock); - thread_sched(TRUE); /*TODO:应该挂起,并在释放时唤醒*/ - preemption(); - goto _to_unlock; - } - umword_t cpu_status = cpulock_lock(); - ref_counter_inc((&to_task->ref_cn)); - //!< 执行目标线程时用的是当前线程的资源,这里还需要备份当前线程的上下文。 - ret = thread_fast_ipc_save(cur_th, to_task, (void *)(to_task->nofity_stack - 4 * 8)); //!< 备份栈和usp - if (ret >= 0) - { - ipc_msg_t *dst_ipc = (void *)to_task->nofity_msg_buf; - ipc_msg_t *src_ipc = (void *)cur_th->msg.msg; - ret = ipc_dat_copy_raw(&to_task->obj_space, &cur_task->obj_space, to_task->lim, - dst_ipc, src_ipc, in_tag, FALSE); - if (ret >= 0) - { - dst_ipc->user[2] = task_pid_get(cur_task); // 设置pid - - slist_add(&to_task->nofity_theads_head, &cur_th->fast_ipc_node); - - pf_s_t *usr_stask_point = (void *)arch_get_user_sp(); - - usr_stask_point->r12 = 0x12121212; - usr_stask_point->xpsr = 0x01000000L; - usr_stask_point->lr = (umword_t)NULL; //!< 线程退出时调用的函数 - usr_stask_point->pc = (umword_t)(to_task->nofity_point) | 0x1; - - pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1; //!< 获得内核栈栈顶 - cur_pf->regs[5] = (umword_t)(to_task->mm_space.mm_block); // 重新设置r9寄存器 - - //! 寄存器传参数 - f->regs[0] = in_tag.raw; - f->regs[1] = user_id; - f->regs[2] = f->regs[2]; - f->regs[3] = f->regs[3]; - - extern void mpu_switch_to_task(struct task * tk); - mpu_switch_to_task(to_task); - return in_tag; - } - else - { - ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj); - mutex_unlock(&to_task->nofity_lock); - } - } - else - { - ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj); - mutex_unlock(&to_task->nofity_lock); - } - cpulock_set(cpu_status); - return msg_tag_init4(0, 0, 0, ret); + return thread_fast_ipc_call(to_th, f, user_id); } break; case IPC_CALL: diff --git a/mkrtos_knl/knl/thread_knl.c b/mkrtos_knl/knl/thread_knl.c index ba66d32bf..39efd701c 100755 --- a/mkrtos_knl/knl/thread_knl.c +++ b/mkrtos_knl/knl/thread_knl.c @@ -23,6 +23,7 @@ #include "thread.h" #include "thread_task_arch.h" #include "types.h" +#include "prot.h" #include #if IS_ENABLED(CONFIG_KNL_TEST) #include @@ -39,13 +40,15 @@ #include #endif #include +#include "pre_cpu.h" static uint8_t knl_msg_buf[CONFIG_CPU][THREAD_MSG_BUG_LEN]; static task_t knl_task; static thread_t *init_thread; static task_t *init_task; - +static thread_t *knl_thread[CONFIG_CPU]; static slist_head_t del_task_head; +static umword_t cpu_usage[CONFIG_CPU]; static spinlock_t del_lock; static void knl_main(void) @@ -69,6 +72,7 @@ static void knl_main(void) spinlock_set(&del_lock, status2); continue; } + // 在这里删除进程 slist_foreach_not_next(pos, &del_task_head, del_node) { task_t *next = slist_next_entry(pos, &del_task_head, del_node); @@ -86,6 +90,7 @@ static void knl_main(void) if (thread_get_ipc_state(init_thread) != THREAD_IPC_ABORT) { +#if 0 int ret = thread_ipc_call(init_thread, msg_tag_init4(0, 3, 0, 0x0005 /*PM_PROT*/), &tag, ipc_timeout_create2(3000, 3000), &user_id, TRUE); @@ -93,6 +98,20 @@ static void knl_main(void) { printk("%s:%d ret:%d\n", __func__, __LINE__, ret); } +#endif +#define PM_PROT 0x0005 + +#define MAGIC_NS_USERPID 0xbabababa + entry_frame_t f; + f.regs[0] = msg_tag_init4(0, 3, 0, PM_PROT).raw; + f.regs[1] = 0; + f.regs[2] = 0x2222; /*传递两个参数,没有用到,暂时用不上*/ + f.regs[3] = 0x3333; + tag = thread_fast_ipc_call(init_thread, &f, MAGIC_NS_USERPID); + if (msg_tag_get_val(tag) < 0) + { + printk("init thread comm failed, ret:%d\n", __func__, __LINE__, msg_tag_get_val(tag)); + } } } } @@ -102,30 +121,68 @@ static void knl_main(void) spinlock_set(&del_lock, status2); } } +static inline uint32_t thread_knl_get_current_run_nr(void) +{ + if (knl_thread[arch_get_current_cpu_id()] == NULL) + { + return 0; + } + return atomic_read(&knl_thread[arch_get_current_cpu_id()]->time_count); +} + +static uint32_t cpu_usage_last_tick_val[CONFIG_CPU]; +/** + * 计算cpu占用率 + */ +void thread_calc_cpu_usage(void) +{ + uint8_t cur_cpu_id = arch_get_current_cpu_id(); + if (sys_tick_cnt_get() % 1000 == 0) + { + cpu_usage[cur_cpu_id] = 1000 - ((thread_knl_get_current_run_nr() - cpu_usage_last_tick_val[cur_cpu_id])); + cpu_usage_last_tick_val[cur_cpu_id] = thread_knl_get_current_run_nr(); + // printk("%d\n", cpu_usage[arch_get_current_cpu_id()]); + } +} +uint16_t cpu_get_current_usage(void) +{ + return (uint16_t)cpu_usage[arch_get_current_cpu_id()]; +} /** * 初始化内核线程 * 初始化内核任务 */ void knl_init_1(void) { - thread_t *knl_thread; + thread_t *knl_th; - knl_thread = thread_get_current(); - - thread_init(knl_thread, &root_factory_get()->limit, FALSE); + knl_thread[arch_get_current_cpu_id()] = thread_get_current(); + knl_th = knl_thread[arch_get_current_cpu_id()]; + thread_init(knl_th, &root_factory_get()->limit, FALSE); task_init(&knl_task, &root_factory_get()->limit, TRUE); task_knl_init(&knl_task); kobject_set_name(&knl_task.kobj, "tk_knl"); - thread_knl_pf_set(knl_thread, knl_main); - thread_bind(knl_thread, &knl_task.kobj); - kobject_set_name(&knl_thread->kobj, "th_knl"); - thread_set_msg_buf(knl_thread, knl_msg_buf[arch_get_current_cpu_id()], + thread_knl_pf_set(knl_th, knl_main); + thread_bind(knl_th, &knl_task.kobj); + kobject_set_name(&knl_th->kobj, "th_knl"); + thread_set_msg_buf(knl_th, knl_msg_buf[arch_get_current_cpu_id()], knl_msg_buf[arch_get_current_cpu_id()]); - knl_thread->cpu = arch_get_current_cpu_id(); - thread_ready(knl_thread, FALSE); + knl_th->cpu = arch_get_current_cpu_id(); + thread_ready(knl_th, FALSE); } INIT_STAGE1(knl_init_1); +/** + * 是否是内核线程 + */ +bool_t thread_is_knl(thread_t *thread) +{ + if (thread == knl_thread[arch_get_current_cpu_id()]) + return TRUE; + else + return FALSE; +} + /** * 初始化init线程 * 初始化用户态任务 @@ -233,7 +290,7 @@ bool_t task_knl_kill(thread_t *kill_thread, bool_t is_knl) // r9 = (umword_t)(thread_get_bind_task(kill_thread)->mm_space.mm_block); mpu_switch_to_task(thread_get_bind_task(kill_thread)); ref_counter_dec_and_release(&task->ref_cn, &task->kobj); - reset_ram =TRUE; + reset_ram = TRUE; } } else 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 index e313c10ae..a59a0b682 100644 --- a/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_fs_ext.c +++ b/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_fs_ext.c @@ -147,4 +147,15 @@ int shell_mem_info(int argc, char *argv[]) printf("sys mem:\ntotal:%dB\nfree:%dB\n", total, free); return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), free, shell_mem_info, free command); \ No newline at end of file +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), free, shell_mem_info, free command); + +int shell_sys_info(int argc, char *argv[]) +{ + size_t total; + size_t free; + + printf("sys:\n"); + printf("\tcpu usage:%2.1f\n", sys_read_cpu_usage() / 10.0f); + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), sys, shell_sys_info, sys command); diff --git a/mkrtos_user/lib/mlibc_shared/CMakeLists.txt b/mkrtos_user/lib/mlibc_shared/CMakeLists.txt index 0aa04c8e0..6e21afe20 100644 --- a/mkrtos_user/lib/mlibc_shared/CMakeLists.txt +++ b/mkrtos_user/lib/mlibc_shared/CMakeLists.txt @@ -55,8 +55,8 @@ add_custom_target( c_dump ALL COMMAND ${CMAKE_OBJCOPY} -O binary -S libc.so libc.bin - COMMAND - ${CMAKE_COMMAND} -E copy libc.bin ${CMAKE_SOURCE_DIR}/build/output/cpio/libc + # COMMAND + # ${CMAKE_COMMAND} -E copy libc.bin ${CMAKE_SOURCE_DIR}/build/output/cpio/libc # COMMAND # cp libc.so ${CMAKE_SOURCE_DIR}/build/output/libc.so # COMMAND diff --git a/mkrtos_user/lib/sys/inc/u_sys.h b/mkrtos_user/lib/sys/inc/u_sys.h index 5723e7b8a..1eea096f6 100644 --- a/mkrtos_user/lib/sys/inc/u_sys.h +++ b/mkrtos_user/lib/sys/inc/u_sys.h @@ -12,6 +12,7 @@ typedef struct sys_info typedef struct sys_info2 { umword_t resv_dtbo; + umword_t cpu_usage_cur; //!< 当前cpu占用率 } sys_info2_t; #define SYS_FLAGS_MAP_CPIO_FS 0x01 @@ -43,3 +44,9 @@ static inline umword_t sys_read_dtbo(void) sys_read_info2(SYS_PROT, &info, 0); return info.resv_dtbo; } +static inline umword_t sys_read_cpu_usage(void) +{ + sys_info2_t info; + sys_read_info2(SYS_PROT, &info, 0); + return info.cpu_usage_cur; +} diff --git a/mkrtos_user/lib/sys/src/u_sys.c b/mkrtos_user/lib/sys/src/u_sys.c index 5df8b1b23..1f0c46c7d 100644 --- a/mkrtos_user/lib/sys/src/u_sys.c +++ b/mkrtos_user/lib/sys/src/u_sys.c @@ -64,6 +64,7 @@ msg_tag_t sys_read_info2(obj_handler_t obj, sys_info2_t *info, umword_t flags) if (info) { info->resv_dtbo = r1; + info->cpu_usage_cur = r2; } return msg_tag_init(r0); diff --git a/mkrtos_user/lib/sys_util/inc/u_rpc_svr.h b/mkrtos_user/lib/sys_util/inc/u_rpc_svr.h index deb43d94c..1590d0580 100644 --- a/mkrtos_user/lib/sys_util/inc/u_rpc_svr.h +++ b/mkrtos_user/lib/sys_util/inc/u_rpc_svr.h @@ -32,8 +32,11 @@ typedef struct meta int rpc_meta_init(obj_handler_t th, obj_handler_t *ret_ipc_hd); void meta_unreg_svr_obj_raw(meta_t *meta, umword_t prot); void meta_unreg_svr_obj(umword_t prot); +rpc_svr_obj_t *meta_find_svr_obj(umword_t prot); int meta_reg_svr_obj(rpc_svr_obj_t *svr_obj, umword_t prot); int meta_reg_svr_obj_raw(meta_t *meta, rpc_svr_obj_t *svr_obj, umword_t prot); int rpc_creaite_bind_ipc(obj_handler_t th, void *obj, obj_handler_t *ipc_hd); void rpc_loop(void); +#if 0 int rpc_mtd_loop(void); +#endif diff --git a/mkrtos_user/lib/sys_util/src/u_app_loader.c b/mkrtos_user/lib/sys_util/src/u_app_loader.c index 1c6240a92..6a2d5fbc9 100644 --- a/mkrtos_user/lib/sys_util/src/u_app_loader.c +++ b/mkrtos_user/lib/sys_util/src/u_app_loader.c @@ -140,7 +140,7 @@ int app_load(const char *name, uenv_t *cur_env, pid_t *pid, #endif int type; umword_t addr; - int ret; + int ret = 0; #if IS_ENABLED(CONFIG_CPIO_SUPPORT) ret = cpio_find_file((umword_t)sys_info.bootfs_start_addr, (umword_t)(-1), name, NULL, &type, &addr); diff --git a/mkrtos_user/lib/sys_util/src/u_fast_ipc.c b/mkrtos_user/lib/sys_util/src/u_fast_ipc.c index cef4a014b..288681b36 100644 --- a/mkrtos_user/lib/sys_util/src/u_fast_ipc.c +++ b/mkrtos_user/lib/sys_util/src/u_fast_ipc.c @@ -6,9 +6,12 @@ #include #include #include +#include #include #include +#define MAGIC_NS_USERPID 0xbabababa + int fast_ipc_setsp(int i, void *stack); #define FAST_IPC_MAIN_STACK_SIZE 512 @@ -57,6 +60,16 @@ static msg_tag_t process_ipc(int j, umword_t obj, long tag) ret_tag = msg_tag_init4(0, 0, 0, -EACCES); goto end; } + if (svr_obj == (void *)MAGIC_NS_USERPID) + { + /*获取ns的user id*/ + svr_obj = meta_find_svr_obj(NS_PROT); + } + if (svr_obj == NULL) + { + ret_tag = msg_tag_init4(0, 0, 0, -EACCES); + goto end; + } if (svr_obj->dispatch) { ret_tag = svr_obj->dispatch(svr_obj, msg_tag_init(tag), msg); diff --git a/mkrtos_user/lib/sys_util/src/u_rpc_svr.c b/mkrtos_user/lib/sys_util/src/u_rpc_svr.c index 52f161e0a..e3a8637a0 100644 --- a/mkrtos_user/lib/sys_util/src/u_rpc_svr.c +++ b/mkrtos_user/lib/sys_util/src/u_rpc_svr.c @@ -48,6 +48,10 @@ static rpc_svr_obj_t *meta_svr_find(meta_t *meta, umword_t prot) pthread_spin_unlock(&meta->lock); return NULL; } +rpc_svr_obj_t *meta_find_svr_obj(umword_t prot) +{ + return meta_svr_find(&meta_obj, prot); +} void meta_unreg_svr_obj_raw(meta_t *meta, umword_t prot) { pthread_spin_lock(&meta->lock); @@ -82,6 +86,7 @@ int meta_reg_svr_obj_raw(meta_t *meta, rpc_svr_obj_t *svr_obj, umword_t prot) pthread_spin_unlock(&meta->lock); return i < META_PROT_NR; } + int meta_reg_svr_obj(rpc_svr_obj_t *svr_obj, umword_t prot) { return meta_reg_svr_obj_raw(&meta_obj, svr_obj, prot); @@ -185,14 +190,18 @@ void rpc_loop(void) continue; } svr_obj = (rpc_svr_obj_t *)obj; - if (svr_obj->dispatch) + if (svr_obj != NULL && svr_obj->dispatch) { tag = svr_obj->dispatch(svr_obj, tag, msg); } + else + { + tag = msg_tag_init4(0, 0, 0, -ENOSYS); + } thread_ipc_reply(tag, ipc_timeout_create2(0, 0)); } } - +#if 0 #define RPC_MTD_TH_STACK_SIZE (1024 + 256) typedef struct mtd_params { @@ -342,3 +351,4 @@ int rpc_mtd_loop(void) } return 0; } +#endif