forked from xuos/xiuos
Adjust directory structure
This commit is contained in:
3
Ubiquitous/XiUOS/fs/shared/Makefile
Normal file
3
Ubiquitous/XiUOS/fs/shared/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
SRC_DIR := src
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
133
Ubiquitous/XiUOS/fs/shared/include/iot-vfs.h
Normal file
133
Ubiquitous/XiUOS/fs/shared/include/iot-vfs.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef _INC_IOT_VFS_H_
|
||||
#define _INC_IOT_VFS_H_
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <bus.h>
|
||||
|
||||
#define MAX_FILE_NAME 255
|
||||
#define MAX_PATH MAX_FILE_NAME
|
||||
|
||||
enum FilesystemType
|
||||
{
|
||||
FSTYPE_FATFS = 0,
|
||||
FSTYPE_IOTDEVICEFILE,
|
||||
FSTYPE_CH376,
|
||||
FSTYPE_END,
|
||||
};
|
||||
|
||||
enum x_FileType
|
||||
{
|
||||
FTYPE_FILE = 0,
|
||||
FTYPE_DIR,
|
||||
FTYPE_SOCKET,
|
||||
FTYPE_END,
|
||||
};
|
||||
|
||||
struct Filesystem;
|
||||
|
||||
struct MountPoint
|
||||
{
|
||||
struct SysDoubleLinklistNode node;
|
||||
enum FilesystemType fs_type;
|
||||
char *mnt_point;
|
||||
size_t mnt_point_len;
|
||||
void *fs_data;
|
||||
BusType bus;
|
||||
HardwareDevType dev;
|
||||
DriverType drv;
|
||||
struct Filesystem *fs;
|
||||
};
|
||||
|
||||
struct FileStat
|
||||
{
|
||||
enum x_FileType type;
|
||||
char name[MAX_FILE_NAME + 1];
|
||||
size_t size;
|
||||
time_t mtime;
|
||||
};
|
||||
|
||||
struct statfs
|
||||
{
|
||||
size_t f_bsize;
|
||||
size_t f_blocks;
|
||||
size_t f_bfree;
|
||||
};
|
||||
|
||||
#define FD_MAX 64
|
||||
#define FD_OFFSET 3
|
||||
|
||||
struct FileDescriptor
|
||||
{
|
||||
char *path;
|
||||
enum x_FileType type;
|
||||
void *data;
|
||||
struct MountPoint *mntp;
|
||||
off_t pos;
|
||||
};
|
||||
|
||||
int NewFileDescriptor(struct FileDescriptor **fdptr);
|
||||
struct FileDescriptor *GetFileDescriptor(int fd);
|
||||
void FreeFileDescriptor(struct FileDescriptor *fdp);
|
||||
|
||||
struct dirent
|
||||
{
|
||||
int d_kind;
|
||||
char d_name[MAX_PATH + 1];
|
||||
};
|
||||
|
||||
/* NOTE: all path arguments must be relative path under mount point */
|
||||
struct Filesystem
|
||||
{
|
||||
int (*open)(struct FileDescriptor *fdp, const char *path);
|
||||
int (*close)(struct FileDescriptor *fdp);
|
||||
ssize_t (*read)(struct FileDescriptor *fdp, void *dst, size_t len);
|
||||
ssize_t (*write)(struct FileDescriptor *fdp, const void *src, size_t len);
|
||||
int (*seek)(struct FileDescriptor *fdp, off_t offset, int whence, off_t *new_offset);
|
||||
off_t (*tell)(struct FileDescriptor *fdp);
|
||||
int (*truncate)(struct FileDescriptor *fdp, off_t length);
|
||||
int (*sync)(struct FileDescriptor *fdp);
|
||||
|
||||
int (*ioctl)(struct FileDescriptor *fdp, int cmd, void *args);
|
||||
int (*poll)(struct FileDescriptor *fdp, struct Pollreq *req);
|
||||
|
||||
int (*opendir)(struct FileDescriptor *fdp, const char *path);
|
||||
int (*closedir)(struct FileDescriptor *fdp);
|
||||
int (*readdir)(struct FileDescriptor *fdp, struct dirent *dirent);
|
||||
int (*seekdir)(struct FileDescriptor *fdp, off_t offset);
|
||||
|
||||
int (*mount)(struct MountPoint *mp);
|
||||
int (*unmount)(struct MountPoint *mp);
|
||||
int (*unlink)(struct MountPoint *mp, const char *path);
|
||||
int (*rename)(struct MountPoint *mp, const char *from,
|
||||
const char *to);
|
||||
int (*mkdir)(struct MountPoint *mp, const char *path);
|
||||
int (*stat)(struct MountPoint *mp, const char *path,
|
||||
struct FileStat *buf);
|
||||
int (*statvfs)(struct MountPoint *mp, const char *path,
|
||||
struct statfs *buf);
|
||||
};
|
||||
|
||||
int RegisterFilesystem(enum FilesystemType fs_type,
|
||||
struct Filesystem *fs);
|
||||
|
||||
int MountFilesystem(const char *bus_name,
|
||||
const char *dev_name, const char *drv_name,
|
||||
enum FilesystemType fs_type, const char *path);
|
||||
|
||||
int UnmountFileSystem(const char *path);
|
||||
|
||||
void SyncOpenedFiles();
|
||||
|
||||
#endif /* _INC_IOT_VFS_H_ */
|
||||
52
Ubiquitous/XiUOS/fs/shared/include/iot-vfs_posix.h
Normal file
52
Ubiquitous/XiUOS/fs/shared/include/iot-vfs_posix.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef _IOT_VFS_POSIX_H_
|
||||
#define _IOT_VFS_POSIX_H_
|
||||
|
||||
#include <iot-vfs.h>
|
||||
|
||||
typedef void DIR;
|
||||
|
||||
#if defined(LIB_NEWLIB) && defined(_EXFUN)
|
||||
_READ_WRITE_RETURN_TYPE _EXFUN(read, (int __fd, void *__buf, size_t __nbyte));
|
||||
_READ_WRITE_RETURN_TYPE _EXFUN(write, (int __fd, const void *__buf, size_t __nbyte));
|
||||
#else
|
||||
int read(int fd, void *buf, size_t len);
|
||||
int write(int fd, const void *buf, size_t len);
|
||||
#endif
|
||||
|
||||
int open(const char *path, int flags, ...);
|
||||
int close(int fd);
|
||||
int ioctl(int fd, int cmd, void *args);
|
||||
off_t lseek(int fd, off_t offset, int whence);
|
||||
int rename(const char *from, const char *to);
|
||||
int unlink(const char *path);
|
||||
int stat(const char *path, struct stat *buf);
|
||||
int fstat(int fd, struct stat *buf);
|
||||
int fsync(int fd);
|
||||
int ftruncate(int fd, off_t length);
|
||||
|
||||
int mkdir(const char *path, mode_t mode);
|
||||
DIR *opendir(const char *path);
|
||||
int closedir(DIR *dirp);
|
||||
struct dirent *readdir(DIR *dirp);
|
||||
int rmdir(const char *path);
|
||||
int chdir(const char *path);
|
||||
char *getcwd(char *buf, size_t size);
|
||||
long telldir(DIR *dirp);
|
||||
void seekdir(DIR *dirp, off_t offset);
|
||||
void rewinddir(DIR *dirp);
|
||||
|
||||
int statfs(const char *path, struct statfs *buf);
|
||||
|
||||
#endif
|
||||
26
Ubiquitous/XiUOS/fs/shared/include/vfs_select.h
Normal file
26
Ubiquitous/XiUOS/fs/shared/include/vfs_select.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#ifndef VFS_SELECT_H__
|
||||
#define VFS_SELECT_H__
|
||||
|
||||
#include <libc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
4
Ubiquitous/XiUOS/fs/shared/src/Makefile
Normal file
4
Ubiquitous/XiUOS/fs/shared/src/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
SRC_FILES := poll.c select.c iot-vfs.c
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
1181
Ubiquitous/XiUOS/fs/shared/src/iot-vfs.c
Normal file
1181
Ubiquitous/XiUOS/fs/shared/src/iot-vfs.c
Normal file
File diff suppressed because it is too large
Load Diff
198
Ubiquitous/XiUOS/fs/shared/src/poll.c
Normal file
198
Ubiquitous/XiUOS/fs/shared/src/poll.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <xs_poll.h>
|
||||
#include <device.h>
|
||||
#include <xiuos.h>
|
||||
#include <iot-vfs.h>
|
||||
#include <iot-vfs_posix.h>
|
||||
|
||||
|
||||
void PollAdd(WaitQueueType *wq, pollreqType *req)
|
||||
{
|
||||
if (req && req->_proc && wq)
|
||||
req->_proc(wq, req);
|
||||
}
|
||||
|
||||
|
||||
struct rt_poll_node;
|
||||
|
||||
struct rt_poll_table
|
||||
{
|
||||
pollreqType req;
|
||||
uint32 triggered;
|
||||
KTaskDescriptorType polling_thread;
|
||||
struct rt_poll_node *nodes;
|
||||
};
|
||||
|
||||
struct rt_poll_node
|
||||
{
|
||||
struct WaitqueueNode wqn;
|
||||
struct rt_poll_table *pt;
|
||||
struct rt_poll_node *next;
|
||||
};
|
||||
|
||||
static int WqueuePollWake(struct WaitqueueNode *wait, void *key)
|
||||
{
|
||||
struct rt_poll_node *pn;
|
||||
|
||||
if (key && !((x_ubase)key & wait->key))
|
||||
return -1;
|
||||
|
||||
pn =CONTAINER_OF(wait, struct rt_poll_node, wqn);
|
||||
pn->pt->triggered = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _poll_add(WaitQueueType *wq, pollreqType *req)
|
||||
{
|
||||
struct rt_poll_table *pt;
|
||||
struct rt_poll_node *node;
|
||||
|
||||
node = (struct rt_poll_node *)x_malloc(sizeof(struct rt_poll_node));
|
||||
if (node == NONE)
|
||||
return;
|
||||
|
||||
pt =CONTAINER_OF(req, struct rt_poll_table, req);
|
||||
|
||||
node->wqn.key = req->_key;
|
||||
InitDoubleLinkList(&(node->wqn.list));
|
||||
node->wqn.polling_task = pt->polling_thread;
|
||||
node->wqn.cb = WqueuePollWake;
|
||||
node->next = pt->nodes;
|
||||
node->pt = pt;
|
||||
pt->nodes = node;
|
||||
WqueueAdd(wq, &node->wqn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int PollWaitTimeout(struct rt_poll_table *pt, int msec)
|
||||
{
|
||||
int32 timeout;
|
||||
int ret = 0;
|
||||
struct TaskDescriptor *thread;
|
||||
x_base level;
|
||||
|
||||
thread = pt->polling_thread;
|
||||
|
||||
timeout = CalculteTickFromTimeMs(msec);
|
||||
|
||||
level = CriticalAreaLock();
|
||||
|
||||
if (timeout != 0 && !pt->triggered) {
|
||||
SuspendKTask(thread->id.id);
|
||||
if (timeout > 0)
|
||||
KTaskSetDelay(thread,timeout);
|
||||
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
level = CriticalAreaLock();
|
||||
}
|
||||
|
||||
ret = !pt->triggered;
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int DoPollFd(struct pollfd *pollfd, pollreqType *req)
|
||||
{
|
||||
int mask = 0;
|
||||
int fd;
|
||||
|
||||
fd = pollfd->fd;
|
||||
|
||||
if (fd >= 0) {
|
||||
struct FileDescriptor *fdp = GetFileDescriptor(fd);
|
||||
mask = POLLNVAL;
|
||||
|
||||
if (fdp) {
|
||||
mask = POLLMASK_DEFAULT;
|
||||
if (fdp->mntp->fs->poll) {
|
||||
req->_key = pollfd->events | POLLERR | POLLHUP;
|
||||
|
||||
mask = fdp->mntp->fs->poll(fdp, req);
|
||||
}
|
||||
/* Mask out unneeded events. */
|
||||
mask &= pollfd->events | POLLERR | POLLHUP;
|
||||
}
|
||||
}
|
||||
pollfd->revents = mask;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static int PollDo(struct pollfd *fds, NfdsType nfds, struct rt_poll_table *pt, int msec)
|
||||
{
|
||||
int num;
|
||||
int istimeout = 0;
|
||||
int n;
|
||||
struct pollfd *pf;
|
||||
|
||||
if (msec == 0) {
|
||||
pt->req._proc = NONE;
|
||||
istimeout = 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
pf = fds;
|
||||
num = 0;
|
||||
|
||||
for (n = 0; n < nfds; n ++) {
|
||||
if (DoPollFd(pf, &pt->req)) {
|
||||
num ++;
|
||||
pt->req._proc = NONE;
|
||||
}
|
||||
pf ++;
|
||||
}
|
||||
|
||||
pt->req._proc = NONE;
|
||||
|
||||
if (num || istimeout)
|
||||
break;
|
||||
|
||||
if (PollWaitTimeout(pt, msec))
|
||||
istimeout = 1;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
int poll(struct pollfd *fds, NfdsType nfds, int timeout)
|
||||
{
|
||||
int num;
|
||||
struct rt_poll_table table;
|
||||
struct rt_poll_node *node, *temp;
|
||||
|
||||
table.req._proc = _poll_add;
|
||||
table.triggered = 0;
|
||||
table.nodes = NULL;
|
||||
table.polling_thread = GetKTaskDescriptor();
|
||||
|
||||
num = PollDo(fds, nfds, &table, timeout);
|
||||
|
||||
node = table.nodes;
|
||||
while (node) {
|
||||
temp = node;
|
||||
node= node->next;
|
||||
WqueueRemove(&temp->wqn);
|
||||
x_free(temp);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
182
Ubiquitous/XiUOS/fs/shared/src/select.c
Normal file
182
Ubiquitous/XiUOS/fs/shared/src/select.c
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-12-28 Bernard first version
|
||||
*/
|
||||
|
||||
#include <iot-vfs.h>
|
||||
#include <iot-vfs_posix.h>
|
||||
#include <xs_poll.h>
|
||||
#include <vfs_select.h>
|
||||
|
||||
#ifdef LIB_POSIX
|
||||
|
||||
static void fdszero(fd_set *set, int nfds)
|
||||
{
|
||||
fd_mask *m;
|
||||
int n;
|
||||
|
||||
/*
|
||||
The 'sizeof(fd_set)' of the system space may differ from user space,
|
||||
so the actual size of the 'fd_set' is determined here with the parameter 'nfds'
|
||||
*/
|
||||
m = (fd_mask *)set;
|
||||
for (n = 0; n < nfds; n += (sizeof(fd_mask) * 8))
|
||||
{
|
||||
memset(m, 0, sizeof(fd_mask));
|
||||
m ++;
|
||||
}
|
||||
}
|
||||
|
||||
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
|
||||
{
|
||||
int fd;
|
||||
int npfds;
|
||||
int msec;
|
||||
int ndx;
|
||||
int ret;
|
||||
struct pollfd *pollset = NONE;
|
||||
|
||||
/* How many pollfd structures do we need to allocate? */
|
||||
for (fd = 0, npfds = 0; fd < nfds; fd++)
|
||||
{
|
||||
/* Check if any monitor operation is requested on this fd */
|
||||
if ((readfds && FD_ISSET(fd, readfds)) ||
|
||||
(writefds && FD_ISSET(fd, writefds)) ||
|
||||
(exceptfds && FD_ISSET(fd, exceptfds)))
|
||||
{
|
||||
npfds++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the descriptor list for poll() */
|
||||
if (npfds > 0)
|
||||
{
|
||||
pollset = (struct pollfd *)x_calloc(npfds, sizeof(struct pollfd));
|
||||
if (!pollset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the descriptor list for poll() */
|
||||
for (fd = 0, ndx = 0; fd < nfds; fd++)
|
||||
{
|
||||
int incr = 0;
|
||||
|
||||
/* The readfs set holds the set of FDs that the caller can be assured
|
||||
* of reading from without blocking. Note that POLLHUP is included as
|
||||
* a read-able condition. POLLHUP will be reported at the end-of-file
|
||||
* or when a connection is lost. In either case, the read() can then
|
||||
* be performed without blocking.
|
||||
*/
|
||||
|
||||
if (readfds && FD_ISSET(fd, readfds))
|
||||
{
|
||||
pollset[ndx].fd = fd;
|
||||
pollset[ndx].events |= POLLIN;
|
||||
incr = 1;
|
||||
}
|
||||
|
||||
if (writefds && FD_ISSET(fd, writefds))
|
||||
{
|
||||
pollset[ndx].fd = fd;
|
||||
pollset[ndx].events |= POLLOUT;
|
||||
incr = 1;
|
||||
}
|
||||
|
||||
if (exceptfds && FD_ISSET(fd, exceptfds))
|
||||
{
|
||||
pollset[ndx].fd = fd;
|
||||
incr = 1;
|
||||
}
|
||||
|
||||
ndx += incr;
|
||||
}
|
||||
|
||||
CHECK(ndx == npfds);
|
||||
|
||||
/* Convert the timeout to milliseconds */
|
||||
if (timeout)
|
||||
{
|
||||
msec = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
msec = -1;
|
||||
}
|
||||
|
||||
/* Then let poll do all of the real work. */
|
||||
|
||||
ret = poll(pollset, npfds, msec);
|
||||
|
||||
/* Now set up the return values */
|
||||
if (readfds)
|
||||
{
|
||||
fdszero(readfds, nfds);
|
||||
}
|
||||
|
||||
if (writefds)
|
||||
{
|
||||
fdszero(writefds, nfds);
|
||||
}
|
||||
|
||||
if (exceptfds)
|
||||
{
|
||||
fdszero(exceptfds, nfds);
|
||||
}
|
||||
|
||||
/* Convert the poll descriptor list back into selects 3 bitsets */
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
ret = 0;
|
||||
for (ndx = 0; ndx < npfds; ndx++)
|
||||
{
|
||||
/* Check for read conditions. Note that POLLHUP is included as a
|
||||
* read condition. POLLHUP will be reported when no more data will
|
||||
* be available (such as when a connection is lost). In either
|
||||
* case, the read() can then be performed without blocking.
|
||||
*/
|
||||
|
||||
if (readfds)
|
||||
{
|
||||
if (pollset[ndx].revents & (POLLIN | POLLHUP))
|
||||
{
|
||||
FD_SET(pollset[ndx].fd, readfds);
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for write conditions */
|
||||
if (writefds)
|
||||
{
|
||||
if (pollset[ndx].revents & POLLOUT)
|
||||
{
|
||||
FD_SET(pollset[ndx].fd, writefds);
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for exceptions */
|
||||
if (exceptfds)
|
||||
{
|
||||
if (pollset[ndx].revents & POLLERR)
|
||||
{
|
||||
FD_SET(pollset[ndx].fd, exceptfds);
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pollset) x_free(pollset);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user