diff --git a/.vscode/settings.json b/.vscode/settings.json index d3bce78f6..cd7a5ccc7 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -272,7 +272,8 @@ "atomic": "c", "futex.h": "c", "u_rpc_buf.h": "c", - "pm_cli.h": "c" + "pm_cli.h": "c", + "u_sig.h": "c" }, "cortex-debug.showRTOS": false, "cortex-debug.variableUseNaturalFormat": false, diff --git a/mkrtos_knl/knl/thread.c b/mkrtos_knl/knl/thread.c index 4ae8c2801..5f3d6eef3 100755 --- a/mkrtos_knl/knl/thread.c +++ b/mkrtos_knl/knl/thread.c @@ -115,6 +115,7 @@ static void thread_release_stage1(kobject_t *kobj) { thread_suspend(th); } + th->ipc_status = THREAD_IPC_ABORT; } else { @@ -122,6 +123,7 @@ static void thread_release_stage1(kobject_t *kobj) { thread_suspend(th); } + cur->ipc_status = THREAD_IPC_ABORT; } thread_wait_entry_t *pos; @@ -505,8 +507,13 @@ static int thread_ipc_reply(msg_tag_t in_tag) cpulock_set(status); return -1; } - assert(cur_th->last_send_th->status == THREAD_SUSPEND); - assert(cur_th->last_send_th->ipc_status == THREAD_RECV); + if (cur_th->last_send_th->status != THREAD_SUSPEND && + cur_th->last_send_th->ipc_status != THREAD_RECV) + { + cur_th->last_send_th = NULL; + cpulock_set(status); + return -1; + } //!< 发送数据给上一次的发送者 int ret = ipc_data_copy(cur_th->last_send_th, cur_th, in_tag); //!< 拷贝数据 @@ -516,8 +523,11 @@ static int thread_ipc_reply(msg_tag_t in_tag) // return ret; in_tag.prot = ret; } + if (cur_th->last_send_th->ipc_status != THREAD_IPC_ABORT) + { + thread_ready(cur_th->last_send_th, TRUE); //!< 直接唤醒接受者 + } cur_th->last_send_th->msg.tag = in_tag; - thread_ready(cur_th->last_send_th, TRUE); //!< 直接唤醒接受者 ref_counter_dec_and_release(&cur_th->last_send_th->ref, &cur_th->last_send_th->kobj); cur_th->last_send_th = NULL; cpulock_set(status); @@ -716,7 +726,7 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id) ipc_timeout_t ipc_tm_out = ipc_timeout_create(f->r[3]); to_th->user_id = user_id; - ret = thread_ipc_call(to_th, in_tag, &recv_tag, ipc_tm_out, &f->r[1]); + ret = thread_ipc_send(to_th, in_tag, ipc_tm_out); return msg_tag_init4(0, 0, 0, ret); } default: diff --git a/mkrtos_user/lib/letter-shell/demo/mkrtos/CMakeLists.txt b/mkrtos_user/lib/letter-shell/demo/mkrtos/CMakeLists.txt index 9df368fb3..9b30933fd 100644 --- a/mkrtos_user/lib/letter-shell/demo/mkrtos/CMakeLists.txt +++ b/mkrtos_user/lib/letter-shell/demo/mkrtos/CMakeLists.txt @@ -11,6 +11,7 @@ add_library(LetterShell # main.c shell_port.c shell_fs_ext.c + shell_test.c # shell_cpp.cpp ../../src/shell.c ../../src/shell_companion.c @@ -40,6 +41,7 @@ target_include_directories(LetterShell PUBLIC ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_util/inc ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/util/inc ${CMAKE_SOURCE_DIR}/mkrtos_user/server/app/drv ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/arm/ diff --git a/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_test.c b/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_test.c new file mode 100644 index 000000000..a8cc85fc4 --- /dev/null +++ b/mkrtos_user/lib/letter-shell/demo/mkrtos/shell_test.c @@ -0,0 +1,31 @@ +#include "shell.h" +#include "cons_cli.h" +#include "u_sig.h" +#include "cons_cli.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +static int shell_sig_call_back(pid_t pid, umword_t sig_val) +{ + /*TODO:这个消息是init发送的,这里不能给init发送消息,否导致卡死*/ + // cons_write_str("test"); + return 0; +} +int shell_test_sig(int argc, char *argv[]) +{ + if (argc < 2) + { + return -1; + } + pm_sig_func_set(shell_sig_call_back); + pid_t pid = atoi(argv[1]); + + return pm_sig_watch(pid, 0 /*TODO:现在只有kill */); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), test_sig, shell_test_sig, shell_test_sig command); diff --git a/mkrtos_user/lib/libc_backend/src/sys_backend.c b/mkrtos_user/lib/libc_backend/src/sys_backend.c index e5381c270..0ace7558a 100644 --- a/mkrtos_user/lib/libc_backend/src/sys_backend.c +++ b/mkrtos_user/lib/libc_backend/src/sys_backend.c @@ -10,11 +10,14 @@ */ #include "u_ipc.h" +#include "u_types.h" #include "u_factory.h" #include "u_thread.h" #include "u_task.h" #include "u_hd_man.h" #include "u_log.h" +#include "pm_cli.h" +#include "u_sig.h" #include "futex_queue.h" #include "u_ipc.h" #include "u_sys.h" @@ -142,8 +145,12 @@ void be_exit(long exit_code) } else { + umword_t pid; del_task: /*TODO:删除其它东西*/ + + task_get_pid(TASK_THIS, &pid); + pm_kill_task(pid, KILL_SIG); task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); //!< 删除当前task,以及申请得所有对象 a_crash(); //!< 强制退出 } diff --git a/mkrtos_user/lib/mlibc/src/env/__libc_start_main.c b/mkrtos_user/lib/mlibc/src/env/__libc_start_main.c index 03cc4c752..419c57847 100644 --- a/mkrtos_user/lib/mlibc/src/env/__libc_start_main.c +++ b/mkrtos_user/lib/mlibc/src/env/__libc_start_main.c @@ -7,6 +7,7 @@ #include "atomic.h" #include "libc.h" #include "cons_cli.h" +#include "u_sig.h" static void dummy(void) {} weak_alias(dummy, _init); @@ -103,6 +104,7 @@ int __libc_start_main(int (*main)(int, char **, char **), int argc, char **argv, * persisting for the entire process lifetime. */ __init_libc(envp, argv[0]); // cons_active(); + sig_init(); /* Barrier against hoisting application code or anything using ssp * or thread pointer prior to its initialization above. */ diff --git a/mkrtos_user/lib/sys_svr/inc/pm_cli.h b/mkrtos_user/lib/sys_svr/inc/pm_cli.h index 46444ed44..43db4ffbd 100644 --- a/mkrtos_user/lib/sys_svr/inc/pm_cli.h +++ b/mkrtos_user/lib/sys_svr/inc/pm_cli.h @@ -1,6 +1,9 @@ #pragma once +#include "u_types.h" +#include #define PM_KILL_TASK_ALL 0x1 int pm_run_app(const char *path, int flags); int pm_kill_task(int pid, int flags); +int pm_watch_pid(obj_handler_t sig_hd, pid_t pid, int flags); diff --git a/mkrtos_user/lib/sys_svr/inc/pm_svr.h b/mkrtos_user/lib/sys_svr/inc/pm_svr.h index 624fdeb18..0c5c00dc4 100644 --- a/mkrtos_user/lib/sys_svr/inc/pm_svr.h +++ b/mkrtos_user/lib/sys_svr/inc/pm_svr.h @@ -11,10 +11,21 @@ #pragma once #include "u_rpc_svr.h" +#include "u_slist.h" +#include "u_types.h" +typedef struct watch_entry +{ + pid_t watch_pid; + pid_t src_pid; + obj_handler_t sig_hd; + int flags; + slist_head_t node; +} watch_entry_t; typedef struct pm { rpc_svr_obj_t svr_obj; + slist_head_t watch_head; } pm_t; #define PM_APP_BG_RUN 0x1 @@ -22,3 +33,4 @@ typedef struct pm void pm_svr_obj_init(pm_t *pm); int pm_rpc_run_app(const char *path, int flags); int pm_rpc_kill_task(int pid, int flags); +int pm_rpc_watch_pid(pm_t *pm, obj_handler_t sig_rcv_hd, pid_t pid, int flags); diff --git a/mkrtos_user/lib/sys_svr/inc/rpc_prot.h b/mkrtos_user/lib/sys_svr/inc/rpc_prot.h index e3425b4b0..649b59f5c 100644 --- a/mkrtos_user/lib/sys_svr/inc/rpc_prot.h +++ b/mkrtos_user/lib/sys_svr/inc/rpc_prot.h @@ -38,8 +38,12 @@ #define PM_PROT 0x0005 //!< 进程管理协议 #define PM_RUN_APP ((uint16_t)0) //!< 启动应用程序 #define PM_KILL_TASK ((uint16_t)1) //!< 删除进程 +#define PM_WATCH_PID ((uint16_t)2) //!< watch pid -#define CONS_PROT 0x0006 -#define CONS_WRITE ((uint16_t)0) -#define CONS_READ ((uint16_t)1) -#define CONS_ACTIVE ((uint16_t)2) \ No newline at end of file +#define CONS_PROT 0x0006 //!< console协议 +#define CONS_WRITE ((uint16_t)0) //!< console删除 +#define CONS_READ ((uint16_t)1) //!< console读 +#define CONS_ACTIVE ((uint16_t)2) //!< console激活 + +#define PM_SIG_PROT 0x0007 //!< pm信号协议 +#define PM_SIG_NOTIFY ((uint16_t)0) //!< 通知消息 \ No newline at end of file diff --git a/mkrtos_user/lib/sys_svr/src/pm_cli.c b/mkrtos_user/lib/sys_svr/src/pm_cli.c index 500c0feb7..f038a4476 100644 --- a/mkrtos_user/lib/sys_svr/src/pm_cli.c +++ b/mkrtos_user/lib/sys_svr/src/pm_cli.c @@ -27,9 +27,119 @@ int pm_run_app(const char *path, int flags) return msg_tag_get_val(tag); } -RPC_GENERATION_CALL2(pm_t, PM_PROT, PM_KILL_TASK, kill_task, - rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, pid, - rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags) +// RPC_GENERATION_CALL2(pm_t, PM_PROT, PM_KILL_TASK, kill_task, +// rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, pid, +// rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags) +msg_tag_t pm_t_kill_task_call(obj_handler_t hd, rpc_int_t *var0, rpc_int_t *var1) +{ + void *buf; + ipc_msg_t *msg_ipc; + thread_msg_buf_get(2, (umword_t *)(&buf), ((void *)0)); + msg_ipc = (ipc_msg_t *)buf; + int off = 0; + int off_buf = 0; + int ret = -1; + size_t op_val = ((uint16_t)1); + rpc_memcpy(msg_ipc->msg_buf, &op_val, sizeof(op_val)); + off += rpc_align(sizeof(op_val), __alignof(((uint16_t)1))); + do + { + if (1 == 1) + { + if (1 == 1 || 1 == 4) + { + int ret = rpc_cli_msg_to_buf_rpc_int_t(var0, (uint8_t *)((uint8_t *)msg_ipc->msg_buf), off); + if (ret < 0) + { + return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)}); + } + off = ret; + } + } + } while (0); + do + { + if (1 == 2) + { + if (1 == 1 || 1 == 4) + { + int ret = rpc_cli_msg_to_buf_rpc_int_t(var0, (uint8_t *)((uint8_t *)msg_ipc->map_buf), off_buf); + if (ret < 0) + { + return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)}); + } + off_buf = ret; + } + } + } while (0); + do + { + if (1 == 1) + { + if (1 == 1 || 1 == 4) + { + int ret = rpc_cli_msg_to_buf_rpc_int_t(var1, (uint8_t *)((uint8_t *)msg_ipc->msg_buf), off); + if (ret < 0) + { + return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)}); + } + off = ret; + } + } + } while (0); + do + { + if (1 == 2) + { + if (1 == 1 || 1 == 4) + { + int ret = rpc_cli_msg_to_buf_rpc_int_t(var1, (uint8_t *)((uint8_t *)msg_ipc->map_buf), off_buf); + if (ret < 0) + { + return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)}); + } + off_buf = ret; + } + } + } while (0); + msg_tag_t tag = thread_ipc_call(((msg_tag_t){.flags = (0), .msg_buf_len = ((((off) / ((sizeof(void *)))) + (((off) % ((sizeof(void *)))) ? 1 : 0))), .map_buf_len = ((((off_buf) / ((sizeof(void *)))) + (((off_buf) % ((sizeof(void *)))) ? 1 : 0))), .prot = (0x0005)}), hd, ipc_timeout_create2(0, 0)); + if (((int16_t)((tag).prot)) < 0) + { + return tag; + } + off = 0; + do + { + if (1 == 1) + { + if (1 == 2 || 1 == 4) + { + int ret = rpc_cli_buf_to_msg_rpc_int_t(var0, (uint8_t *)((uint8_t *)msg_ipc->msg_buf), off, tag.msg_buf_len * (sizeof(void *))); + if (ret < 0) + { + return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)}); + } + off = ret; + } + } + } while (0); + do + { + if (1 == 1) + { + if (1 == 2 || 1 == 4) + { + int ret = rpc_cli_buf_to_msg_rpc_int_t(var1, (uint8_t *)((uint8_t *)msg_ipc->msg_buf), off, tag.msg_buf_len * (sizeof(void *))); + if (ret < 0) + { + return ((msg_tag_t){.flags = (0), .msg_buf_len = (0), .map_buf_len = (0), .prot = (ret)}); + } + off = ret; + } + } + } while (0); + return tag; +} int pm_kill_task(int pid, int flags) { rpc_int_t rpc_pid = { @@ -42,3 +152,23 @@ int pm_kill_task(int pid, int flags) return msg_tag_get_val(tag); } +RPC_GENERATION_CALL3(pm_t, PM_PROT, PM_WATCH_PID, watch_pid, + rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, sig_hd, + rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, pid, + rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags) +int pm_watch_pid(obj_handler_t sig_hd, pid_t pid, int flags) +{ + rpc_obj_handler_t_t rpc_sig_hd = { + .data = sig_hd, + }; + rpc_umword_t_t rpc_pid = { + .data = pid, + }; + rpc_int_t rpc_flags = { + .data = flags, + }; + + msg_tag_t tag = pm_t_watch_pid_call(u_get_global_env()->ns_hd, &rpc_sig_hd, &rpc_pid, &rpc_flags); + + return msg_tag_get_val(tag); +} \ No newline at end of file diff --git a/mkrtos_user/lib/sys_svr/src/pm_svr.c b/mkrtos_user/lib/sys_svr/src/pm_svr.c index 5e93f701c..61b317dd7 100644 --- a/mkrtos_user/lib/sys_svr/src/pm_svr.c +++ b/mkrtos_user/lib/sys_svr/src/pm_svr.c @@ -14,6 +14,7 @@ #include "u_hd_man.h" #include "fs_svr.h" #include "pm_svr.h" +#include "u_rpc_buf.h" #include /*run_app*/ @@ -44,10 +45,28 @@ RPC_GENERATION_OP2(pm_t, PM_PROT, PM_KILL_TASK, kill_task, RPC_GENERATION_DISPATCH2(pm_t, PM_PROT, PM_KILL_TASK, kill_task, rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, pid, rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags) + +/*watch pid*/ +RPC_GENERATION_OP3(pm_t, PM_PROT, PM_WATCH_PID, watch_pid, + rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, sig_hd, + rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, pid, + rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags) +{ + int16_t ret = 0; + + ret = pm_rpc_watch_pid(obj, rpc_hd_get(0), pid->data, flags->data); + return ret; +} + +RPC_GENERATION_DISPATCH3(pm_t, PM_PROT, PM_WATCH_PID, watch_pid, + rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, sig_hd, + rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, pid, + rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags) /*dispatch*/ -RPC_DISPATCH2(pm_t, PM_PROT, typeof(PM_RUN_APP), PM_RUN_APP, run_app, PM_KILL_TASK, kill_task) +RPC_DISPATCH3(pm_t, PM_PROT, typeof(PM_RUN_APP), PM_RUN_APP, run_app, PM_KILL_TASK, kill_task, PM_WATCH_PID, watch_pid) void pm_svr_obj_init(pm_t *pm) { rpc_svr_obj_init(&pm->svr_obj, rpc_pm_t_dispatch, PM_PROT); + slist_init(&pm->watch_head); } diff --git a/mkrtos_user/lib/sys_util/inc/u_hd_man.h b/mkrtos_user/lib/sys_util/inc/u_hd_man.h index 11b8f49ac..1f9d48b6d 100644 --- a/mkrtos_user/lib/sys_util/inc/u_hd_man.h +++ b/mkrtos_user/lib/sys_util/inc/u_hd_man.h @@ -6,5 +6,6 @@ obj_handler_t handler_alloc(void); void handler_free(obj_handler_t hd_inx); void handler_free_umap(obj_handler_t hd_inx); +void handler_del_umap(obj_handler_t hd_inx); void hanlder_pre_alloc(obj_handler_t inx); bool_t handler_is_used(obj_handler_t hd_inx); diff --git a/mkrtos_user/lib/sys_util/inc/u_rpc.h b/mkrtos_user/lib/sys_util/inc/u_rpc.h index 221c15598..ca6b6d0d3 100644 --- a/mkrtos_user/lib/sys_util/inc/u_rpc.h +++ b/mkrtos_user/lib/sys_util/inc/u_rpc.h @@ -46,6 +46,8 @@ static inline void rpc_memcpy(void *dst, void *src, size_t size) while (size--) { *_dst = *_src; + _dst++; + _src++; } } diff --git a/mkrtos_user/lib/sys_util/inc/u_rpc_3.h b/mkrtos_user/lib/sys_util/inc/u_rpc_3.h index fe22f463a..9c51ce957 100644 --- a/mkrtos_user/lib/sys_util/inc/u_rpc_3.h +++ b/mkrtos_user/lib/sys_util/inc/u_rpc_3.h @@ -25,7 +25,7 @@ int ret = -1; \ size_t op_val = op; \ /*拷贝op*/ \ - rpc_memcpy(msg_ipc->msg_buf, &op_val, sizeof(op_val)); \ + rpc_memcpy(msg_ipc->msg_buf, &op_val, __alignof(op_val)); \ off += rpc_align(sizeof(op_val), __alignof(op)); \ \ RPC_CLI_MSG_TO_BUF_IN(rpc_type0, cli_type0, var0, dir0, (uint8_t *)msg_ipc->msg_buf, off); \ diff --git a/mkrtos_user/lib/sys_util/inc/u_sig.h b/mkrtos_user/lib/sys_util/inc/u_sig.h new file mode 100644 index 000000000..c08deaa7b --- /dev/null +++ b/mkrtos_user/lib/sys_util/inc/u_sig.h @@ -0,0 +1,11 @@ +#pragma once + +enum signal_val +{ + KILL_SIG, +}; +typedef int (*sig_call_back)(pid_t pid, umword_t sig_val); + +void sig_init(void); +int pm_sig_watch(pid_t pid, int flags); +void pm_sig_func_set(sig_call_back sig_func); diff --git a/mkrtos_user/lib/sys_util/src/u_hd_man.c b/mkrtos_user/lib/sys_util/src/u_hd_man.c index b3145df5a..278ca2955 100644 --- a/mkrtos_user/lib/sys_util/src/u_hd_man.c +++ b/mkrtos_user/lib/sys_util/src/u_hd_man.c @@ -7,7 +7,7 @@ #include #define HANDLER_START_INX 10 //!< fd开始的值,前10个内核保留 -#define HANDLER_MAX_NR 96 //!< 单个task最大支持的hd数量 +#define HANDLER_MAX_NR 96 //!< 单个task最大支持的hd数量 static umword_t bitmap_handler_alloc[HANDLER_MAX_NR / WORD_BITS]; static pthread_spinlock_t lock; @@ -100,3 +100,13 @@ void handler_free_umap(obj_handler_t hd_inx) handler_free(hd_inx); task_unmap(TASK_THIS, vpage_create_raw3(0, 0, hd_inx)); } +/** + * @brief 删除用户态的hd,并从内核中删除 + * + * @param hd_inx + */ +void handler_del_umap(obj_handler_t hd_inx) +{ + handler_free(hd_inx); + task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, hd_inx)); +} diff --git a/mkrtos_user/lib/sys_util/src/u_rpc_buf.c b/mkrtos_user/lib/sys_util/src/u_rpc_buf.c index ddfddbc44..e26f80c09 100644 --- a/mkrtos_user/lib/sys_util/src/u_rpc_buf.c +++ b/mkrtos_user/lib/sys_util/src/u_rpc_buf.c @@ -6,10 +6,11 @@ #include "u_thread.h" #include "u_util.h" #include -#define RPC_SVR_MAP_OBJ_NR 4 +#define RPC_SVR_MAP_OBJ_NR (MAP_BUF_SIZE / sizeof(umword_t)) static obj_handler_t buf_hd[RPC_SVR_MAP_OBJ_NR]; -AUTO_CALL(101) void rpc_hd_init(void) +AUTO_CALL(101) +void rpc_hd_init(void) { for (int i = 0; i < RPC_SVR_MAP_OBJ_NR; i++) { diff --git a/mkrtos_user/lib/sys_util/src/u_sig.c b/mkrtos_user/lib/sys_util/src/u_sig.c new file mode 100644 index 000000000..4ce197b79 --- /dev/null +++ b/mkrtos_user/lib/sys_util/src/u_sig.c @@ -0,0 +1,75 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static sig_call_back sig_cb_func; +static ATTR_ALIGN(8) uint8_t sig_stack[1024]; +static uint8_t sig_msg_buf[MSG_BUG_LEN]; +static obj_handler_t sig_th; +static obj_handler_t sig_ipc; +static uint8_t sig_init_flags; + +int pm_sig_watch(pid_t pid, int flags) +{ + int ret = pm_watch_pid(sig_ipc, pid, flags); + + return ret; +} + +void pm_sig_func_set(sig_call_back sig_func) +{ + sig_cb_func = sig_func; +} + +/** + * @brief 信号的回调函数 + * + */ +static void sig_func(void) +{ + assert(rpc_creaite_bind_ipc(sig_th, NULL, &sig_ipc) >= 0); + + while (1) + { + msg_tag_t tag = thread_ipc_wait(ipc_timeout_create2(0, 0), NULL); + if (msg_tag_get_val(tag) < 0) + { + continue; + } + int ret = 0; + ipc_msg_t *ipc = (ipc_msg_t *)sig_msg_buf; + + switch (ipc->msg_buf[0]) + { + case PM_SIG_NOTIFY: + if (sig_cb_func) + { + ret = sig_cb_func(ipc->msg_buf[2], ipc->msg_buf[1]); + tag = msg_tag_init4(0, 0, 0, ret); + } + break; + } + thread_ipc_reply(tag, ipc_timeout_create2(0, 0)); + } + while (1) + { + u_sleep_ms(1000); + } +} +void sig_init(void) +{ + if (sig_init_flags) + { + return; + } + u_thread_create(&sig_th, sig_stack, sizeof(sig_stack), sig_msg_buf, sig_func); + u_thread_run(sig_th, 3); +} diff --git a/mkrtos_user/server/fs/fatfs/fs_rpc.c b/mkrtos_user/server/fs/fatfs/fs_rpc.c index 6372b8117..ce262042a 100644 --- a/mkrtos_user/server/fs/fatfs/fs_rpc.c +++ b/mkrtos_user/server/fs/fatfs/fs_rpc.c @@ -11,11 +11,14 @@ #include #include #include "rpc_prot.h" +#include "u_sig.h" static fs_t fs; +static int fs_sig_call_back(pid_t pid, umword_t sig_val); void fs_svr_init(void) { fs_init(&fs); meta_reg_svr_obj(&fs.svr, FS_PROT); + pm_sig_func_set(fs_sig_call_back); } typedef struct file_desc { @@ -24,12 +27,37 @@ typedef struct file_desc FIL fp; FATFS_DIR dir; }; + pid_t pid; uint8_t type; //!< 0:file 1:dir } file_desc_t; #define FILE_DESC_NR 8 //!< 最多同时可以打开多少个文件 static file_desc_t files[FILE_DESC_NR]; //!< 预先设置的文件描述符 +static void free_fd(pid_t pid) +{ + for (int i = 0; i < FILE_DESC_NR; i++) + { + if (files[i].fp.obj.fs) + { + fs_svr_close(i); + files[i].fp.obj.fs = NULL; + files[i].pid = 0; + } + } +} + +static int fs_sig_call_back(pid_t pid, umword_t sig_val) +{ + switch (sig_val) + { + case KILL_SIG: + free_fd(pid); + break; + } + return 0; +} + static file_desc_t *alloc_file(int *fd) { for (int i = 0; i < FILE_DESC_NR; i++) @@ -37,6 +65,7 @@ static file_desc_t *alloc_file(int *fd) if (files[i].fp.obj.fs == NULL) { *fd = i; + files[i].pid = thread_get_src_pid(); return &files[i]; } } @@ -92,6 +121,7 @@ int fs_svr_open(const char *path, int flags, int mode) { // printf("open %s.\n", path); int fd; + pid_t pid = thread_get_src_pid(); file_desc_t *file = alloc_file(&fd); if (!file) @@ -154,6 +184,11 @@ int fs_svr_open(const char *path, int flags, int mode) { return fatfs_err_conv(ret); } + int w_ret = pm_sig_watch(pid, 0 /*TODO:现在只有kill */); + if (w_ret < 0) + { + printf("pm wath pid %d err.\n", w_ret); + } return fd; } @@ -216,6 +251,7 @@ void fs_svr_close(int fd) f_closedir(&file->dir); break; } + file->fp.obj.fs = NULL; } int fs_svr_lseek(int fd, int offs, int whence) { diff --git a/mkrtos_user/server/init/src/init.cfg b/mkrtos_user/server/init/src/init.cfg index bdb173d51..0fdc128ba 100644 --- a/mkrtos_user/server/init/src/init.cfg +++ b/mkrtos_user/server/init/src/init.cfg @@ -1,7 +1,4 @@ #一次读取一行,每行代表启动的应用程序,暂时不支持参数 -# mr_drv -# hello -# rtthread_drv fatfs sh diff --git a/mkrtos_user/server/init/src/namespace.c b/mkrtos_user/server/init/src/namespace.c index 62fe3c857..f33ca6c3f 100644 --- a/mkrtos_user/server/init/src/namespace.c +++ b/mkrtos_user/server/init/src/namespace.c @@ -181,9 +181,9 @@ static ns_node_t *node_lookup(ns_node_t *dir, const char *name, size_t *ret_inx) { return dir; } + node = dir; if (name[0] == '/') { - node = dir; find_inx++; r_inx++; find = TRUE; diff --git a/mkrtos_user/server/init/src/pm.c b/mkrtos_user/server/init/src/pm.c index 2988b90f4..a37ef2812 100644 --- a/mkrtos_user/server/init/src/pm.c +++ b/mkrtos_user/server/init/src/pm.c @@ -12,11 +12,15 @@ #include "u_app_loader.h" #include "u_env.h" #include "rpc_prot.h" -#include #include "cons_svr.h" #include "namespace.h" #include "u_task.h" +#include "u_hd_man.h" +#include "u_sig.h" #include +#include +#include +#include static pm_t pm; void pm_init(void) @@ -25,34 +29,180 @@ void pm_init(void) meta_reg_svr_obj(&pm.svr_obj, PM_PROT); printf("pm runing..\n"); } -int pm_rpc_kill_task(int pid, int flags) +/** + * @brief pid值是不是一个task + * + * @param pid + * @return bool_t + */ +bool_t pm_pid_is_task(pid_t pid) { int obj_type; - msg_tag_t tag; + msg_tag_t tag = task_obj_valid(TASK_THIS, pid, &obj_type); + if (msg_tag_get_val(tag) < 0) + { + return FALSE; + } + if (msg_tag_get_val(tag) == 0) + { + return FALSE; + } + if (obj_type != TASK_TYPE) + { + return FALSE; + } + return TRUE; +} +/** + * @brief 查找某个观察项 + * + * @param pm + * @param pid + * @return watch_entry_t* + */ +watch_entry_t *pm_watch_lookup(pm_t *pm, pid_t pid) +{ + watch_entry_t *pos; + slist_foreach_not_next(pos, &pm->watch_head, node) + { + watch_entry_t *next = slist_next_entry(pos, &pm->watch_head, node); + if (pos->src_pid == pid) + { + return pos; + } + pos = next; + } + return NULL; +} +/** + * @brief 删除某个监听者 + * + * @param pm + * @param pid 要删除的pid + */ +void pm_del_watch_by_pid(pm_t *pm, pid_t pid) +{ + watch_entry_t *pos; + + slist_foreach_not_next(pos, &pm->watch_head, node) + { + watch_entry_t *next = slist_next_entry(pos, &pm->watch_head, node); + if (pos->src_pid == pid) + { + slist_del(&pos->node); + { + handler_free_umap(pos->sig_hd); + } + free(pos); + } + pos = next; + } +} +/** + * @brief 源pid监听某个pid的状态 + * + * @param pid 被监听的状态 + * @param flags 监听的flags + * @return int >=0 success <0 fail + */ +int pm_rpc_watch_pid(pm_t *pm, obj_handler_t sig_rcv_hd, pid_t pid, int flags) +{ + pid_t src_pid = thread_get_src_pid(); + + if (pm_pid_is_task(src_pid) == FALSE) + { + return -EINVAL; + } + if (pm_watch_lookup(pm, src_pid)) + { + handler_free_umap(sig_rcv_hd); + return -EEXIST; + } + watch_entry_t *entry = (watch_entry_t *)malloc(sizeof(watch_entry_t)); + + if (!entry) + { + handler_free_umap(sig_rcv_hd); + return -ENOMEM; + } + + entry->sig_hd = sig_rcv_hd; + entry->src_pid = src_pid; + entry->watch_pid = pid; + entry->flags = flags; + slist_init(&entry->node); + slist_add_append(&pm->watch_head, &entry->node); + printf("[pm] watch pid:%d, sig hd:%d.\n", src_pid, sig_rcv_hd); + return 0; +} +/** + * @brief pm给task的信号线程发送消息 + * + * @param pm + * @param pid + * @return bool_t + */ +static bool_t pm_send_sig_to_task(pm_t *pm, pid_t pid, umword_t sig_val) +{ + ipc_msg_t *ipc; + watch_entry_t *pos; + + ipc = thread_get_cur_ipc_msg(); + assert(ipc); + + slist_foreach_not_next(pos, &pm->watch_head, node) + { + watch_entry_t *next = slist_next_entry(pos, &pm->watch_head, node); + + if (pos->watch_pid == pid) + { + if (sig_val == KILL_SIG) + { + ipc->msg_buf[0] = PM_SIG_NOTIFY; + ipc->msg_buf[1] = sig_val; + ipc->msg_buf[2] = pid; + + thread_ipc_call(msg_tag_init4(0, 3, 0, PM_SIG_PROT), pos->sig_hd, + ipc_timeout_create2(0, 0)); + } + slist_del(&pos->node); + } + pos = next; + } +} +/** + * @brief 杀死某个进程 + * + * @param pid + * @param flags + * @return int + */ +int pm_rpc_kill_task(int pid, int flags) +{ if (pid == TASK_THIS) { return -EINVAL; } + if (pm_pid_is_task(pid) == FALSE) + { + return -EINVAL; + } - tag = task_obj_valid(TASK_THIS, pid, &obj_type); - if (msg_tag_get_val(tag) < 0) - { - return msg_tag_get_val(tag); - } - if (msg_tag_get_val(tag) == 0) - { - return -1; - } - if (obj_type != TASK_TYPE) - { - return -1; - } printf("[pm] kill pid:%d.\n", pid); - ns_node_del_by_pid(pid, flags); + ns_node_del_by_pid(pid, flags); //!< 从ns中删除 + pm_del_watch_by_pid(&pm, pid); //!< 从watch中删除 + pm_send_sig_to_task(&pm, pid, KILL_SIG); //!< 给watch者发送sig task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, pid)); return 0; } +/** + * @brief 运行一个新的app + * + * @param path + * @param flags + * @return int + */ int pm_rpc_run_app(const char *path, int flags) { pid_t pid;