文件描述符自动回收支持
This commit is contained in:
@@ -22,4 +22,5 @@ add_subdirectory(printf)
|
||||
add_subdirectory(lwip)
|
||||
add_subdirectory(cJSON)
|
||||
add_subdirectory(cutest)
|
||||
add_subdirectory(fd)
|
||||
|
||||
|
||||
19
mkrtos_user/lib/fd/CMakeLists.txt
Normal file
19
mkrtos_user/lib/fd/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
|
||||
file(GLOB_RECURSE deps *.c *.S)
|
||||
add_library(
|
||||
fd
|
||||
STATIC
|
||||
${deps}
|
||||
)
|
||||
target_include_directories(
|
||||
fd
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/fd/
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc/${ARCH_NAME}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_util/inc
|
||||
)
|
||||
|
||||
|
||||
114
mkrtos_user/lib/fd/fd.c
Normal file
114
mkrtos_user/lib/fd/fd.c
Normal file
@@ -0,0 +1,114 @@
|
||||
|
||||
#include "u_types.h"
|
||||
#include "u_hd_man.h"
|
||||
#include <u_mutex.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <u_sig.h>
|
||||
#include "fd.h"
|
||||
|
||||
#define FILE_DESC_NR_OPEN 8
|
||||
static file_desc_t file_desc[FILE_DESC_NR_OPEN];
|
||||
static u_mutex_t fds_lock;
|
||||
|
||||
static int fs_sig_call_back(pid_t pid, umword_t sig_val)
|
||||
{
|
||||
switch (sig_val)
|
||||
{
|
||||
case KILL_SIG:
|
||||
file_desc_recycle(pid);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int file_desc_init(void)
|
||||
{
|
||||
int ret;
|
||||
obj_handler_t sema_hd;
|
||||
|
||||
sema_hd = handler_alloc();
|
||||
if (sema_hd == HANDLER_INVALID)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
ret = u_mutex_init(&fds_lock, sema_hd);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
pm_sig_func_set(fs_sig_call_back);
|
||||
return ret;
|
||||
}
|
||||
int file_desc_alloc(pid_t pid, void *priv, void (*close_fn)(int fd))
|
||||
{
|
||||
u_mutex_lock(&fds_lock, 0, NULL);
|
||||
for (int i = 0; i < FILE_DESC_NR_OPEN; i++)
|
||||
{
|
||||
if (file_desc[i].close == NULL)
|
||||
{
|
||||
file_desc[i].pid = pid;
|
||||
file_desc[i].priv = priv;
|
||||
file_desc[i].close = close_fn;
|
||||
u_mutex_unlock(&fds_lock);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
u_mutex_unlock(&fds_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
int file_desc_set_priv(int fd, void *priv)
|
||||
{
|
||||
if (fd < 0 || fd >= FILE_DESC_NR_OPEN)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
file_desc[fd].priv = priv;
|
||||
return 0;
|
||||
}
|
||||
file_desc_t *file_desc_get(int fd)
|
||||
{
|
||||
if (fd < 0 || fd >= FILE_DESC_NR_OPEN)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return &file_desc[fd];
|
||||
}
|
||||
void *file_desc_free_unlock(int fd)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (fd < 0 || fd >= FILE_DESC_NR_OPEN)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
file_desc[fd].pid = 0;
|
||||
ret = file_desc[fd].priv;
|
||||
file_desc[fd].priv = NULL;
|
||||
file_desc[fd].close = NULL;
|
||||
return ret;
|
||||
}
|
||||
void *file_desc_free(int fd)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
u_mutex_lock(&fds_lock, 0, NULL);
|
||||
ret = file_desc_free_unlock(fd);
|
||||
u_mutex_unlock(&fds_lock);
|
||||
return ret;
|
||||
}
|
||||
void file_desc_recycle(pid_t pid)
|
||||
{
|
||||
int free_cn = 0;
|
||||
|
||||
u_mutex_lock(&fds_lock, 0, NULL);
|
||||
for (int i = 0; i < FILE_DESC_NR_OPEN; i++)
|
||||
{
|
||||
if (file_desc[i].close != NULL && file_desc[i].pid == pid)
|
||||
{
|
||||
file_desc[i].close(i);
|
||||
printf("free fd:%d.\n", i);
|
||||
}
|
||||
}
|
||||
u_mutex_unlock(&fds_lock);
|
||||
}
|
||||
18
mkrtos_user/lib/fd/fd.h
Normal file
18
mkrtos_user/lib/fd/fd.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <u_types.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct file_desc
|
||||
{
|
||||
pid_t pid;
|
||||
void (*close)(int fd);
|
||||
void *priv;
|
||||
} file_desc_t;
|
||||
|
||||
int file_desc_init(void);
|
||||
int file_desc_alloc(pid_t pid, void *priv, void (*close_fn)(int fd));
|
||||
int file_desc_set_priv(int fd, void *priv);
|
||||
file_desc_t *file_desc_get(int fd);
|
||||
void *file_desc_free_unlock(int fd);
|
||||
void *file_desc_free(int fd);
|
||||
void file_desc_recycle(pid_t pid);
|
||||
@@ -35,7 +35,7 @@ RPC_GENERATION_OP2(sig_t, SIG_PORT, SIG_TOKILL, to_kill,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, resv)
|
||||
{
|
||||
if (!obj->op->kill)
|
||||
if (!obj->op->to_kill)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
enum signal_val
|
||||
{
|
||||
KILL_SIG,
|
||||
@@ -8,5 +8,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);
|
||||
void pm_sig_func_set(sig_call_back sig_func);
|
||||
sig_call_back pm_sig_func_set(sig_call_back sig_func);
|
||||
int pm_sig_del_watch(pid_t pid, int flags);
|
||||
@@ -40,9 +40,12 @@ int pm_sig_del_watch(pid_t pid, int flags)
|
||||
{
|
||||
return pm_del_watch_pid(pid, flags);
|
||||
}
|
||||
void pm_sig_func_set(sig_call_back sig_func)
|
||||
sig_call_back pm_sig_func_set(sig_call_back sig_func)
|
||||
{
|
||||
sig_call_back tmp = sig_cb_func;
|
||||
|
||||
sig_cb_func = sig_func;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int kill(int flags, int pid)
|
||||
|
||||
@@ -13,41 +13,66 @@
|
||||
#include <string.h>
|
||||
#include "kstat.h"
|
||||
#include "appfs_open.h"
|
||||
|
||||
static fs_t fs;
|
||||
|
||||
static int fs_sig_call_back(pid_t pid, umword_t sig_val)
|
||||
{
|
||||
switch (sig_val)
|
||||
{
|
||||
case KILL_SIG:
|
||||
appfs_task_free(pid);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fs_svr_open(const char *path, int flags, int mode)
|
||||
{
|
||||
int fd;
|
||||
pid_t pid = thread_get_src_pid();
|
||||
|
||||
fd = appfs_open(path, flags, mode);
|
||||
|
||||
if (fd >= 0)
|
||||
{
|
||||
#ifdef CONFIG_USING_SIG
|
||||
int w_ret = pm_sig_watch(pid, 0 /*TODO:现在只有kill */);
|
||||
if (w_ret < 0)
|
||||
{
|
||||
printf("pm wath pid %d err.\n", w_ret);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int fs_svr_read(int fd, void *buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
ret = appfs_read(fd, buf, len);
|
||||
ret = appfs_read(fd, buf, len);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
int fs_svr_write(int fd, void *buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
ret = appfs_write(fd, buf, len);
|
||||
return ret;
|
||||
ret = appfs_write(fd, buf, len);
|
||||
return ret;
|
||||
}
|
||||
void fs_svr_close(int fd)
|
||||
{
|
||||
appfs_close(fd);
|
||||
appfs_close(fd);
|
||||
}
|
||||
int fs_svr_readdir(int fd, dirent_t *dir)
|
||||
{
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
ret = appfs_readdir(fd, dir);
|
||||
return ret;
|
||||
ret = appfs_readdir(fd, dir);
|
||||
return ret;
|
||||
}
|
||||
int fs_svr_lseek(int fd, int offs, int whence)
|
||||
{
|
||||
@@ -146,7 +171,9 @@ static const fs_operations_t ops =
|
||||
};
|
||||
void fs_svr_init(void)
|
||||
{
|
||||
|
||||
fs_init(&fs, &ops);
|
||||
meta_reg_svr_obj(&fs.svr, FS_PROT);
|
||||
#ifdef CONFIG_USING_SIG
|
||||
pm_sig_func_set(fs_sig_call_back);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include "appfs.h"
|
||||
|
||||
#ifdef MKRTOS
|
||||
#include <u_thread.h>
|
||||
#endif
|
||||
static fs_info_t *fs;
|
||||
|
||||
#define DIR_INFO_CACHE_NR 32
|
||||
@@ -78,16 +80,27 @@ typedef struct appfs_file
|
||||
uint8_t flags; //!< 文件操作的flags
|
||||
int offset; //!< 文件操作的偏移
|
||||
enum appfs_type type; //!< 类型
|
||||
uint8_t used;
|
||||
// int pid; //!< 属于哪个进程
|
||||
// pthread_mutex_t mutex; //!< 锁
|
||||
uint8_t used; //!< 使用中
|
||||
int pid; //!< 属于哪个进程
|
||||
} appfs_file_t;
|
||||
|
||||
static appfs_file_t appfs_files[DIR_INFO_NR];
|
||||
|
||||
static appfs_file_t *appfs_get_file(int fd);
|
||||
|
||||
static int appfs_file_alloc(const dir_info_t *file, int flags, enum appfs_type type)
|
||||
void appfs_task_free(int pid)
|
||||
{
|
||||
for (int i = 0; i < DIR_INFO_NR; i++)
|
||||
{
|
||||
if (appfs_files[i].dir_info_fd != -1)
|
||||
{
|
||||
appfs_close(i);
|
||||
printf("free fd:%d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int appfs_file_alloc(const dir_info_t *file, int flags, enum appfs_type type, int pid)
|
||||
{
|
||||
int dir_info_fd = -1;
|
||||
|
||||
@@ -108,11 +121,10 @@ static int appfs_file_alloc(const dir_info_t *file, int flags, enum appfs_type t
|
||||
// 不存在则增加一个新的
|
||||
appfs_files[i].dir_info_fd = dir_info_fd;
|
||||
appfs_files[i].flags = flags;
|
||||
// appfs_files[i].pid = pid;
|
||||
appfs_files[i].pid = pid;
|
||||
appfs_files[i].offset = 0;
|
||||
appfs_files[i].type = type;
|
||||
appfs_files[i].used = 1;
|
||||
// pthread_mutex_init(&appfs_files[i].mutex, NULL);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -134,6 +146,11 @@ static appfs_file_t *appfs_get_file(int fd)
|
||||
|
||||
int appfs_open(const char *name, int flags, int mode)
|
||||
{
|
||||
#ifdef MKRTOS
|
||||
int pid = thread_get_src_pid();
|
||||
#else
|
||||
int pid = 0;
|
||||
#endif
|
||||
int ret;
|
||||
const dir_info_t *file;
|
||||
int fd;
|
||||
@@ -163,7 +180,7 @@ int appfs_open(const char *name, int flags, int mode)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
fd = appfs_file_alloc(file, flags, type);
|
||||
fd = appfs_file_alloc(file, flags, type, pid);
|
||||
if (fd < 0)
|
||||
{
|
||||
return fd;
|
||||
@@ -171,7 +188,7 @@ int appfs_open(const char *name, int flags, int mode)
|
||||
}
|
||||
else if (type == APPFS_DIR_TYPE)
|
||||
{
|
||||
fd = appfs_file_alloc(NULL, flags, type);
|
||||
fd = appfs_file_alloc(NULL, flags, type, pid);
|
||||
if (fd < 0)
|
||||
{
|
||||
return fd;
|
||||
@@ -233,7 +250,7 @@ int appfs_read(int fd, void *data, int len)
|
||||
int appfs_ioctl(int fd, unsigned long cmd, unsigned long arg)
|
||||
{
|
||||
#ifdef MKRTOS
|
||||
pid_t src_pid = thread_get_src_pid();
|
||||
int src_pid = thread_get_src_pid();
|
||||
#endif
|
||||
appfs_file_t *file = appfs_get_file(fd);
|
||||
int ret = 0;
|
||||
@@ -440,7 +457,7 @@ int appfs_close(int fd)
|
||||
}
|
||||
}
|
||||
file->dir_info_fd = -1;
|
||||
// file->pid = -1;
|
||||
file->pid = -1;
|
||||
file->flags = 0;
|
||||
file->offset = 0;
|
||||
file->used = 0;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <dirent.h>
|
||||
#include "appfs.h"
|
||||
#include "kstat.h"
|
||||
#include <u_types.h>
|
||||
enum appfs_ioctl_cmd_op
|
||||
{
|
||||
APPFS_IOCTOL_GET_ACCESS_ADDR,
|
||||
@@ -13,6 +14,7 @@ typedef struct appfs_ioctl_arg
|
||||
unsigned long size;
|
||||
} appfs_ioctl_arg_t;
|
||||
|
||||
void appfs_task_free(int pid);
|
||||
int appfs_open(const char *name, int flags, int mode);
|
||||
int appfs_write(int fd, void *data, int len);
|
||||
int appfs_read(int fd, void *data, int len);
|
||||
|
||||
@@ -26,6 +26,7 @@ target_link_libraries(
|
||||
sys
|
||||
sys_util
|
||||
sys_svr
|
||||
fd
|
||||
# stm32f1_bsp
|
||||
${GCC_LIB_PATH}/libgcc.a
|
||||
)
|
||||
@@ -41,12 +42,15 @@ target_include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/stm32f1_bsp/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/stm32f1_bsp/core_inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/fs/fatfs/ext_disk_drv
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/fd
|
||||
)
|
||||
add_dependencies(
|
||||
fatfs.elf
|
||||
${START_LIB}
|
||||
sys
|
||||
sys_util
|
||||
fd
|
||||
# stm32f1_bsp
|
||||
)
|
||||
set_target_properties(
|
||||
|
||||
@@ -14,76 +14,22 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <u_malloc.h>
|
||||
#include "fd.h"
|
||||
static fs_t fs;
|
||||
static int fs_sig_call_back(pid_t pid, umword_t sig_val);
|
||||
|
||||
typedef struct file_desc
|
||||
typedef struct file_desc_priv
|
||||
{
|
||||
union
|
||||
{
|
||||
FIL fp;
|
||||
FATFS_DIR dir;
|
||||
};
|
||||
pid_t pid;
|
||||
uint8_t type; //!< 0:file 1:dir
|
||||
} file_desc_t;
|
||||
} file_desc_priv_t;
|
||||
|
||||
#define FILE_DESC_NR 8 //!< 最多同时可以打开多少个文件
|
||||
static file_desc_t files[FILE_DESC_NR]; //!< 预先设置的文件描述符
|
||||
void fs_svr_close(int fd);
|
||||
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++)
|
||||
{
|
||||
if (files[i].fp.obj.fs == NULL)
|
||||
{
|
||||
*fd = i;
|
||||
files[i].pid = thread_get_src_pid();
|
||||
return &files[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static void free_file(int fd)
|
||||
{
|
||||
files[fd].fp.obj.fs = NULL;
|
||||
}
|
||||
static file_desc_t *file_get(int fd)
|
||||
{
|
||||
if (fd < 0 || fd >= FILE_DESC_NR)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (files[fd].fp.obj.fs == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return files + fd;
|
||||
}
|
||||
static int fatfs_err_conv(FRESULT res)
|
||||
{
|
||||
switch (res)
|
||||
@@ -116,15 +62,23 @@ static int fatfs_err_conv(FRESULT res)
|
||||
}
|
||||
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);
|
||||
file_desc_priv_t *file = NULL;
|
||||
|
||||
if (!file)
|
||||
file = u_malloc(sizeof(*file));
|
||||
if (file == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fd = file_desc_alloc(pid, file, fs_svr_close);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
u_free(file);
|
||||
return fd;
|
||||
}
|
||||
int new_mode = 0;
|
||||
|
||||
switch (flags & O_ACCMODE)
|
||||
@@ -164,7 +118,8 @@ int fs_svr_open(const char *path, int flags, int mode)
|
||||
if (ret != FR_OK)
|
||||
{
|
||||
cons_write_str("open fail..\n");
|
||||
free_file(fd);
|
||||
file_desc_free(fd);
|
||||
u_free(file);
|
||||
return fatfs_err_conv(ret);
|
||||
}
|
||||
file->type = 1;
|
||||
@@ -179,6 +134,8 @@ int fs_svr_open(const char *path, int flags, int mode)
|
||||
|
||||
if (ret != FR_OK)
|
||||
{
|
||||
file_desc_free(fd);
|
||||
u_free(file);
|
||||
return fatfs_err_conv(ret);
|
||||
}
|
||||
#ifdef CONFIG_USING_SIG
|
||||
@@ -194,17 +151,19 @@ int fs_svr_open(const char *path, int flags, int mode)
|
||||
int fs_svr_read(int fd, void *buf, size_t len)
|
||||
{
|
||||
UINT br;
|
||||
file_desc_t *file = file_get(fd);
|
||||
file_desc_t *file = file_desc_get(fd);
|
||||
file_desc_priv_t *file_priv = NULL;
|
||||
|
||||
if (!file)
|
||||
if (!file || file->priv == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
if (file->type != 0)
|
||||
file_priv = file->priv;
|
||||
if (file_priv->type != 0)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
FRESULT ret = f_read(&file->fp, buf, len, &br);
|
||||
FRESULT ret = f_read(&file_priv->fp, buf, len, &br);
|
||||
|
||||
if (ret != FR_OK)
|
||||
{
|
||||
@@ -215,17 +174,19 @@ int fs_svr_read(int fd, void *buf, size_t len)
|
||||
int fs_svr_write(int fd, void *buf, size_t len)
|
||||
{
|
||||
UINT bw;
|
||||
file_desc_t *file = file_get(fd);
|
||||
file_desc_t *file = file_desc_get(fd);
|
||||
file_desc_priv_t *file_priv = NULL;
|
||||
|
||||
if (!file)
|
||||
if (!file || file->priv == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
if (file->type != 0)
|
||||
file_priv = file->priv;
|
||||
if (file_priv->type != 0)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
FRESULT ret = f_write(&file->fp, buf, len, &bw);
|
||||
FRESULT ret = f_write(&file_priv->fp, buf, len, &bw);
|
||||
|
||||
if (ret != FR_OK)
|
||||
{
|
||||
@@ -235,33 +196,40 @@ int fs_svr_write(int fd, void *buf, size_t len)
|
||||
}
|
||||
void fs_svr_close(int fd)
|
||||
{
|
||||
file_desc_t *file = file_get(fd);
|
||||
file_desc_t *file = file_desc_get(fd);
|
||||
file_desc_priv_t *file_priv = NULL;
|
||||
|
||||
if (!file)
|
||||
if (!file || file->priv == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (file->type)
|
||||
file_priv = file->priv;
|
||||
|
||||
switch (file_priv->type)
|
||||
{
|
||||
case 0:
|
||||
f_close(&file->fp);
|
||||
f_close(&file_priv->fp);
|
||||
break;
|
||||
case 1:
|
||||
f_closedir(&file->dir);
|
||||
f_closedir(&file_priv->dir);
|
||||
break;
|
||||
}
|
||||
file->fp.obj.fs = NULL;
|
||||
file_priv->fp.obj.fs = NULL;
|
||||
file_desc_free_unlock(fd);
|
||||
u_free(file_priv);
|
||||
}
|
||||
int fs_svr_readdir(int fd, dirent_t *dir)
|
||||
{
|
||||
file_desc_t *file = file_get(fd);
|
||||
file_desc_t *file = file_desc_get(fd);
|
||||
file_desc_priv_t *file_priv = NULL;
|
||||
|
||||
if (!file)
|
||||
if (!file || file->priv == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
file_priv = file->priv;
|
||||
FILINFO info;
|
||||
FRESULT ret = f_readdir(&file->dir, &info);
|
||||
FRESULT ret = f_readdir(&file_priv->dir, &info);
|
||||
|
||||
if (ret != FR_OK || info.fname[0] == 0)
|
||||
{
|
||||
@@ -284,14 +252,18 @@ int fs_svr_readdir(int fd, dirent_t *dir)
|
||||
int fs_svr_lseek(int fd, int offs, int whence)
|
||||
{
|
||||
UINT bw;
|
||||
file_desc_t *file = file_get(fd);
|
||||
file_desc_t *file = file_desc_get(fd);
|
||||
file_desc_priv_t *file_priv = NULL;
|
||||
|
||||
int new_offs = 0;
|
||||
|
||||
if (!file)
|
||||
if (!file || file->priv == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
if (file->type != 0)
|
||||
file_priv = file->priv;
|
||||
|
||||
if (file_priv->type != 0)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
@@ -302,58 +274,62 @@ int fs_svr_lseek(int fd, int offs, int whence)
|
||||
break;
|
||||
case SEEK_END:
|
||||
{
|
||||
new_offs = f_size(&file->fp) + offs;
|
||||
new_offs = f_size(&file_priv->fp) + offs;
|
||||
}
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
{
|
||||
new_offs = offs + f_tell(&file->fp);
|
||||
new_offs = offs + f_tell(&file_priv->fp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
#if 0
|
||||
if (new_offs > f_size(&file->fp)) {
|
||||
new_offs = f_size(&file->fp);
|
||||
if (new_offs > f_size(&file_priv->fp)) {
|
||||
new_offs = f_size(&file_priv->fp);
|
||||
}
|
||||
#endif
|
||||
if (new_offs < 0)
|
||||
{
|
||||
new_offs = 0;
|
||||
}
|
||||
FRESULT ret = f_lseek(&file->fp, new_offs);
|
||||
FRESULT ret = f_lseek(&file_priv->fp, new_offs);
|
||||
|
||||
return fatfs_err_conv(ret);
|
||||
}
|
||||
int fs_svr_ftruncate(int fd, off_t off)
|
||||
{
|
||||
file_desc_t *file = file_get(fd);
|
||||
file_desc_t *file = file_desc_get(fd);
|
||||
file_desc_priv_t *file_priv = NULL;
|
||||
|
||||
if (!file)
|
||||
if (!file || file->priv == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
if (file->type != 0)
|
||||
file_priv = file->priv;
|
||||
if (file_priv->type != 0)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
FRESULT ret = f_truncate(&file->fp);
|
||||
FRESULT ret = f_truncate(&file_priv->fp);
|
||||
|
||||
return fatfs_err_conv(ret);
|
||||
}
|
||||
int fs_svr_fstat(int fd, void *_stat)
|
||||
{
|
||||
struct kstat *stat = _stat;
|
||||
file_desc_t *file = file_get(fd);
|
||||
file_desc_t *file = file_desc_get(fd);
|
||||
file_desc_priv_t *file_priv = NULL;
|
||||
|
||||
if (!file)
|
||||
if (!file || file->priv == NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
file_priv = file->priv;
|
||||
memset(stat, 0, sizeof(*stat));
|
||||
stat->st_size = file->type == 1 ? 0 : f_size(&file->fp);
|
||||
stat->st_mode = file->type == 1 ? S_IFDIR : S_IFREG;
|
||||
stat->st_size = file_priv->type == 1 ? 0 : f_size(&file_priv->fp);
|
||||
stat->st_mode = file_priv->type == 1 ? S_IFDIR : S_IFREG;
|
||||
stat->st_blksize = 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -363,17 +339,19 @@ int fs_svr_ioctl(int fd, int req, void *arg)
|
||||
}
|
||||
int fs_svr_fsync(int fd)
|
||||
{
|
||||
file_desc_t *file = file_get(fd);
|
||||
file_desc_t *file = file_desc_get(fd);
|
||||
file_desc_priv_t *file_priv = NULL;
|
||||
|
||||
if (!file)
|
||||
if (!file || file->priv == NULL)
|
||||
{
|
||||
return -EBADFD;
|
||||
}
|
||||
if (file->type != 0)
|
||||
file_priv = file->priv;
|
||||
if (file_priv->type != 0)
|
||||
{
|
||||
return -EBADFD;
|
||||
}
|
||||
f_sync(&file->fp);
|
||||
f_sync(&file_priv->fp);
|
||||
return 0;
|
||||
}
|
||||
int fs_svr_unlink(const char *path)
|
||||
@@ -457,7 +435,5 @@ void fs_svr_init(void)
|
||||
{
|
||||
fs_init(&fs, &ops);
|
||||
meta_reg_svr_obj(&fs.svr, FS_PROT);
|
||||
#ifdef CONFIG_USING_SIG
|
||||
pm_sig_func_set(fs_sig_call_back);
|
||||
#endif
|
||||
file_desc_init();
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ static bool_t pm_send_sig_to_task(pm_t *pm, pid_t pid, umword_t sig_val)
|
||||
}
|
||||
slist_del(&pos->node);
|
||||
handler_free_umap(pos->sig_hd); //!< 删除信号通知的ipc
|
||||
handler_del_umap(pos->watch_pid); //!< 删除被watch的进程
|
||||
handler_free_umap(pos->watch_pid); //!< 删除被watch的进程
|
||||
u_free(pos);
|
||||
}
|
||||
pos = next;
|
||||
|
||||
@@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.13)
|
||||
# add_subdirectory(coremark)
|
||||
# add_subdirectory(tinycc-arm-thumb)
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(test2)
|
||||
add_subdirectory(vi)
|
||||
add_subdirectory(binutils-2.33.1)
|
||||
# add_subdirectory(share_lib_test)
|
||||
|
||||
64
mkrtos_user/user/app/test2/CMakeLists.txt
Normal file
64
mkrtos_user/user/app/test2/CMakeLists.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
|
||||
file(
|
||||
GLOB deps
|
||||
*.c
|
||||
)
|
||||
|
||||
add_executable(
|
||||
tst2.elf
|
||||
${deps}
|
||||
${START_SRC}
|
||||
)
|
||||
target_link_libraries(
|
||||
tst2.elf
|
||||
PUBLIC
|
||||
-Bstatic
|
||||
${LIBC_NAME}
|
||||
--whole-archive
|
||||
${START_LIB}
|
||||
libc_be
|
||||
sys
|
||||
sys_util
|
||||
sys_svr
|
||||
--no-whole-archive
|
||||
${GCC_LIB_PATH}/libgcc.a
|
||||
)
|
||||
target_include_directories(
|
||||
tst2.elf
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/user/drv/lib/mk_pin
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/user/drv/lib/mk_drv
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/user/drv/lib/mk_display
|
||||
)
|
||||
add_dependencies(
|
||||
tst2.elf
|
||||
${START_LIB}
|
||||
sys
|
||||
sys_util
|
||||
)
|
||||
set_target_properties(
|
||||
tst2.elf PROPERTIES LINK_FLAGS
|
||||
"-T ${CMAKE_CURRENT_LIST_DIR}/${ARCH_NAME}/link.lds ${CORTEX_M_LINK_FLAGS} --gc-section -no-dynamic-linker "
|
||||
#--no-warn-rwx-segments
|
||||
)
|
||||
add_custom_target(
|
||||
tst2_dump ALL
|
||||
COMMAND
|
||||
${CMAKE_OBJCOPY} -O binary -S tst2.elf tst2.bin
|
||||
COMMAND
|
||||
${CMAKE_SIZE} tst2.elf
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy tst2.bin ${CMAKE_SOURCE_DIR}/build/output/cpio/tst2
|
||||
COMMAND
|
||||
cp tst2.elf ${CMAKE_SOURCE_DIR}/build/output/tst2.elf
|
||||
)
|
||||
|
||||
add_dependencies(tst2_dump tst2.elf)
|
||||
|
||||
124
mkrtos_user/user/app/test2/armv7_8m/link.lds
Normal file
124
mkrtos_user/user/app/test2/armv7_8m/link.lds
Normal file
@@ -0,0 +1,124 @@
|
||||
ENTRY(_start_)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
. = ALIGN(4);
|
||||
__text_start__ = .;
|
||||
KEEP(*(.first))
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(SORT(.rodata.*))
|
||||
*(.rodata)
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
|
||||
. = ALIGN(4);
|
||||
__rel_start__ = .;
|
||||
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
|
||||
__rel_end__ = .;
|
||||
}
|
||||
.ARM.exidx : {
|
||||
. = ALIGN(4);
|
||||
__exdix_start = .;
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
/* This is used by the startup in order to initialize the .data secion */
|
||||
__exdix_end = .;
|
||||
}
|
||||
|
||||
.permissions_table : {
|
||||
. = ALIGN(4);
|
||||
__permissions_table_start__ = .;
|
||||
KEEP(*(.permissions_table))
|
||||
__permissions_table_end__ = .;
|
||||
}
|
||||
|
||||
|
||||
PROVIDE(__ram_size__ = __bss_end__ - __data_start__);
|
||||
.data : {
|
||||
. = ALIGN(4);
|
||||
__data_start__ = .;
|
||||
__got_start__ = .;
|
||||
*(.got)
|
||||
__got_end__ = .;
|
||||
. = ALIGN(4);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
_shell_command_start = .;
|
||||
KEEP(*(shellCommand))
|
||||
_shell_command_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
}
|
||||
|
||||
PROVIDE(__heap_size__ = __heap_end__ - __heap_start__);
|
||||
PROVIDE(__stack_size__ = __stack_end__ - __stack_start__);
|
||||
.bss : {
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
__heap_start__ = .;
|
||||
KEEP(*(.bss.heap))
|
||||
__heap_end__ = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__stack_start__ = .;
|
||||
KEEP(*(.bss.stack))
|
||||
__stack_end__ = .;
|
||||
|
||||
*(.bss.*)
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
}
|
||||
_end = .;
|
||||
}
|
||||
17
mkrtos_user/user/app/test2/heap_stack.c
Normal file
17
mkrtos_user/user/app/test2/heap_stack.c
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
#define HEAP_SIZE (10*1024)
|
||||
#define STACK_SIZE (1024 * 2)
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#define HEAP_ATTR SECTION("HEAP") __attribute__((zero_init))
|
||||
#define STACK_ATTR SECTION("STACK") __attribute__((zero_init))
|
||||
#elif defined(__GNUC__)
|
||||
#define HEAP_ATTR __attribute__((__section__(".bss.heap")))
|
||||
#define STACK_ATTR __attribute__((__section__(".bss.stack")))
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
#define HEAP_ATTR
|
||||
#define STACK_ATTR
|
||||
#endif
|
||||
|
||||
__attribute__((used)) HEAP_ATTR static char _____heap_____[HEAP_SIZE];
|
||||
__attribute__((used)) STACK_ATTR static char _____stack_____[STACK_SIZE];
|
||||
24
mkrtos_user/user/app/test2/main.c
Normal file
24
mkrtos_user/user/app/test2/main.c
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
#include "u_task.h"
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <u_sleep.h>
|
||||
#include <u_vmam.h>
|
||||
#include <unistd.h>
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int fd;
|
||||
|
||||
task_set_obj_name(TASK_THIS, TASK_THIS, "tk_tst2");
|
||||
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_tst2");
|
||||
fd = open("/mnt/1.txt", O_RDWR | O_CREAT, 0777);
|
||||
if (fd < 0) {
|
||||
printf("open faile:%d.\n", fd);
|
||||
return fd;
|
||||
}
|
||||
exit(-3333);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user