其他进程能监听到其他进程信号
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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/
|
||||
|
||||
31
mkrtos_user/lib/letter-shell/demo/mkrtos/shell_test.c
Normal file
31
mkrtos_user/lib/letter-shell/demo/mkrtos/shell_test.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "shell.h"
|
||||
#include "cons_cli.h"
|
||||
#include "u_sig.h"
|
||||
#include "cons_cli.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
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);
|
||||
@@ -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(); //!< 强制退出
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "u_types.h"
|
||||
#include <sys/types.h>
|
||||
#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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
#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) //!< 通知消息
|
||||
@@ -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);
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "u_hd_man.h"
|
||||
#include "fs_svr.h"
|
||||
#include "pm_svr.h"
|
||||
#include "u_rpc_buf.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -46,6 +46,8 @@ static inline void rpc_memcpy(void *dst, void *src, size_t size)
|
||||
while (size--)
|
||||
{
|
||||
*_dst = *_src;
|
||||
_dst++;
|
||||
_src++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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); \
|
||||
|
||||
11
mkrtos_user/lib/sys_util/inc/u_sig.h
Normal file
11
mkrtos_user/lib/sys_util/inc/u_sig.h
Normal file
@@ -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);
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <pthread.h>
|
||||
|
||||
#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));
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
#include "u_thread.h"
|
||||
#include "u_util.h"
|
||||
#include <assert.h>
|
||||
#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++)
|
||||
{
|
||||
|
||||
75
mkrtos_user/lib/sys_util/src/u_sig.c
Normal file
75
mkrtos_user/lib/sys_util/src/u_sig.c
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
#include <u_thread_util.h>
|
||||
#include <u_util.h>
|
||||
#include <u_rpc_svr.h>
|
||||
#include <u_factory.h>
|
||||
#include <u_sleep.h>
|
||||
#include <u_sig.h>
|
||||
#include <pm_cli.h>
|
||||
#include <rpc_prot.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -11,11 +11,14 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#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)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
#一次读取一行,每行代表启动的应用程序,暂时不支持参数
|
||||
|
||||
# mr_drv
|
||||
# hello
|
||||
# rtthread_drv
|
||||
fatfs
|
||||
sh
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -12,11 +12,15 @@
|
||||
#include "u_app_loader.h"
|
||||
#include "u_env.h"
|
||||
#include "rpc_prot.h"
|
||||
#include <stdio.h>
|
||||
#include "cons_svr.h"
|
||||
#include "namespace.h"
|
||||
#include "u_task.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_sig.h"
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user