tty支持&vi完整支持

This commit is contained in:
zhangzheng
2025-03-09 00:21:55 +08:00
parent 567f6ae529
commit cff255baf2
53 changed files with 1793 additions and 467 deletions

View File

@@ -14,6 +14,7 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
int ls(int argc, char *agrv[])
{
DIR *dir;
@@ -117,7 +118,7 @@ int cat(int argc, char *argv[])
while ((c = fgetc(fp)) != EOF)
{
cons_write((uint8_t *)&c, 1);
write(STDOUT_FILENO, (uint8_t *)&c, 1);
}
fclose(fp);
@@ -178,8 +179,7 @@ int shell_symlink(int argc, char *argv[])
return symlink(argv[1], argv[2]);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), symlink, shell_symlink, symlink command);
#include <unistd.h>
#include <fcntl.h>
int shell_touch(int argc, char *argv[])
{
if (argc < 2)

View File

@@ -23,6 +23,10 @@
#include <string.h>
#include <sys/time.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/types.h>
#include <termios.h>
#include <sys/stat.h>
#include "cons_cli.h"
#include "u_sleep.h"
#include "u_sema.h"
@@ -41,8 +45,7 @@ static char shellBuffer[512];
* @return unsigned short 写入实际长度
*/
signed short userShellWrite(char *data, unsigned short len)
{
return cons_write((const char *)data, len);
{ return write(STDOUT_FILENO, data, len);
}
/**
@@ -57,13 +60,7 @@ signed short userShellRead(char *data, unsigned short len)
{
int rlen;
again:
rlen = cons_read((uint8_t *)data, len);
if (rlen <= 0)
{
u_sema_down(SEMA_PROT, 0, NULL);
goto again;
}
rlen = read(STDIN_FILENO, data, len);
return rlen;
}
/**
@@ -98,12 +95,29 @@ size_t userShellListDir(char *path, char *buffer, size_t maxLen)
closedir(dir);
return 0;
}
static struct termios old_settings;
static struct termios new_settings;
void tty_set_raw_mode(void)
{
new_settings = old_settings;
new_settings.c_lflag &= ~(ICANON | ECHO); // 禁用规范模式和回显
new_settings.c_cc[VMIN] = 1; // 读取的最小字符数
new_settings.c_cc[VTIME] = 0; // 读取的超时时间以10ms为单位
tcsetattr(STDIN_FILENO, TCSANOW, &new_settings);
}
void tty_set_normal_mode(void)
{
tcsetattr(STDIN_FILENO, TCSANOW, &old_settings);
}
/**
* @brief 用户shell初始化
*
*/
void userShellInit(void)
{
tcgetattr(STDIN_FILENO, &old_settings);
tty_set_raw_mode();
task_set_obj_name(TASK_THIS, TASK_THIS, "tk_shell");
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_shell");
// shellFs.getcwd = getcwd;

View File

@@ -15,6 +15,9 @@
#include "stdarg.h"
#include "shell_ext.h"
#include "fs_types.h"
#include "u_sig.h"
#include <termios.h>
#include <unistd.h>
#if SHELL_USING_CMD_EXPORT == 1
/**
* @brief 默认用户
@@ -234,7 +237,7 @@ void shellInit(Shell *shell, char *buffer, unsigned short size)
else if (cmd->attr.attrs.type <= SHELL_TYPE_KEY)
{
cmd->data.key.desc += start_addr;
cmd->data.key.function = (void*)(int (*)())((unsigned long)cmd->data.key.function + start_addr | 0x1);
cmd->data.key.function = (void *)(int (*)())((unsigned long)cmd->data.key.function + start_addr | 0x1);
}
}
#endif
@@ -1454,6 +1457,7 @@ void shellExec(Shell *shell)
{
uint8_t params[FS_RPC_BUF_LEN];
int params_len = 0;
int pid;
for (int i = 1; i < shell->parser.paramCount; i++)
{
@@ -1461,10 +1465,31 @@ void shellExec(Shell *shell)
params_len += strlen(shell->parser.param[i]) + 1;
}
//!< 内建命令中未找到,则执行应用
if (pm_run_app(shell->parser.param[0], PM_APP_BG_RUN/*PM_APP_BG_RUN*/, params, params_len) < 0)
pid = pm_run_app(shell->parser.param[0], 0 /*PM_APP_BG_RUN*/, params, params_len);
if (pid < 0)
{
shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]);
}
else
{
pid_t cur_pid;
if (strcmp(shell->parser.param[shell->parser.paramCount - 1], "&") != 0)
{
shell->parser.param[shell->parser.paramCount - 1] = NULL;
shell->parser.paramCount--;
task_get_pid(TASK_THIS, &cur_pid);
pm_sig_watch(pid, 0);
extern void tty_set_raw_mode(void);
extern void tty_set_normal_mode(void);
tty_set_normal_mode();
tcsetpgrp(STDIN_FILENO, pid);
pm_waitpid(pid, NULL);
tcsetpgrp(STDIN_FILENO, cur_pid);
tty_set_raw_mode();
}
}
}
}
else

View File

@@ -25,9 +25,24 @@
AUTO_CALL(101)
void fs_backend_init(void)
{
assert(fd_map_alloc(0, 0, FD_TTY) >= 0);
assert(fd_map_alloc(0, 1, FD_TTY) >= 0);
assert(fd_map_alloc(0, 2, FD_TTY) >= 0);
umword_t cur_pid;
msg_tag_t tag;
tag = task_get_pid(TASK_THIS, (umword_t *)(&cur_pid));
assert(msg_tag_get_val(tag) >= 0);
if (cur_pid != 0)
{
assert(be_open("/dev/tty", O_RDWR, 0) >= 0);
assert(be_open("/dev/tty", O_RDWR, 0) >= 0);
assert(be_open("/dev/tty", O_RDWR, 0) >= 0);
}
else
{
assert(fd_map_alloc(0, 0, FD_TTY) >= 0);
assert(fd_map_alloc(0, 1, FD_TTY) >= 0);
assert(fd_map_alloc(0, 2, FD_TTY) >= 0);
}
}
#define FS_PATH_LEN 64
static char cur_path[FS_PATH_LEN] = "/";
@@ -491,21 +506,25 @@ long be_poll(struct pollfd *fds, nfds_t n, int timeout)
if (fds[0].fd >= 3)
{
/*TODO:暂时只支持TTY*/
return -1;
return -ENOSYS;
}
/*FIXME:性能优化*/
if (fds[0].events & POLLIN)
{
char buf;
int len;
int ret;
int time = 0;
if (timeout == -1)
{
// u_sema_down(SEMA_PROT);
again1:
len = cons_read(&buf, 0);
if (len <= 0)
ret = ioctl(fds[0].fd, FIONREAD, &len);
if (ret < 0)
{
return ret;
}
if (len == 0)
{
u_sleep_ms(1);
goto again1;
@@ -515,8 +534,12 @@ long be_poll(struct pollfd *fds, nfds_t n, int timeout)
else
{
again:
len = cons_read(&buf, 0);
if (len <= 0)
ret = ioctl(fds[0].fd, FIONREAD, &len);
if (ret < 0)
{
return ret;
}
if (len == 0)
{
u_sleep_ms(1);
time++;

View File

@@ -12,7 +12,7 @@ typedef struct cons
rpc_svr_obj_t svr;
queue_t r_queue;
uint8_t r_data[CONS_WRITE_BUF_SIZE];
pthread_spinlock_t r_lock;
// pthread_spinlock_t r_lock;
// pthread_mutex_t w_lock;
pid_t active_pid;
obj_handler_t hd_cons_read;

View File

@@ -2,6 +2,7 @@
#include <stddef.h>
#include <dirent.h>
#include <poll.h>
#include <u_types.h>
#include <u_rpc.h>
sd_t fs_open(const char *path, int flags, int mode);
@@ -23,3 +24,4 @@ int fs_rename(char *old, char *new);
int fs_stat(char *path, void *buf);
int fs_readlink(const char *path, char *buf, int bufsize);
int fs_statfs(const char *path, statfs_t *buf);
int fs_poll(struct pollfd *fds, nfds_t n, int timeout);

View File

@@ -4,7 +4,8 @@
#include "u_rpc_svr.h"
#include "u_types.h"
typedef struct fs_operations {
typedef struct fs_operations
{
int (*fs_svr_open)(const char *path, int flags, int mode);
int (*fs_svr_read)(int fd, void *buf, size_t len);
int (*fs_svr_write)(int fd, void *buf, size_t len);
@@ -24,11 +25,13 @@ typedef struct fs_operations {
int (*fs_svr_stat)(const char *path, void *buf);
ssize_t (*fs_svr_readlink)(const char *path, char *buf, size_t bufsize);
int (*fs_svr_statfs)(const char *path, struct statfs *buf);
//select
//poll
int (*fs_svr_poll)(/*struct pollfd*/ void *fds, unsigned long n, int timeout);
// select
// poll
} fs_operations_t;
typedef struct fs {
typedef struct fs
{
rpc_svr_obj_t svr;
const fs_operations_t *op;
} fs_t;

View File

@@ -16,11 +16,14 @@
#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;
pid_t watch_pid;//!<被监控的pid
pid_t src_pid; //!<发起监控的pid
obj_handler_t sig_hd; //!<用于通信用的ipc对象
#if 0
obj_handler_t notify_sem_hd;//!<通知用的信号量
#endif
int flags; //!<暂时没有用到
slist_head_t node;//!<双向链表串联起来
} watch_entry_t;
typedef struct pm
@@ -33,7 +36,8 @@ typedef struct pm
void pm_svr_obj_init(pm_t *pm);
int pm_rpc_run_app(const char *path, int flags, char *params, int params_len);
int pm_rpc_kill_task(int pid, int flags, int exit_code);
int pm_rpc_kill_task(int src_pid, int pid, int flags, int exit_code);
int pm_rpc_watch_pid(pm_t *pm, obj_handler_t sig_rcv_hd, pid_t pid, int flags);
int pm_rpc_copy_data(pid_t src_pid, pid_t dst_pid, umword_t src_addr, umword_t dst_addr, size_t len);
int pm_rpc_del_watch_pid(pm_t *pm, pid_t pid, int flags);

View File

@@ -25,6 +25,7 @@
#define FS_STAT ((umword_t)16) //!< 获取文件状态
#define FS_READLINK ((umword_t)17)
#define FS_STATFS ((umword_t)18) //!< 文件系统状态
#define FS_POLL ((umword_t)19) //!< poll命令
#define DRV_PROT 0x0003
#define DRV_OPEN ((umword_t)0) //!< 打开设备
@@ -35,14 +36,13 @@
#define META_PROT 0x0004 //!< 元协议
#define PM_PROT 0x0005 //!< 进程管理协议
#define PM_RUN_APP ((umword_t)0) //!< 启动应用程序
#define PM_KILL_TASK ((umword_t)1) //!< 删除进程
#define PM_WATCH_PID ((umword_t)2) //!< watch pid
#define PM_COPY_DATA ((umword_t)3) //!< copy 进程数据
#define PM_PROT 0x0005 //!< 进程管理协议
#define PM_RUN_APP ((umword_t)0) //!< 启动应用程序
#define PM_KILL_TASK ((umword_t)1) //!< 删除进程
#define PM_WATCH_PID ((umword_t)2) //!< watch pid
#define PM_COPY_DATA ((umword_t)3) //!< copy 进程数据
#define PM_DEL_WATCH_PID ((umword_t)4) //!< watch pid
#define CONS_PROT 0x0006 //!< console协议
#define CONS_WRITE ((umword_t)0) //!< console删除
#define CONS_READ ((umword_t)1) //!< console读

View File

@@ -55,6 +55,6 @@ void cons_svr_obj_init(cons_t *cons)
rpc_svr_obj_init(&cons->svr, rpc_cons_t_dispatch, CONS_PROT);
cons->active_pid = -1;
q_init(&cons->r_queue, cons->r_data, CONS_WRITE_BUF_SIZE);
pthread_spin_init(&cons->r_lock, 0);
// pthread_spin_init(&cons->r_lock, 0);
// pthread_mutex_init(&cons->w_lock, NULL);
}

View File

@@ -12,6 +12,7 @@
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <poll.h>
#include "kstat.h"
typedef struct kstat kstat_t;
RPC_TYPE_DEF_ALL(kstat_t)
@@ -598,3 +599,36 @@ int fs_statfs(const char *path, statfs_t *buf)
*buf = rpc_buf.data;
return msg_tag_get_val(tag);
}
// long poll(struct pollfd *fds, nfds_t n, int timeout)
RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_POLL, poll,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, fds,
rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, n,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, timeout)
int fs_poll(struct pollfd *fds, nfds_t n, int timeout)
{
if (!fds || n == 0)
{
return -EINVAL;
}
obj_handler_t hd = mk_sd_init_raw(fds[0].fd).hd;
msg_tag_t tag;
rpc_ref_file_array_t rpc_fds = {
.data = (uint8_t *)(fds),
.len = sizeof(*fds) * n,
};
rpc_umword_t_t rpc_n = {
.data = n,
};
rpc_int_t rpc_timeout = {
.data = timeout,
};
tag = fs_t_poll_call(hd, &rpc_fds, &rpc_n, &rpc_timeout);
if (msg_tag_get_val(tag) < 0)
{
return msg_tag_get_val(tag);
}
return msg_tag_get_val(tag);
}

View File

@@ -16,7 +16,8 @@ RPC_GENERATION_OP3(fs_t, FS_PROT, FS_OPEN, open,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, mode)
{
path->data[path->len - 1] = 0;
if (!obj->op->fs_svr_open) {
if (!obj->op->fs_svr_open)
{
return -ENOSYS;
}
int ret = obj->op->fs_svr_open((char *)(path->data), flags->data, mode->data);
@@ -31,7 +32,8 @@ RPC_GENERATION_DISPATCH3(fs_t, FS_PROT, FS_OPEN, open,
RPC_GENERATION_OP1(fs_t, FS_PROT, FS_CLOSE, close,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd)
{
if (!obj->op->fs_svr_close) {
if (!obj->op->fs_svr_close)
{
return -ENOSYS;
}
obj->op->fs_svr_close(fd->data);
@@ -47,12 +49,14 @@ RPC_GENERATION_OP3(fs_t, FS_PROT, FS_READ, read,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_OUT, RPC_TYPE_DATA, buf,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
{
if (!obj->op->fs_svr_read) {
if (!obj->op->fs_svr_read)
{
return -ENOSYS;
}
int ret = obj->op->fs_svr_read(fd->data, buf->data, len->data);
if (ret >= 0) {
if (ret >= 0)
{
buf->len = ret;
}
return ret;
@@ -69,7 +73,8 @@ RPC_GENERATION_OP3(fs_t, FS_PROT, FS_WRITE, write,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, buf,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
{
if (!obj->op->fs_svr_write) {
if (!obj->op->fs_svr_write)
{
return -ENOSYS;
}
int ret = obj->op->fs_svr_write(fd->data, buf->data, len->data);
@@ -85,7 +90,8 @@ RPC_GENERATION_OP2(fs_t, FS_PROT, FS_READDIR, readdir,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
rpc_dirent_t_t, rpc_dirent_t_t, RPC_DIR_OUT, RPC_TYPE_DATA, dir)
{
if (!obj->op->fs_svr_readdir) {
if (!obj->op->fs_svr_readdir)
{
return -ENOSYS;
}
return obj->op->fs_svr_readdir(fd->data, &dir->data);
@@ -101,7 +107,8 @@ RPC_GENERATION_OP3(fs_t, FS_PROT, FS_LSEEK, lseek,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, offs,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, whence)
{
if (!obj->op->fs_svr_lseek) {
if (!obj->op->fs_svr_lseek)
{
return -ENOSYS;
}
int ret = obj->op->fs_svr_lseek(fd->data, offs->data, whence->data);
@@ -118,7 +125,8 @@ RPC_GENERATION_OP2(fs_t, FS_PROT, FS_FTRUNCATE, ftruncate,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
rpc_int64_t_t, rpc_int64_t_t, RPC_DIR_IN, RPC_TYPE_DATA, offs)
{
if (!obj->op->fs_svr_ftruncate) {
if (!obj->op->fs_svr_ftruncate)
{
return -ENOSYS;
}
int ret = obj->op->fs_svr_ftruncate(fd->data, offs->data);
@@ -133,7 +141,8 @@ RPC_GENERATION_OP2(fs_t, FS_PROT, FS_FSTAT, fstat,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
rpc_kstat_t_t, rpc_kstat_t_t, RPC_DIR_OUT, RPC_TYPE_DATA, statbuf)
{
if (!obj->op->fs_svr_fstat) {
if (!obj->op->fs_svr_fstat)
{
return -ENOSYS;
}
int ret = obj->op->fs_svr_fstat(fd->data, &statbuf->data);
@@ -150,7 +159,8 @@ RPC_GENERATION_OP3(fs_t, FS_PROT, FS_IOCTL, ioctl,
rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, arg)
{
if (!obj->op->fs_svr_ioctl) {
if (!obj->op->fs_svr_ioctl)
{
return -ENOSYS;
}
int ret = obj->op->fs_svr_ioctl(fd->data, req->data, (void *)arg->data /*TODO:可能传递的内存指针*/);
@@ -173,7 +183,8 @@ RPC_GENERATION_OP3(fs_t, FS_PROT, FS_FCNTL, fcntl,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, cmd,
rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, arg)
{
if (!obj->op->fs_svr_fcntl) {
if (!obj->op->fs_svr_fcntl)
{
return -ENOSYS;
}
int ret = obj->op->fs_svr_fcntl(fd->data, cmd->data, (void *)arg->data /*TODO:可能传递的内存指针*/);
@@ -189,7 +200,8 @@ RPC_GENERATION_DISPATCH3(fs_t, FS_PROT, FS_FCNTL, fcntl,
RPC_GENERATION_OP1(fs_t, FS_PROT, FS_FSYNC, fsync,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd)
{
if (!obj->op->fs_svr_fsync) {
if (!obj->op->fs_svr_fsync)
{
return -ENOSYS;
}
return obj->op->fs_svr_fsync(fd->data);
@@ -201,7 +213,8 @@ RPC_GENERATION_DISPATCH1(fs_t, FS_PROT, FS_FSYNC, fsync,
RPC_GENERATION_OP1(fs_t, FS_PROT, FS_UNLINK, unlink,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, path)
{
if (!obj->op->fs_svr_unlink) {
if (!obj->op->fs_svr_unlink)
{
return -ENOSYS;
}
path->data[path->len - 1] = 0;
@@ -214,7 +227,8 @@ RPC_GENERATION_OP2(fs_t, FS_PROT, FS_SYMLINK, symlink,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, src,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, dst)
{
if (!obj->op->fs_svr_symlink) {
if (!obj->op->fs_svr_symlink)
{
return -ENOSYS;
}
src->data[src->len - 1] = 0;
@@ -230,7 +244,8 @@ RPC_GENERATION_DISPATCH2(fs_t, FS_PROT, FS_SYMLINK, symlink,
RPC_GENERATION_OP1(fs_t, FS_PROT, FS_MKDIR, mkdir,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, dir)
{
if (!obj->op->fs_svr_mkdir) {
if (!obj->op->fs_svr_mkdir)
{
return -ENOSYS;
}
dir->data[dir->len - 1] = 0;
@@ -242,7 +257,8 @@ RPC_GENERATION_DISPATCH1(fs_t, FS_PROT, FS_MKDIR, mkdir,
RPC_GENERATION_OP1(fs_t, FS_PROT, FS_RMDIR, rmdir,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, dir)
{
if (!obj->op->fs_svr_rmdir) {
if (!obj->op->fs_svr_rmdir)
{
return -ENOSYS;
}
dir->data[dir->len - 1] = 0;
@@ -256,7 +272,8 @@ RPC_GENERATION_OP2(fs_t, FS_PROT, FS_RENAME, rename,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, old,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, new)
{
if (!obj->op->fs_svr_rename) {
if (!obj->op->fs_svr_rename)
{
return -ENOSYS;
}
old->data[old->len - 1] = 0;
@@ -273,7 +290,8 @@ RPC_GENERATION_OP2(fs_t, FS_PROT, FS_STAT, stat,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_kstat_t_t, rpc_kstat_t_t, RPC_DIR_OUT, RPC_TYPE_DATA, buf)
{
if (!obj->op->fs_svr_stat) {
if (!obj->op->fs_svr_stat)
{
return -ENOSYS;
}
path->data[path->len - 1] = 0;
@@ -289,7 +307,8 @@ RPC_GENERATION_OP3(fs_t, FS_PROT, FS_READLINK, readlink,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_OUT, RPC_TYPE_DATA, buf,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, bufsize)
{
if (!obj->op->fs_svr_readlink) {
if (!obj->op->fs_svr_readlink)
{
return -ENOSYS;
}
path->data[path->len - 1] = 0;
@@ -307,7 +326,8 @@ RPC_GENERATION_OP2(fs_t, FS_PROT, FS_STATFS, statfs,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_statfs_t_t, rpc_statfs_t_t, RPC_DIR_OUT, RPC_TYPE_DATA, buf)
{
if (!obj->op->fs_svr_statfs) {
if (!obj->op->fs_svr_statfs)
{
return -ENOSYS;
}
path->data[path->len - 1] = 0;
@@ -317,13 +337,28 @@ RPC_GENERATION_DISPATCH2(fs_t, FS_PROT, FS_STATFS, statfs,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_statfs_t_t, rpc_statfs_t_t, RPC_DIR_OUT, RPC_TYPE_DATA, buf)
RPC_GENERATION_OP3(fs_t, FS_PROT, FS_POLL, poll,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, fds,
rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, n,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, timeout)
{
if (!obj->op->fs_svr_poll)
{
return -ENOSYS;
}
return obj->op->fs_svr_poll((struct pollfd *)(fds->data), n->data, timeout->data);
}
RPC_GENERATION_DISPATCH3(fs_t, FS_PROT, FS_POLL, poll,
rpc_ref_file_array_t, rpc_file_array_t, RPC_DIR_IN, RPC_TYPE_DATA, fds,
rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, n,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, timeout)
/*dispatch*/
RPC_DISPATCH18(fs_t, FS_PROT, typeof(FS_OPEN), FS_OPEN, open, FS_READ, read,
RPC_DISPATCH19(fs_t, FS_PROT, typeof(FS_OPEN), FS_OPEN, open, FS_READ, read,
FS_WRITE, write, FS_CLOSE, close, FS_LSEEK, lseek, FS_FTRUNCATE, ftruncate,
FS_FSYNC, fsync, FS_READDIR, readdir, FS_MKDIR, mkdir, FS_UNLINK,
unlink, FS_RENAME, rename, FS_FSTAT, fstat, FS_SYMLINK, symlink,
FS_RMDIR, rmdir, FS_STAT, stat,
FS_READLINK, readlink, FS_STATFS, statfs, FS_IOCTL, ioctl)
FS_READLINK, readlink, FS_STATFS, statfs, FS_IOCTL, ioctl, FS_POLL, poll)
void fs_init(fs_t *fs, const fs_operations_t *op)
{

View File

@@ -48,7 +48,7 @@ RPC_GENERATION_OP3(pm_t, PM_PROT, PM_KILL_TASK, kill_task,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, exit_code)
{
int16_t ret = 0;
ret = pm_rpc_kill_task(pid->data, flags->data, exit_code->data);
ret = pm_rpc_kill_task(thread_get_src_pid(), pid->data, flags->data, exit_code->data);
return ret;
}

View File

@@ -922,7 +922,7 @@ RPC_TYPE_INIT_WITHOUT_IMPL(rpc_obj_handler_t_t)
func4_op, func4_name, func5_op, func5_name, func6_op, func6_name, \
func7_op, func7_name, func8_op, func8_name, func9_op, func9_name, \
func10_op, func10_name, func11_op, func11_name, func12_op, func12_name, \
func13_op, func13_name) \
func13_op, func13_name) \
msg_tag_t rpc_##struct_type##_dispatch(struct rpc_svr_obj *obj, msg_tag_t in_tag, ipc_msg_t *ipc_msg) \
{ \
msg_tag_t tag = msg_tag_init4(0, 0, 0, -EPROTO); \
@@ -1210,6 +1210,121 @@ RPC_TYPE_INIT_WITHOUT_IMPL(rpc_obj_handler_t_t)
} \
return tag; \
}
#define RPC_DISPATCH19(struct_type, prot, op_type, func0_op, func0_name, func1_op, func1_name, \
func2_op, func2_name, func3_op, func3_name, \
func4_op, func4_name, func5_op, func5_name, func6_op, func6_name, \
func7_op, func7_name, func8_op, func8_name, func9_op, func9_name, \
func10_op, func10_name, func11_op, func11_name, func12_op, func12_name, \
func13_op, func13_name, func14_op, func14_name, func15_op, func15_name, \
func16_op, func16_name, func17_op, func17_name, func18_op, func18_name) \
msg_tag_t rpc_##struct_type##_dispatch(struct rpc_svr_obj *obj, msg_tag_t in_tag, ipc_msg_t *ipc_msg) \
{ \
msg_tag_t tag = msg_tag_init4(0, 0, 0, -EPROTO); \
size_t op_val; \
\
op_val = *((op_type *)(ipc_msg->msg_buf)); \
switch (op_val) \
{ \
case func0_op: \
{ \
tag = struct_type##_##func0_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func1_op: \
{ \
tag = struct_type##_##func1_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func2_op: \
{ \
tag = struct_type##_##func2_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func3_op: \
{ \
tag = struct_type##_##func3_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func4_op: \
{ \
tag = struct_type##_##func4_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func5_op: \
{ \
tag = struct_type##_##func5_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func6_op: \
{ \
tag = struct_type##_##func6_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func7_op: \
{ \
tag = struct_type##_##func7_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func8_op: \
{ \
tag = struct_type##_##func8_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func9_op: \
{ \
tag = struct_type##_##func9_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func10_op: \
{ \
tag = struct_type##_##func10_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func11_op: \
{ \
tag = struct_type##_##func11_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func12_op: \
{ \
tag = struct_type##_##func12_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func13_op: \
{ \
tag = struct_type##_##func13_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func14_op: \
{ \
tag = struct_type##_##func14_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func15_op: \
{ \
tag = struct_type##_##func15_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func16_op: \
{ \
tag = struct_type##_##func16_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func17_op: \
{ \
tag = struct_type##_##func17_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
case func18_op: \
{ \
tag = struct_type##_##func18_name##_dispatch((struct_type *)obj, in_tag, ipc_msg); \
} \
break; \
default: \
break; \
} \
return tag; \
}
#include "u_rpc_1.h"
#include "u_rpc_2.h"
#include "u_rpc_3.h"

View File

@@ -32,15 +32,13 @@ typedef struct meta
bool_t is_init;
} meta_t;
int rpc_meta_init(obj_handler_t tk, obj_handler_t *ret_ipc_hd);
void meta_obj_init(void);
int rpc_meta_init_def(obj_handler_t tk, obj_handler_t *ret_ipc_hd);
int rpc_meta_init(meta_t *meta_obj, obj_handler_t tk_hd, obj_handler_t *ret_ipc_hd);
void meta_obj_init_def(void);
void meta_obj_init(meta_t *meta);
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 tk, void *obj, obj_handler_t *ipc_hd);
#if 0
void rpc_loop(void);
int rpc_mtd_loop(void);
#endif

View File

@@ -9,4 +9,5 @@ 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);
sig_call_back pm_sig_func_set(sig_call_back sig_func);
int pm_sig_del_watch(pid_t pid, int flags);
int pm_sig_del_watch(pid_t pid, int flags);
int pm_waitpid(pid_t pid, umword_t *status);

View File

@@ -92,12 +92,16 @@ 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);
}
AUTO_CALL(101)
void meta_obj_init(void)
void meta_obj_init_def(void)
{
if (!meta_obj.svr.dispatch)
meta_obj_init(&meta_obj);
}
void meta_obj_init(meta_t *meta)
{
if (!meta->svr.dispatch)
{
// 防止重复初始化
rpc_svr_obj_init(&meta_obj.svr, rpc_meta_t_dispatch, META_PROT);
rpc_svr_obj_init(&meta->svr, rpc_meta_t_dispatch, META_PROT);
}
}
static msg_tag_t rpc_meta_t_dispatch(struct rpc_svr_obj *obj, msg_tag_t in_tag, ipc_msg_t *ipc_msg)
@@ -132,7 +136,28 @@ static msg_tag_t rpc_meta_t_dispatch(struct rpc_svr_obj *obj, msg_tag_t in_tag,
return msg;
}
}
int rpc_meta_init_def(obj_handler_t tk_hd, obj_handler_t *ret_ipc_hd)
{
return rpc_meta_init(&meta_obj, tk_hd, ret_ipc_hd);
}
int rpc_meta_init(meta_t *meta_obj, obj_handler_t tk_hd, obj_handler_t *ret_ipc_hd)
{
int ret;
if (meta_obj->is_init)
{
*ret_ipc_hd = meta_obj->hd_meta;
return 0;
}
ret = rpc_creaite_bind_ipc(tk_hd, &meta_obj->svr, ret_ipc_hd);
if (ret < 0)
{
return ret;
}
meta_obj->hd_meta = *ret_ipc_hd;
meta_obj->is_init = TRUE;
return 0;
}
/**
* @brief 绑定IPC
*
@@ -167,209 +192,3 @@ int rpc_creaite_bind_ipc(obj_handler_t tk, void *obj, obj_handler_t *ret_ipc_hd)
*ret_ipc_hd = ipc_hd;
return 0;
}
int rpc_meta_init(obj_handler_t tk_hd, obj_handler_t *ret_ipc_hd)
{
int ret;
if (meta_obj.is_init)
{
*ret_ipc_hd = meta_obj.hd_meta;
return 0;
}
ret = rpc_creaite_bind_ipc(tk_hd, &meta_obj.svr, ret_ipc_hd);
if (ret < 0)
{
return ret;
}
meta_obj.hd_meta = *ret_ipc_hd;
meta_obj.is_init = TRUE;
return 0;
}
#if 0
/**
* @brief RPC循环处理消息
*
* @param ipc_hd
* @param svr_obj
* @param dispatch
*/
void rpc_loop(void)
{
umword_t obj = 0;
msg_tag_t tag;
umword_t buf;
ipc_msg_t *msg;
rpc_svr_obj_t *svr_obj;
thread_msg_buf_get(-1, &buf, NULL);
msg = (ipc_msg_t *)buf;
while (1)
{
rpc_hd_alloc();
tag = thread_ipc_wait(ipc_timeout_create2(0, 0), &obj, -1);
if (msg_tag_get_val(tag) < 0)
{
continue;
}
svr_obj = (rpc_svr_obj_t *)obj;
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));
}
}
#define RPC_MTD_TH_STACK_SIZE (1024 + 256)
typedef struct mtd_params
{
rpc_svr_obj_t *obj;
void *stack;
int is_del;
msg_tag_t in_tag;
obj_handler_t ipc_obj;
obj_handler_t th_obj;
slist_head_t node;
} mtd_params_t;
static slist_head_t th_head;
static pthread_spinlock_t lock;
static void rpc_mtc_thread(void *arg)
{
rpc_svr_obj_t *svr_obj;
msg_tag_t tag;
ipc_msg_t *msg;
mtd_params_t *params = (mtd_params_t *)arg;
thread_msg_buf_get(-1, (umword_t *)(&msg), NULL);
svr_obj = (rpc_svr_obj_t *)params->obj;
if (svr_obj->dispatch)
{
tag = svr_obj->dispatch(svr_obj, params->in_tag, msg);
}
thread_ipc_send(tag, params->ipc_obj, ipc_timeout_create2(0, 0));
params->is_del = 1;
while (1)
{
u_sleep_ms(1000);
}
}
static void check_release_stack_mem(void)
{
mtd_params_t *pos;
pthread_spin_lock(&lock);
slist_foreach_not_next(pos, &th_head, node)
{
mtd_params_t *next = slist_next_entry(pos, &th_head, node);
if (pos->is_del == 1)
{
slist_del(&pos->node);
// void *stack = (void *)((char *)pos - (RPC_MTD_TH_STACK_SIZE + MSG_BUG_LEN));
handler_del_umap(pos->ipc_obj);
u_thread_del(pos->th_obj);
free(pos->stack);
}
pos = next;
}
pthread_spin_unlock(&lock);
}
extern void __pthread_new_thread_entry__(void);
int rpc_mtd_loop(void)
{
umword_t obj = 0;
msg_tag_t tag;
umword_t buf;
obj_handler_t ipc_hd;
uint8_t *main_msg_buf;
thread_msg_buf_get(-1, (umword_t *)(&main_msg_buf), NULL);
slist_init(&th_head);
while (1)
{
rpc_hd_alloc();
check_release_stack_mem();
ipc_hd = handler_alloc();
if (ipc_hd == HANDLER_INVALID)
{
// cons_write_str("mtd alloc is fial.\n");
// u_sleep_ms(1000);
continue;
}
tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(0, 0, ipc_hd));
if (msg_tag_get_val(tag) < 0)
{
// cons_write_str("mtd factory ipc fail.\n");
handler_free(ipc_hd);
// u_sleep_ms(1000);
continue;
}
tag = thread_ipc_wait(ipc_timeout_create2(1000, 1000), &obj, ipc_hd);
if (msg_tag_get_val(tag) < 0)
{
handler_free_umap(ipc_hd);
continue;
}
again_create:;
obj_handler_t th_obj;
void *stack;
stack = memalign(sizeof(void *) * 2,
RPC_MTD_TH_STACK_SIZE + MSG_BUG_LEN + sizeof(mtd_params_t));
if (!stack)
{
// cons_write_str("mtd no stack mem.\n");
check_release_stack_mem();
// u_sleep_ms(1000);
goto again_create;
}
uint8_t *msg_buf = (uint8_t *)stack + RPC_MTD_TH_STACK_SIZE;
int ret_val;
umword_t *stack_tmp = (umword_t *)((uint8_t *)stack + RPC_MTD_TH_STACK_SIZE);
mtd_params_t *params = (mtd_params_t *)((char *)stack + RPC_MTD_TH_STACK_SIZE + MSG_BUG_LEN);
// 设置调用参数等
*(--stack_tmp) = (umword_t)(params);
*(--stack_tmp) = (umword_t)0; // 保留
*(--stack_tmp) = (umword_t)rpc_mtc_thread;
//
params->in_tag = tag;
params->ipc_obj = ipc_hd;
params->obj = (rpc_svr_obj_t *)obj;
params->stack = stack;
params->is_del = 0;
slist_init(&params->node);
pthread_spin_lock(&lock);
slist_add(&th_head, &params->node);
pthread_spin_unlock(&lock);
again_th_create:
ret_val = u_thread_create(&params->th_obj,
(char *)stack_tmp,
(char *)stack + RPC_MTD_TH_STACK_SIZE,
(void (*)(void))__pthread_new_thread_entry__);
if (ret_val < 0)
{
// cons_write_str("mtd no mem.\n");
check_release_stack_mem();
// u_sleep_ms(1000);
goto again_th_create;
}
memcpy(msg_buf, main_msg_buf, MSG_BUG_LEN - IPC_USER_SIZE);
ipc_msg_t *msg = (ipc_msg_t *)msg_buf;
msg->user[2] = thread_get_src_pid();
u_thread_run(params->th_obj, 2);
// thread_ipc_reply(tag, ipc_timeout_create2(0, 0));
}
return 0;
}
#endif

View File

@@ -22,6 +22,8 @@
#include "u_hd_man.h"
#include "u_rpc_svr.h"
#include "sig_svr.h"
#include "u_sema.h"
#include "u_task.h"
#ifdef CONFIG_USING_SIG
static sig_t sig_obj;
@@ -29,6 +31,8 @@ static sig_t sig_obj;
static sig_call_back sig_cb_func;
static obj_handler_t sig_ipc = HANDLER_INVALID;
static uint8_t sig_init_flags;
static pid_t wait_pid;
static obj_handler_t sema_wait_hd;
int pm_sig_watch(pid_t pid, int flags)
{
@@ -40,6 +44,21 @@ int pm_sig_del_watch(pid_t pid, int flags)
{
return pm_del_watch_pid(pid, flags);
}
/**
* FIXME:对于已经挂了的进程暂时还不支持waitpid。
*/
int pm_waitpid(pid_t pid, umword_t *status)
{
msg_tag_t tag;
wait_pid = pid;
pm_sig_watch(pid, 0);
u_sema_down(sema_wait_hd, 0, NULL);
if (status) {
*status = 0;/*FIXME:*/
}
return 0;
}
sig_call_back pm_sig_func_set(sig_call_back sig_func)
{
sig_call_back tmp = sig_cb_func;
@@ -52,6 +71,10 @@ static int kill(int flags, int pid)
{
int ret = -EINVAL;
if (wait_pid == pid || wait_pid == -1)
{
u_sema_up(sema_wait_hd);
}
if (sig_cb_func)
{
ret = sig_cb_func(pid, flags);
@@ -64,15 +87,21 @@ static const sig_op_t sig_op = {
};
void sig_init(void)
{
msg_tag_t tag;
if (sig_init_flags)
{
return;
}
rpc_meta_init(TASK_THIS, &sig_ipc);
rpc_meta_init_def(TASK_THIS, &sig_ipc);
// 注册到队列中去
sig_svr_obj_init(&sig_obj);
sig_obj.op = &sig_op;
meta_obj_init();
meta_obj_init_def();
meta_reg_svr_obj(&sig_obj.svr_obj, SIG_PORT);
sema_wait_hd = handler_alloc();
assert(sema_wait_hd != HANDLER_INVALID);
tag = facotry_create_sema(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_wait_hd), 0, 1);
assert(msg_tag_get_val(tag) >= 0);
}
#endif

View File

@@ -13,6 +13,8 @@ typedef struct queue
void q_init(queue_t *q, uint8_t *data, int size);
int q_empty(queue_t *q);
int q_enqueue(queue_t *q, uint8_t e);
int q_get_tail(queue_t *q, uint8_t *e);
int q_dequeue_tail(queue_t *q, uint8_t *e);
int q_dequeue(queue_t *q, uint8_t *e);
int q_queue_len(queue_t *q);
void q_queue_clear(queue_t *q);

View File

@@ -1,12 +1,12 @@
/**
* @file u_queue.c
* @author ATShining (1358745329@qq.com)
* @brief
* @brief
* @version 0.1
* @date 2024-08-27
*
*
* @copyright Copyright (c) 2024
*
*
*/
#include "u_types.h"
#include "u_queue.h"
@@ -51,6 +51,31 @@ int q_dequeue(queue_t *q, uint8_t *e)
q->front = (q->front + 1) % q->size;
return 0;
}
int q_get_tail(queue_t *q, uint8_t *e)
{
if (q->rear == q->front)
{ // 空的
return -1;
}
if (e)
{
*e = q->m[q->rear];
}
return 0;
}
int q_dequeue_tail(queue_t *q, uint8_t *e)
{
if (q->rear == q->front)
{ // 空的
return -1;
}
q->rear = (q->rear - 1 + q->size) % q->size;
if (e)
{
*e = q->m[q->rear];
}
return 0;
}
int q_queue_len(queue_t *q)
{
return (q->rear - q->front + q->size) % q->size;

View File

@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
ret = appfs_open_init(&fs_obj);
assert(ret >= 0);
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
fs_svr_init();
ns_register(mount_path, hd, 0);

View File

@@ -163,6 +163,9 @@ int appfs_open(const char *name, int flags, int mode)
}
else
{
if (name[0] == '/') {
name++;
}
type = APPFS_FILE_TYPE;
}
if (type == APPFS_FILE_TYPE)
@@ -399,7 +402,7 @@ int appfs_truncate(int fd, off_t length)
ret = appfs_file_resize_raw(fs, dir_info_cache_list[file->dir_info_fd].info, length);
return ret;
}
int appfs_fstat(int fd, struct stat *st)
int appfs_fstat(int fd, struct kstat *st)
{
appfs_file_t *file = appfs_get_file(fd);

View File

@@ -20,7 +20,7 @@ int appfs_write(int fd, void *data, int len);
int appfs_read(int fd, void *data, int len);
int appfs_ioctl(int fd, unsigned long cmd, unsigned long arg);
int appfs_lseek(int fd, int offset, unsigned long whence);
int appfs_fstat(int fd, struct stat *st);
int appfs_fstat(int fd, struct kstat *st);
int appfs_stat(const char *path, struct kstat *st);
int appfs_close(int fd);
int appfs_remove(const char *name);

View File

@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
}
}
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
fs_svr_init();
ns_register(mount_path, hd, 0);

View File

@@ -36,7 +36,7 @@ int main(int args, char *argv[])
int ret;
fast_ipc_init();
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
fs_svr_init();
ns_register("/mnt", hd, 0);

View File

@@ -17,7 +17,7 @@ int main(int argv, char *args[])
int ret;
printf("args[0]:%s\n", args[0]);
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
fs_svr_init();
ns_register("/vfs_test", hd, 0);

View File

@@ -1,151 +1,172 @@
#include <u_types.h>
#include <u_queue.h>
#include <u_util.h>
#include <u_thread.h>
#include <u_log.h>
#include <u_hd_man.h>
#include <u_err.h>
#include <u_sema.h>
#include <assert.h>
#include <errno.h>
#include <u_sleep.h>
#include <pthread.h>
#include <rpc_prot.h>
#include "cons_svr.h"
#include <stdio.h>
#include <u_thread_util.h>
#include <u_thread.h>
#include <string.h>
// #include <u_types.h>
// #include <u_queue.h>
// #include <u_util.h>
// #include <u_thread.h>
// #include <u_log.h>
// #include <u_hd_man.h>
// #include <u_err.h>
// #include <u_sema.h>
// #include <assert.h>
// #include <errno.h>
// #include <u_sleep.h>
// #include <pthread.h>
// #include <rpc_prot.h>
// #include "cons_svr.h"
// #include <stdio.h>
// #include <u_thread_util.h>
// #include <u_thread.h>
// #include <string.h>
// #include "u_hd_man.h"
// #include "u_mutex.h"
// #include "u_factory.h"
// #include "u_task.h"
#if IS_ENABLED(CONFIG_MMU)
#define CONS_STACK_SIZE 1024
#else
#define CONS_STACK_SIZE 512
#endif
static ATTR_ALIGN(8) uint8_t cons_stack[CONS_STACK_SIZE];
// static uint8_t cons_msg_buf[MSG_BUG_LEN];
static cons_t cons_obj;
static obj_handler_t cons_th;
static obj_handler_t sem_th;
static void console_read_func(void)
{
while (1)
{
int r_len = ulog_read_bytes(LOG_PROT, cons_obj.r_data_buf, sizeof(cons_obj.r_data_buf));
// #if IS_ENABLED(CONFIG_MMU)
// #define CONS_STACK_SIZE 1024
// #else
// #define CONS_STACK_SIZE 512
// #endif
// static ATTR_ALIGN(8) uint8_t cons_stack[CONS_STACK_SIZE];
if (r_len > 0)
{
pthread_spin_lock(&cons_obj.r_lock);
for (int i = 0; i < r_len; i++)
{
q_enqueue(&cons_obj.r_queue, cons_obj.r_data_buf[i]);
}
if (sem_th)
{
u_sema_up(sem_th);
}
pthread_spin_unlock(&cons_obj.r_lock);
}
}
handler_free_umap(cons_obj.hd_cons_read);
while (1)
{
u_sleep_ms(1000);
}
}
// static cons_t cons_obj;
// static obj_handler_t cons_th;
// static obj_handler_t sem_th;
// static u_mutex_t lock_cons;
void console_init(void)
{
cons_svr_obj_init(&cons_obj);
meta_reg_svr_obj(&cons_obj.svr, CONS_PROT);
u_thread_create(&cons_th, (char *)cons_stack + sizeof(cons_stack) - 8, NULL, console_read_func);
u_thread_run(cons_th, 3);
ulog_write_str(LOG_PROT, "cons svr init...\n");
}
/**
* @brief 向控制台写入数据
*
* @param data
* @param len
*/
int console_write(uint8_t *data, size_t len)
{
// pid_t src_pid = thread_get_src_pid();
// static void cons_read_lock(void)
// {
// u_mutex_lock(&lock_cons, 0, 0);
// }
// static void cons_read_unlock(void)
// {
// u_mutex_unlock(&lock_cons);
// }
// if (src_pid != cons_obj.active_pid)
// {
// /*TODO:存储到文件或者通过其他方式*/
// return -EACCES;
// }
// pthread_mutex_lock(&cons_obj.w_lock);
ulog_write_bytes(LOG_PROT, data, len);
// pthread_mutex_unlock(&cons_obj.w_lock);
// static void console_read_func(void)
// {
// while (1)
// {
// int r_len = ulog_read_bytes(LOG_PROT, cons_obj.r_data_buf, sizeof(cons_obj.r_data_buf));
return len;
}
/**
* @brief 向控制台读取数据
*
* @param data
* @param len 如果len为0则返回数据长度。
* @return int
*/
int console_read(uint8_t *data, size_t len)
{
int r_len = 0;
pid_t src_pid = thread_get_src_pid();
// if (r_len > 0)
// {
// cons_read_lock();
// for (int i = 0; i < r_len; i++)
// {
// q_enqueue(&cons_obj.r_queue, cons_obj.r_data_buf[i]);
// }
// cons_read_unlock();
// if (sem_th)
// {
// u_sema_up(sem_th);
// }
// }
// }
// handler_free_umap(cons_obj.hd_cons_read);
// while (1)
// {
// u_sleep_ms(1000);
// }
// }
// int console_init(void)
// {
// msg_tag_t tag;
if (src_pid != cons_obj.active_pid)
{
return -EACCES;
}
if (len == 0)
{
return q_queue_len(&cons_obj.r_queue);
}
if (q_queue_len(&cons_obj.r_queue) == 0)
{
// 回复没有消息
return 0;
}
else
{
pthread_spin_lock(&cons_obj.r_lock);
if (q_queue_len(&cons_obj.r_queue) == 0)
{
// 回复没有消息
pthread_spin_unlock(&cons_obj.r_lock);
return 0;
}
int i;
for (i = 0; i < q_queue_len(&cons_obj.r_queue) && i < len; i++)
{
uint8_t e;
if (q_dequeue(&cons_obj.r_queue, &e) < 0)
{
break;
}
data[i] = e;
}
r_len = i;
pthread_spin_unlock(&cons_obj.r_lock);
}
return r_len;
}
/**
* @brief 激活控制台为发送者进程
*
*/
void console_active(mk_pid_t pid, obj_handler_t sem)
{
cons_obj.active_pid = pid;
if (sem)
{
if (sem_th)
{
handler_free_umap(sem_th);
}
sem_th = sem;
}
}
// cons_svr_obj_init(&cons_obj);
// meta_reg_svr_obj(&cons_obj.svr, CONS_PROT);
// u_mutex_init(&lock_cons, handler_alloc());
// sem_th = handler_alloc();
// if (sem_th == HANDLER_INVALID)
// {
// return -1;
// }
// tag = facotry_create_sema(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sem_th), 0, INT32_MAX);
// if (msg_tag_get_val(tag) < 0)
// {
// return msg_tag_get_val(tag);
// }
// // u_thread_create(&cons_th, (char *)cons_stack + sizeof(cons_stack) - 8, NULL, console_read_func);
// // u_thread_run(cons_th, 3);
// ulog_write_str(LOG_PROT, "cons svr init...\n");
// return 0;
// }
// /**
// * @brief 向控制台写入数据
// *
// * @param data
// * @param len
// */
// int console_write(uint8_t *data, size_t len)
// {
// u_mutex_lock(&lock_cons, 0, 0);
// ulog_write_bytes(LOG_PROT, data, len);
// u_mutex_unlock(&lock_cons);
// return len;
// }
// /**
// * @brief 向控制台读取数据
// *
// * @param data
// * @param len 如果len为0则返回数据长度。
// * @return int
// */
// int console_read(uint8_t *data, size_t len)
// {
// int r_len = 0;
// pid_t src_pid = thread_get_src_pid();
// if (src_pid != cons_obj.active_pid)
// {
// return -EACCES;
// }
// if (len == 0)
// {
// return q_queue_len(&cons_obj.r_queue);
// }
// if (q_queue_len(&cons_obj.r_queue) == 0)
// {
// // 回复没有消息
// return 0;
// }
// else
// {
// u_mutex_lock(&lock_cons, 0, 0);
// if (q_queue_len(&cons_obj.r_queue) == 0)
// {
// // 回复没有消息
// u_mutex_unlock(&lock_cons);
// return 0;
// }
// int i;
// for (i = 0; i < q_queue_len(&cons_obj.r_queue) && i < len; i++)
// {
// uint8_t e;
// if (q_dequeue(&cons_obj.r_queue, &e) < 0)
// {
// break;
// }
// data[i] = e;
// }
// r_len = i;
// u_mutex_unlock(&lock_cons);
// }
// return r_len;
// }
// /**
// * @brief 激活控制台为发送者进程
// *
// */
// void console_active(mk_pid_t pid, obj_handler_t sem)
// {
// cons_obj.active_pid = pid;
// if (sem)
// {
// if (sem_th)
// {
// handler_free_umap(sem_th);
// }
// sem_th = sem;
// }
// }

View File

@@ -2,3 +2,5 @@
#include <u_types.h>
void console_init(void);
void console_active(mk_pid_t pid, obj_handler_t sem);
int console_write(uint8_t *data, size_t len);
int console_read(uint8_t *data, size_t len);

View File

@@ -9,7 +9,7 @@
*
*/
#include "cons.h"
#include "namespace.h"
#include "ns.h"
#include "ns_svr.h"
#include "parse_cfg.h"
#include "pm.h"
@@ -31,9 +31,10 @@
#include <string.h>
#include <u_fast_ipc.h>
#include "nsfs.h"
#include "tty.h"
#define DEFAULT_INIT_CFG "init.cfg"
#define STACK_COM_ITME_SIZE (2 * 1024 /*sizeof(struct pthread) + TP_OFFSET*/)
#define STACK_COM_ITME_SIZE ((1024+512) * 4)
#define STACK_NUM 2
ATTR_ALIGN(8)
static uint8_t stack_coms[STACK_COM_ITME_SIZE * STACK_NUM];
@@ -61,10 +62,10 @@ int main(int argc, char *args[])
ulog_write_str(LOG_PROT, "init..\n");
u_env_default_init();
env = u_get_global_env();
rpc_meta_init(TASK_THIS, &env->ns_hd);
rpc_meta_init_def(TASK_THIS, &env->ns_hd);
namespace_init(env->ns_hd);
pm_init();
console_init();
// console_init();
parse_cfg_init();
fs_ns_mkdir("/dev");
@@ -73,7 +74,7 @@ int main(int argc, char *args[])
printf("test_main..\n");
test_main();
#endif
tty_svr_init();
ret = parse_cfg(DEFAULT_INIT_CFG, env);
printf("run app num is %d.\n", ret);
// task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, THREAD_MAIN));

View File

@@ -8,7 +8,7 @@
* @copyright Copyright (c) 2023
*
*/
#include "namespace.h"
#include "ns.h"
#include <assert.h>
#include <errno.h>
@@ -28,6 +28,7 @@
#include "u_rpc_svr.h"
#include "u_slist.h"
#include "nsfs.h"
static ns_t ns;
static fs_t ns_fs;

View File

@@ -343,6 +343,11 @@ ns_node_t *ns_node_find_svr_file(const char *path, int *ret, int *cur_inx)
{
return parent_node;
}
if (!parent_node)
{
*ret = -ENOENT;
return NULL;
}
if ((parent_node->type == NODE_TYPE_DUMMY && (dir_node == NULL || dir_node->type == NODE_TYPE_DUMMY)))
{
return &root_node;

View File

@@ -22,7 +22,7 @@
#include <u_mutex.h>
#include <u_hd_man.h>
#include <stdlib.h>
#include "tty.h"
#include <parse_cfg.h>
#include <appfs_tiny.h>
static char cmd_line[CMD_LEN]; //!< 命令行
@@ -186,7 +186,8 @@ int parse_cfg(const char *parse_cfg_file_name, uenv_t *env)
}
else
{
console_active(pid, hd_sem);
// console_active(pid, hd_sem);
tty_set_fg_pid(pid);
run_cn++;
}
}

View File

@@ -13,7 +13,7 @@
#include "u_env.h"
#include "rpc_prot.h"
#include "cons_svr.h"
#include "namespace.h"
#include "ns.h"
#include "u_task.h"
#include "u_hd_man.h"
#include "u_sig.h"
@@ -22,6 +22,7 @@
#include "u_malloc.h"
#include "nsfs.h"
#include "sig_cli.h"
#include "tty.h"
#include <errno.h>
#include <malloc.h>
#include <stdio.h>
@@ -130,14 +131,16 @@ int pm_rpc_watch_pid(pm_t *pm, obj_handler_t sig_rcv_hd, pid_t pid, int flags)
handler_free_umap(sig_rcv_hd);
return -ENOMEM;
}
#if 0
entry->notify_sem_hd = HANDLER_INVALID;
#endif
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);
printf("[pm] watch pid:%d, sig hd:%d.\n", pid, sig_rcv_hd);
return 0;
}
#if IS_ENABLED(CONFIG_USING_SIG)
@@ -160,6 +163,7 @@ static bool_t pm_send_sig_to_task(pm_t *pm, pid_t pid, umword_t sig_val)
{
watch_entry_t *next = slist_next_entry(pos, &pm->watch_head, node);
printf("watch_pid:%d pid:%d\n", pos->watch_pid, pid);
if (pos->watch_pid == pid)
{
if (sig_val == KILL_SIG)
@@ -184,10 +188,8 @@ static bool_t pm_send_sig_to_task(pm_t *pm, pid_t pid, umword_t sig_val)
* @param flags
* @return int
*/
int pm_rpc_kill_task(int pid, int flags, int exit_code)
int pm_rpc_kill_task(int src_pid, int pid, int flags, int exit_code)
{
pid_t src_pid = thread_get_src_pid();
if (pid == TASK_THIS)
{
printf("not kill init task.\n");
@@ -200,15 +202,15 @@ int pm_rpc_kill_task(int pid, int flags, int exit_code)
}
// ns_node_del_by_pid(pid, flags); TODO: //!< 从ns中删除
pm_del_watch_by_pid(&pm, pid); //!< 从watch中删除
#if IS_ENABLED(CONFIG_USING_SIG)
pm_send_sig_to_task(&pm, pid, KILL_SIG); //!< 给watch者发送sig
#endif
#if IS_ENABLED(CONFIG_USING_SIG)
if (src_pid != pid)
{
// 发起者自己删除
handler_del_umap(pid);
}
pm_send_sig_to_task(&pm, pid, KILL_SIG); //!< 给watch者发送sig
#endif
pm_del_watch_by_pid(&pm, pid); //!< 从watch中删除
printf("[pm] kill pid:%d code:%d.\n", pid, exit_code);
return 0;
}
@@ -247,11 +249,15 @@ int pm_rpc_run_app(const char *path, int flags, char *params, int params_len)
NULL, 0, &sem, 0);
if (ret >= 0)
{
#if 0
if (!(flags & PM_APP_BG_RUN))
{
console_active(pid, sem);
tty_set_fg_pid(pid);
}
#endif
return pid;
}
return ret;
}
/**
* @brief 用于拷贝数据
@@ -272,3 +278,27 @@ int pm_rpc_copy_data(pid_t src_pid, pid_t dst_pid, umword_t src_addr, umword_t d
return msg_tag_get_val(tag);
}
#if 0
/**
* @brief 等待某个进程死亡
*/
int pm_waitpid(obj_handler_t sig_rcv_hd, pid_t pid)
{
pid_t src_pid = thread_get_src_pid();
watch_entry_t *pos;
/*TODO:检测sig_rcv_hd的类型*/
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 && src_pid == pos->src_pid)
{
pos->notify_sem_hd = sig_rcv_hd;
break;
}
pos = next;
}
return 0;
}
#endif

View File

@@ -17,3 +17,4 @@ static inline obj_handler_t pm_hd2pid(pid_t _pid)
{
return (obj_handler_t)_pid;
}
int pm_rpc_copy_data(pid_t src_pid, pid_t dst_pid, umword_t src_addr, umword_t dst_addr, size_t len);

View File

@@ -0,0 +1,672 @@
#include "tty.h"
#include "u_types.h"
#include <sys/ioctl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <u_queue.h>
#include <ctype.h>
#include <stdio.h>
#include "cons.h"
#include "u_hd_man.h"
#include "u_prot.h"
#include "u_task.h"
#include "u_sema.h"
#include "u_mutex.h"
#include "u_factory.h"
#include "u_thread_util.h"
#include "u_log.h"
#include "u_sleep.h"
#include "rpc_prot.h"
#include "fs_svr.h"
#include "ns.h"
#include "u_task.h"
#include "pm.h"
#include "pm_svr.h"
#if IS_ENABLED(CONFIG_MMU)
#define CONS_STACK_SIZE 1024
#else
#define CONS_STACK_SIZE 1024
#endif
static ATTR_ALIGN(8) uint8_t cons_stack[CONS_STACK_SIZE];
static uint8_t cons_ipc_msg[MSG_BUG_LEN];
static tty_struct_t sys_tty;
static obj_handler_t cons_th;
static obj_handler_t sem_th;
static u_mutex_t lock_cons;
static meta_t tty_meta;
static obj_handler_t tty_ipc_hd;
static fs_t tty_fs;
static int tty_def_line_handler(tty_struct_t *tty, uint8_t r);
static int tty_write_hw(tty_struct_t *tty);
void tty_set_fg_pid(pid_t pid)
{
sys_tty.fg_pid = pid;
}
void tty_struct_init(tty_struct_t *tty)
{
// q_init(&tty->r_queue, tty->r_queue_data, TTY_QUEUE_DATA_SIZE);
q_init(&tty->w_queue, tty->w_queue_data, TTY_QUEUE_DATA_SIZE);
q_init(&tty->pre_queue, tty->pre_uque_data, TTY_QUEUE_DATA_SIZE);
}
static inline void cons_read_lock(void)
{
u_mutex_lock(&lock_cons, 0, 0);
}
static inline void cons_read_unlock(void)
{
u_mutex_unlock(&lock_cons);
}
static void console_read_func(void)
{
uint8_t data[32];
while (1)
{
int r_len = ulog_read_bytes(LOG_PROT, data, sizeof(data));
if (r_len > 0)
{
cons_read_lock();
for (int i = 0; i < r_len; i++)
{
// q_enqueue(&sys_tty.r_queue, data[i]);
if (tty_def_line_handler(&sys_tty, data[i]) == 1)
{
break;
}
}
if (!sys_tty.is_nl && L_ICANON(&sys_tty))
{
tty_write_hw(&sys_tty);
// 规范模式下没有成一行
cons_read_unlock();
}
else
{
u_sema_up(sem_th);
}
cons_read_unlock();
}
}
// handler_free_umap(cons_obj.hd_cons_read);
while (1)
{
u_sleep_ms(0);
}
}
// 初始化termios
static void init_termios(struct termios *tp)
{
memset(tp, 0, sizeof(struct termios));
memcpy(tp->c_cc, C_CC_INIT, NCCS);
// if (IS_A_CONSOLE(line) || IS_A_PTY_SLAVE(line)) {
// tp->c_iflag = ICRNL | IXON;
// tp->c_oflag = OPOST | ONLCR;
// tp->c_cflag = B38400 | CS8 | CREAD;
// tp->c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
// ECHOCTL | ECHOKE | IEXTEN;
// } else if (IS_A_SERIAL(line)) {
tp->c_iflag = ICRNL | IXOFF;
tp->c_oflag = OPOST | ONLCR | XTABS;
tp->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
tp->c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
// ECHOCTL |
ECHOKE | IEXTEN;
// } else if (IS_A_PTY_MASTER(line))
// tp->c_cflag = B9600 | CS8 | CREAD;
}
static int cons_init(void)
{
msg_tag_t tag;
u_mutex_init(&lock_cons, handler_alloc());
sem_th = handler_alloc();
if (sem_th == HANDLER_INVALID)
{
return -1;
}
tag = facotry_create_sema(FACTORY_PROT,
vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sem_th), 0, 1);
if (msg_tag_get_val(tag) < 0)
{
return msg_tag_get_val(tag);
}
u_thread_create(&cons_th, (char *)cons_stack + sizeof(cons_stack) - 8, cons_ipc_msg, console_read_func);
u_thread_run(cons_th, 4);
ulog_write_str(LOG_PROT, "cons init...\n");
return 0;
}
static int tty_open(const char *path, int flags, int mode)
{
ulog_write_str(LOG_PROT, "tty init...\n");
return 0;
}
static void tty_add_w_queue(tty_struct_t *tty, char r)
{
if (O_OPOST(tty))
{
if (O_OLCUC(tty) && isupper(r))
{
// 小写转大写
r = toupper(r);
}
if (O_ONLCR(tty) && r == '\n')
{
q_enqueue(&tty->w_queue, '\r');
}
if (O_OCRNL(tty) && r == '\r')
{
r = '\n';
if (O_ONLRET(tty))
{
tty->col = 0;
}
}
if (O_XTABS(tty) && r == '\t')
{
// 制表符会被转换成空格符
r = ' ';
}
}
q_enqueue(&tty->w_queue, r);
}
/**
* 删除一个字符
* @param tty
* @return
*/
static int erase_c(tty_struct_t *tty)
{
char r_tmp;
// 如果最后一个字符是换行符号,则不能在进行擦除了。
if (q_get_tail(&tty->pre_queue, &r_tmp) < 0)
{
return -1;
}
if (r_tmp == '\n')
{
return 0;
}
if (q_dequeue_tail(&tty->pre_queue, &r_tmp) >= 0)
{
// 刪除上次写的两个字符
// 如果在标准模式下设定了ECHOE标志则当收到一个ERASE控制符时将删除前一个显示字符。
tty_add_w_queue(tty, '\b');
tty_add_w_queue(tty, ' ');
tty_add_w_queue(tty, '\b');
if (tty->col > 0)
{
tty->col--;
}
}
return 0;
}
/**
* 对读取的数据进行处理
* @param tty
*/
static int tty_def_line_handler(tty_struct_t *tty, uint8_t r)
{
int ret = 0;
if (L_ICANON(tty))
{
// 能够读到数据
// while (q_dequeue(&tty->r_queue, &r) >= 0)
{
if (tty->is_error)
{
if (!I_IGNPAR(tty))
{
if (I_PARMRK(tty))
{
q_enqueue(&tty->pre_queue, '\377');
q_enqueue(&tty->pre_queue, '\0');
q_enqueue(&tty->pre_queue, r);
}
else
{
q_enqueue(&tty->pre_queue, '\0');
}
}
}
else
{
if (I_ISTRIP(tty))
{ // 去掉最高位
r &= 0x7f;
}
if (I_IGNCR(tty))
{ // 去掉输入的cr
if (r == '\r')
{
return ret;
}
}
else if (I_INLCR(tty))
{
if (r == '\n')
{
r = '\r';
}
}
if (I_ICRNL(tty) && !I_IGNCR(tty))
{
if (r == '\r')
{
r = '\n';
}
}
if (I_IUCLC(tty) && isupper(r))
{ // 大写转小写
r = tolower(r);
}
// 本地模式的处理
if (L_ECHO(tty))
{
if (L_ECHOCTL(tty) && iscntrl(r))
{
if (r != START_C(tty) // 显示指定的控制字符
&& r != STOP_C(tty) && r != '\t' && r != '\n' && (r >= 0 && r <= 37))
{
tty_add_w_queue(tty, '^');
tty_add_w_queue(tty, r + 0x40);
goto next;
}
}
if (L_ICANON(tty))
{ // 标准模式
if (L_ECHOE(tty) && r == ERASE_C(tty))
{ // 删除一个字符
erase_c(tty);
return ret;
}
if (!L_ECHOKE(tty))
{
if (L_ECHOK(tty))
{
// 如果ICANON同时设置KILL将删除当前行
if (r == KILL_C(tty))
{
// 删除当前行,还没写
tty_add_w_queue(tty, '\n');
return ret;
}
}
}
else if (r == KILL_C(tty))
{
// 刪除这行的每一个字符
for (int i = 0; i < tty->col; i++)
{
erase_c(tty);
}
return ret;
}
}
tty_add_w_queue(tty, r);
}
else
{
if (L_ECHONL(tty) && L_ICANON(tty))
{
// 如果在标准模式下设置了该标志即使没有设置ECHO标志换行符还是会被显示出来。
if (r == '\n')
{
tty_add_w_queue(tty, r);
}
}
}
next:
// if(!I_IGNBRK(tty) && I_BRKINT(tty) && r==){
// inner_set_sig(SIGINT-1);
// }
if (L_ISIG(tty))
{
// 发送响应的信号
if (r == INTR_C(tty))
{
// 发送给前台进程组的所有进程
// inner_set_sig(SIGINT);TODO:
pm_rpc_kill_task(-1, tty->fg_pid, 0, 0);
// ulog_write_str(LOG_PROT, "ctrl c");
if (!L_NOFLSH(tty))
{
q_queue_clear(&tty->w_queue);
// q_queue_clear(&tty->r_queue);
ret = 1;
}
tty->is_nl = 1;
return ret;
}
else if (r == QUIT_C(tty))
{
// inner_set_sig(SIGQUIT);TODO:
ulog_write_str(LOG_PROT, "Ctrl+C");
if (!L_NOFLSH(tty))
{
q_queue_clear(&tty->w_queue);
// q_queue_clear(&tty->r_queue);
ret = 1;
}
tty->is_nl = 1;
return ret;
}
else if (r == SUSP_C(tty))
{
// inner_set_sig(SIGTSTP);TODO:
if (!L_NOFLSH(tty))
{
// q_queue_clear(&tty->r_queue);
ret = 0;
}
tty->is_nl = 1;
return ret;
}
}
if (L_TOSTOP(tty))
{
// 个非前台进程组的进程试图向它的控制终端写入数据时,
// 信号SIGTTOU会被被发送到这个进程所在的进程组。
// 默认情况下,这个信号会使进程停止
// 就像收到SUSP控制符一样。
}
if (!iscntrl(r))
{
tty->col++;
}
else
{
if (r == '\n')
{
tty->col = 0;
}
}
if (L_ICANON(tty))
{
// 规范工作方式
if (
// r == EOF_C(tty)
// || r == EOL_C(tty)
// || r == EOL2_C(tty)
// || r == ERASE_C(tty)
// || r == KILL_C(tty)
// || r == REPRINT_C(tty)
// || r == START_C(tty)
// || r == WERASE_C(tty)
r == '\n' || r == EOL_C(tty) || r == EOL2_C(tty) || r == EOF_C(tty))
{
if (r != EOF_C(tty))
{
if (q_enqueue(&tty->pre_queue, r) < 0)
{
// 添加失败了
// 这里应该加上等待机制
}
}
tty->is_nl = 1;
// q_clear(&tty->r_queue);
return ret;
}
else
{
tty->is_nl = 0;
}
}
if (q_enqueue(&tty->pre_queue, r) < 0)
{
// 添加失败了
// 这里应该加上等待机制
}
}
}
}
else
{
// while (q_dequeue(&tty->r_queue, &r) != -1)
{
q_enqueue(&tty->pre_queue, r);
}
}
end:
return ret;
}
static int tty_write_hw(tty_struct_t *tty)
{
uint8_t r;
int w_len = 0;
int res;
if (!q_queue_len(&tty->w_queue))
{
return w_len;
}
while ((res = q_dequeue(&tty->w_queue, &r)) >= 0)
{
ulog_write_bytes(LOG_PROT, &r, 1);
w_len++;
}
return w_len;
}
static int tty_read(int fd, void *buf, size_t len)
{
uint8_t r;
uint8_t *tmp_buf = buf;
int i = 0;
if (thread_get_src_pid() != sys_tty.fg_pid)
{
return -ENOTTY;
}
if (q_queue_len(&sys_tty.pre_queue) == 0)
{
u_sema_down(sem_th, 0, NULL);
}
again:
cons_read_lock();
if (q_queue_len(&sys_tty.pre_queue) == 0)
{
cons_read_unlock();
return -EAGAIN;
}
sys_tty.is_nl = 0;
for (i = 0; i < len && q_dequeue(&sys_tty.pre_queue, &r) >= 0; i++)
{
tmp_buf[i] = r;
}
if (q_queue_len(&sys_tty.pre_queue) != 0)
{
u_sema_up(sem_th);
}
cons_read_unlock();
// 如果有回显的字符,直接在这里写
tty_write_hw(&sys_tty);
return i;
}
static int tty_write(int fd, void *buf, size_t len)
{
int i;
uint8_t r;
#if 0
int ret;
uint8_t *tmp_buf = buf;
for (i = 0; i < len; i++)
{
r = tmp_buf[i];
tty_add_w_queue(&sys_tty, r);
}
// 调用写函数
ret = tty_write_hw(&sys_tty);
#else
ulog_write_bytes(LOG_PROT, buf, len);
#endif
return len;
}
static int tty_ioctl(int fd, int req, void *args)
{
pid_t src_pid = thread_get_src_pid();
pid_t cur_pid = TASK_THIS;
int ret = 0;
msg_tag_t tag;
if (!args)
{
return -EINVAL;
}
#if 1
tag = task_get_pid(TASK_THIS, (umword_t *)(&cur_pid));
if (msg_tag_get_val(tag) < 0)
{
return msg_tag_get_val(tag);
}
if (cur_pid == 0)
{
cur_pid = TASK_THIS;
}
#endif
switch (req)
{
case TCGETS:
{
ret = pm_rpc_copy_data(cur_pid, src_pid,
(addr_t)&sys_tty.termios, (addr_t)args,
sizeof(struct termios));
if (ret < 0)
{
return ret;
}
}
break;
case TCSETS:
{
ret = pm_rpc_copy_data(src_pid, cur_pid,
(addr_t)args, (addr_t)&sys_tty.termios,
sizeof(struct termios));
{
return ret;
}
}
break;
case TIOCGWINSZ:
{
sys_tty.w_size.ws_col = 80;
sys_tty.w_size.ws_row = 80;
ret = pm_rpc_copy_data(cur_pid, src_pid,
(addr_t)&sys_tty.w_size, (addr_t)args,
sizeof(struct winsize));
if (ret < 0)
{
return ret;
}
}
break;
case TIOCSWINSZ:
{
ret = pm_rpc_copy_data(src_pid, cur_pid,
(addr_t)args, (addr_t)&sys_tty.w_size,
sizeof(struct winsize));
{
return ret;
}
// inner_set_sig(SIGWINCH);TODO:
}
break;
case TIOCSPGRP:
{
pid_t pgrp;
ret = pm_rpc_copy_data(src_pid, cur_pid,
(addr_t)args, (addr_t)&pgrp,
sizeof(pid_t));
if (ret < 0)
{
return ret;
}
sys_tty.fg_pid = pgrp; //!< FIXME:暂时没有进程组的概念
}
break;
case TIOCGPGRP:
{
ret = pm_rpc_copy_data(cur_pid, src_pid,
(addr_t)&sys_tty.fg_pid, (addr_t)args,
sizeof(pid_t));
if (ret < 0)
{
return ret;
}
}
break;
case FIONREAD:
{
int r_len = q_queue_len(&sys_tty.pre_queue);
ret = pm_rpc_copy_data(cur_pid, src_pid,
(addr_t)&r_len, (addr_t)args,
sizeof(int));
if (ret < 0)
{
return ret;
}
}
break;
default:
ret = -ENOSYS;
break;
}
return ret;
}
static void tty_close(int fd)
{
printf("to close tty.\n");
}
static const fs_operations_t ops =
{
.fs_svr_close = tty_close,
.fs_svr_open = tty_open,
.fs_svr_read = tty_read,
.fs_svr_write = tty_write,
.fs_svr_ioctl = tty_ioctl,
};
void tty_svr_init(void)
{
int ret;
tty_struct_init(&sys_tty);
init_termios(&sys_tty.termios);
cons_init();
meta_obj_init(&tty_meta);
rpc_meta_init(&tty_meta, TASK_THIS, &tty_ipc_hd);
fs_init(&tty_fs, &ops);
meta_reg_svr_obj_raw(&tty_meta, &tty_fs.svr, FS_PROT);
ret = namespace_register("/dev/tty", tty_ipc_hd, 0);
if (ret < 0)
{
printf("tty driver reg failed [%d].\n", ret);
}
}

View File

@@ -0,0 +1,130 @@
#pragma once
#include <termios.h>
#include "u_queue.h"
#include "u_types.h"
#define TTY_QUEUE_DATA_SIZE 128
typedef struct tty_struct
{
struct termios termios; //!< 当前使用的终端信息
struct winsize w_size; //!< 窗口大小
// queue_t r_queue; //!< 最底层的数据首先读取到这里
// uint8_t r_queue_data[TTY_QUEUE_DATA_SIZE];
queue_t w_queue; //!< 写数据的缓存
uint8_t w_queue_data[TTY_QUEUE_DATA_SIZE];
queue_t pre_queue; //!< 然后通过handler处理机制存放到per_queue中pre_queue中的数据直接可以给用户或者进行回显
uint8_t pre_uque_data[TTY_QUEUE_DATA_SIZE];
// 有多少列
int col;
// 有多少行
int row;
// 字符错误
uint8_t is_error;
// 是否成行了
uint8_t is_nl;
pid_t fg_pid;
} tty_struct_t;
#define C_CC_INIT "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
// #define C_CC_INIT "\003\034\b\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
#define INTR_C(tty) ((tty)->termios.c_cc[VINTR])
#define QUIT_C(tty) ((tty)->termios.c_cc[VQUIT])
#define ERASE_C(tty) ((tty)->termios.c_cc[VERASE])
#define KILL_C(tty) ((tty)->termios.c_cc[VKILL])
#define EOF_C(tty) ((tty)->termios.c_cc[VEOF])
#define TIME_C(tty) ((tty)->termios.c_cc[VTIME])
#define MIN_C(tty) ((tty)->termios.c_cc[VMIN])
#define SWTC_C(tty) ((tty)->termios.c_cc[VSWTC])
#define START_C(tty) ((tty)->termios.c_cc[VSTART])
#define STOP_C(tty) ((tty)->termios.c_cc[VSTOP])
#define SUSP_C(tty) ((tty)->termios.c_cc[VSUSP])
#define EOL_C(tty) ((tty)->termios.c_cc[VEOL])
#define REPRINT_C(tty) ((tty)->termios.c_cc[VREPRINT])
#define DISCARD_C(tty) ((tty)->termios.c_cc[VDISCARD])
#define WERASE_C(tty) ((tty)->termios.c_cc[VWERASE])
#define LNEXT_C(tty) ((tty)->termios.c_cc[VLNEXT])
#define EOL2_C(tty) ((tty)->termios.c_cc[VEOL2])
#define _I_FLAG(tty, f) ((tty)->termios.c_iflag & (f))
#define _O_FLAG(tty, f) ((tty)->termios.c_oflag & (f))
#define _C_FLAG(tty, f) ((tty)->termios.c_cflag & (f))
#define _L_FLAG(tty, f) ((tty)->termios.c_lflag & (f))
#define I_IGNBRK(tty) _I_FLAG((tty), IGNBRK)
#define I_BRKINT(tty) _I_FLAG((tty), BRKINT)
#define I_IGNPAR(tty) _I_FLAG((tty), IGNPAR)
#define I_PARMRK(tty) _I_FLAG((tty), PARMRK)
#define I_INPCK(tty) _I_FLAG((tty), INPCK)
#define I_ISTRIP(tty) _I_FLAG((tty), ISTRIP)
#define I_INLCR(tty) _I_FLAG((tty), INLCR)
#define I_IGNCR(tty) _I_FLAG((tty), IGNCR)
#define I_ICRNL(tty) _I_FLAG((tty), ICRNL)
#define I_IUCLC(tty) _I_FLAG((tty), IUCLC)
#define I_IXON(tty) _I_FLAG((tty), IXON)
#define I_IXANY(tty) _I_FLAG((tty), IXANY)
#define I_IXOFF(tty) _I_FLAG((tty), IXOFF)
#define I_IMAXBEL(tty) _I_FLAG((tty), IMAXBEL)
#define O_OPOST(tty) _O_FLAG((tty), OPOST)
#define O_OLCUC(tty) _O_FLAG((tty), OLCUC)
#define O_ONLCR(tty) _O_FLAG((tty), ONLCR)
#define O_OCRNL(tty) _O_FLAG((tty), OCRNL)
#define O_ONOCR(tty) _O_FLAG((tty), ONOCR)
#define O_ONLRET(tty) _O_FLAG((tty), ONLRET)
#define O_OFILL(tty) _O_FLAG((tty), OFILL)
#define O_OFDEL(tty) _O_FLAG((tty), OFDEL)
#define O_NLDLY(tty) _O_FLAG((tty), NLDLY)
#define O_CRDLY(tty) _O_FLAG((tty), CRDLY)
#define O_TABDLY(tty) _O_FLAG((tty), TABDLY)
#define O_BSDLY(tty) _O_FLAG((tty), BSDLY)
#define O_VTDLY(tty) _O_FLAG((tty), VTDLY)
#define O_FFDLY(tty) _O_FLAG((tty), FFDLY)
#define O_XTABS(tty) _O_FLAG((tty), XTABS)
#define __C_FLAG(flag, f) ((flag) & (f))
#define C_BAUD(tty) _C_FLAG((tty), CBAUD)
#define C_CSIZE(tty) _C_FLAG((tty), CSIZE)
#define C_CSTOPB(tty) _C_FLAG((tty), CSTOPB)
#define C_CREAD(tty) _C_FLAG((tty), CREAD)
#define C_PARENB(tty) _C_FLAG((tty), PARENB)
#define C_PARODD(tty) _C_FLAG((tty), PARODD)
#define C_HUPCL(tty) _C_FLAG((tty), HUPCL)
#define C_CLOCAL(tty) _C_FLAG((tty), CLOCAL)
#define C_CIBAUD(tty) _C_FLAG((tty), CIBAUD)
#define C_CRTSCTS(tty) _C_FLAG((tty), CRTSCTS)
#define C_BAUDEX(tty) _C_FLAG((tty), CBAUDEX)
#define F_C_BAUD(tty) __C_FLAG((tty), CBAUD)
#define F_C_CSIZE(tty) __C_FLAG((tty), CSIZE)
#define F_C_CSTOPB(tty) __C_FLAG((tty), CSTOPB)
#define F_C_CREAD(tty) __C_FLAG((tty), CREAD)
#define F_C_PARENB(tty) __C_FLAG((tty), PARENB)
#define F_C_PARODD(tty) __C_FLAG((tty), PARODD)
#define F_C_HUPCL(tty) __C_FLAG((tty), HUPCL)
#define F_C_CLOCAL(tty) __C_FLAG((tty), CLOCAL)
#define F_C_CIBAUD(tty) __C_FLAG((tty), CIBAUD)
#define F_C_CRTSCTS(tty) __C_FLAG((tty), CRTSCTS)
#define F_C_BAUDEX(tty) __C_FLAG((tty), CBAUDEX)
#define L_ISIG(tty) _L_FLAG((tty), ISIG)
#define L_ICANON(tty) _L_FLAG((tty), ICANON)
#define L_XCASE(tty) _L_FLAG((tty), XCASE)
#define L_ECHO(tty) _L_FLAG((tty), ECHO)
#define L_ECHOE(tty) _L_FLAG((tty), ECHOE)
#define L_ECHOK(tty) _L_FLAG((tty), ECHOK)
#define L_ECHONL(tty) _L_FLAG((tty), ECHONL)
#define L_NOFLSH(tty) _L_FLAG((tty), NOFLSH)
#define L_TOSTOP(tty) _L_FLAG((tty), TOSTOP)
#define L_ECHOCTL(tty) _L_FLAG((tty), ECHOCTL)
#define L_ECHOPRT(tty) _L_FLAG((tty), ECHOPRT)
#define L_ECHOKE(tty) _L_FLAG((tty), ECHOKE)
#define L_FLUSHO(tty) _L_FLAG((tty), FLUSHO)
#define L_PENDIN(tty) _L_FLAG((tty), PENDIN)
#define L_IEXTEN(tty) _L_FLAG((tty), IEXTEN)
void tty_svr_init(void);
void tty_set_fg_pid(pid_t pid);

View File

@@ -51,7 +51,7 @@ int main(int args, char *argv[])
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_net");
printf("net startup..\n");
fast_ipc_init();
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
if (ret < 0)
{
printf("rpc meta init failed\n");

View File

@@ -66,7 +66,7 @@ int main(int argc, char *args[])
net_drv_init(&net_drv);
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
meta_reg_svr_obj(&net_drv.svr, BLK_DRV_PROT);

View File

@@ -19,6 +19,7 @@ int main(int argc, char *argv[])
{
printf("argv[%d]: %s\n", i, argv[i]);
}
exit(-1);
net_test();
fs_test3();
fs_test2();

View File

@@ -20,6 +20,9 @@ int main(int argc, char *argv[])
printf("open faile:%d.\n", fd);
return fd;
}
while(1){
u_sleep_ms(100000);
}
exit(-3333);
return 0;
}

View File

@@ -7,9 +7,19 @@
#include <unistd.h>
#include <u_vmam.h>
#include <u_sleep.h>
#include <termios.h>
#include <sys/stat.h>
extern int vi_main(int argc, char **argv);
static struct termios old_settings;
static struct termios new_settings;
int main(int argc, char *argv[])
{
tcgetattr(STDIN_FILENO, &old_settings);
new_settings = old_settings;
new_settings.c_lflag &= ~(ICANON | ECHO); // 禁用规范模式和回显
new_settings.c_cc[VMIN] = 1; // 读取的最小字符数
new_settings.c_cc[VTIME] = 0; // 读取的超时时间以10ms为单位
tcsetattr(STDIN_FILENO, TCSANOW, &new_settings);
printf("%s running..\n", argv[0]);
return vi_main(argc, argv);
}

View File

@@ -120,7 +120,7 @@ int main(int argc, char *argv[])
flash_init();
blk_drv_init(&blk_drv);
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
ns_register(argv[1], hd, 0);
meta_reg_svr_obj(&blk_drv.svr, BLK_DRV_PROT);

View File

@@ -41,7 +41,7 @@ int main(int argc, char *argv[])
drv_display_init();
dtb_parse_init();
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
fs_svr_init();
// mkdir("/dev", 0777);

View File

@@ -94,7 +94,7 @@ int main(int argc, char *argv[])
dtb_parse_init();
blk_drv_init(&net_drv);
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
// fs_svr_init();
// mkdir("/dev", 0777);

View File

@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
drv_i2c_init();
dtb_parse_init();
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
fs_svr_init();
// mkdir("/dev", 0777);

View File

@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
drv_pca9555_init();
dtb_parse_init();
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
fs_svr_init();
// mkdir("/dev", 0777);

View File

@@ -43,7 +43,7 @@ int main(int argc, char *argv[])
drv_pin_init();
dtb_parse_init();
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
fs_svr_init();
// mkdir("/dev", 0777);

View File

@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
dtb_parse_init();
blk_drv_init(&snd_drv);
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
ns_register("/snd", hd, 0);
meta_reg_svr_obj(&snd_drv.svr, BLK_DRV_PROT);

View File

@@ -120,7 +120,7 @@ int main(int argc, char *argv[])
flash_init();
blk_drv_init(&blk_drv);
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
ns_register(argv[1], hd, 0);
meta_reg_svr_obj(&blk_drv.svr, BLK_DRV_PROT);

View File

@@ -152,7 +152,7 @@ int main(int argc, char *argv[])
fast_ipc_init();
blk_drv_init(&blk_drv);
ret = rpc_meta_init(TASK_THIS, &hd);
ret = rpc_meta_init_def(TASK_THIS, &hd);
assert(ret >= 0);
ns_register(dev_path, hd, 0);
meta_reg_svr_obj(&blk_drv.svr, BLK_DRV_PROT);