diff options
-rw-r--r-- | os/Makefile | 2 | ||||
-rw-r--r-- | os/include/fio.h | 28 | ||||
-rw-r--r-- | os/src/fio.c | 140 | ||||
-rw-r--r-- | os/src/fstat.c | 23 | ||||
-rw-r--r-- | os/src/init.c | 14 | ||||
-rw-r--r-- | os/src/isatty.c | 11 |
6 files changed, 205 insertions, 13 deletions
diff --git a/os/Makefile b/os/Makefile index 2dee1e9..bb74b34 100644 --- a/os/Makefile +++ b/os/Makefile @@ -8,7 +8,7 @@ include $(ROOTDIR)/FreeRTOS/config.mk include $(ROOTDIR)/arch/config.mk TARGET_SRCS = src/init.c src/sbrk.c src/sprintf.c src/malloc.c src/free.c src/fclose.c src/read.c src/lseek.c src/write.c src/close.c src/osdebug.c \ -src/printf.c src/fstat.c src/isatty.c src/fprintf.c +src/printf.c src/fstat.c src/isatty.c src/fprintf.c src/fio.c include $(ROOTDIR)/target-rules.mk diff --git a/os/include/fio.h b/os/include/fio.h new file mode 100644 index 0000000..a1a1c1f --- /dev/null +++ b/os/include/fio.h @@ -0,0 +1,28 @@ +#ifndef __FIO_H__ +#define __FIO_H__ + +#include <stdio.h> + +#define MAX_FDS 32 + +typedef ssize_t (*fdread_t)(void * opaque, void * buf, size_t count); +typedef ssize_t (*fdwrite_t)(void * opaque, const void * buf, size_t count); +typedef off_t (*fdseek_t)(void * opaque, off_t offset, int whence); +typedef int (*fdclose_t)(void * opaque); + +struct fddef_t { + fdread_t fdread; + fdwrite_t fdwrite; + fdseek_t fdseek; + fdclose_t fdclose; + void * opaque; +}; + +int fio_is_open(int fd); +int fio_open(fdread_t, fdwrite_t, fdseek_t, fdclose_t, void * opaque); +ssize_t fio_read(int fd, void * buf, size_t count); +ssize_t fio_write(int fd, const void * buf, size_t count); +off_t fio_seek(int fd, off_t offset, int whence); +int fio_close(int fd); + +#endif diff --git a/os/src/fio.c b/os/src/fio.c new file mode 100644 index 0000000..bd3f8ae --- /dev/null +++ b/os/src/fio.c @@ -0,0 +1,140 @@ +#include <BoardConsole.h> +#include <string.h> +#include <FreeRTOS.h> +#include <semphr.h> +#include "fio.h" + +static struct fddef_t fio_fds[MAX_FDS]; + +static ssize_t stdin_read(void * opaque, void * buf, size_t count) { + return 0; +} + +static ssize_t stdout_write(void * opaque, const void * buf, size_t count) { + int i; + const char * data = (const char *) buf; + + for (i = 0; i < count; i++) + BoardConsolePutc(data[i]); + + return count; +} + +static xSemaphoreHandle fio_sem = NULL; + +__attribute__((constructor)) static void fio_init() { + memset(fio_fds, 0, sizeof(fio_fds)); + fio_fds[0].fdread = stdin_read; + fio_fds[1].fdwrite = stdout_write; + fio_fds[2].fdwrite = stdout_write; + fio_sem = xSemaphoreCreateMutex(); +} + +struct fddef_t * fio_getfd(int fd) { + if ((fd < 0) || (fd >= MAX_FDS)) + return NULL; + return fio_fds + fd; +} + +static int fio_is_open_int(int fd) { + if ((fd < 0) || (fd >= MAX_FDS)) + return 0; + int r = !((fio_fds[fd].fdread == NULL) && + (fio_fds[fd].fdwrite == NULL) && + (fio_fds[fd].fdseek == NULL) && + (fio_fds[fd].fdclose == NULL) && + (fio_fds[fd].opaque == NULL)); + return r; +} + +static int fio_findfd() { + int i; + + for (i = 0; i < MAX_FDS; i++) { + if (!fio_is_open_int(i)) + return i; + } + + return -1; +} + +int fio_is_open(int fd) { + int r = 0; + xSemaphoreTake(fio_sem, portMAX_DELAY); + r = fio_is_open_int(fd); + xSemaphoreGive(fio_sem); + return r; +} + +int fio_open(fdread_t fdread, fdwrite_t fdwrite, fdseek_t fdseek, fdclose_t fdclose, void * opaque) { + int fd; + xSemaphoreTake(fio_sem, portMAX_DELAY); + fd = fio_findfd(); + + if (fd >= 0) { + fio_fds[fd].fdread = fdread; + fio_fds[fd].fdwrite = fdwrite; + fio_fds[fd].fdseek = fdseek; + fio_fds[fd].fdclose = fdclose; + fio_fds[fd].opaque = opaque; + } + xSemaphoreGive(fio_sem); + + return fd; +} + +ssize_t fio_read(int fd, void * buf, size_t count) { + ssize_t r = 0; + if (fio_is_open_int(fd)) { + if (fio_fds[fd].fdread) { + r = fio_fds[fd].fdread(fio_fds[fd].opaque, buf, count); + } else { + r = -3; + } + } else { + r = -2; + } + return r; +} + +ssize_t fio_write(int fd, const void * buf, size_t count) { + ssize_t r = 0; + if (fio_is_open_int(fd)) { + if (fio_fds[fd].fdwrite) { + r = fio_fds[fd].fdwrite(fio_fds[fd].opaque, buf, count); + } else { + r = -3; + } + } else { + r = -2; + } + return r; +} + +off_t fio_seek(int fd, off_t offset, int whence) { + off_t r = 0; + if (fio_is_open_int(fd)) { + if (fio_fds[fd].fdseek) { + r = fio_fds[fd].fdseek(fio_fds[fd].opaque, offset, whence); + } else { + r = -3; + } + } else { + r = -2; + } + return r; +} + +int fio_close(int fd) { + int r = 0; + if (fio_is_open_int(fd)) { + if (fio_fds[fd].fdclose) + r = fio_fds[fd].fdclose(fio_fds[fd].opaque); + xSemaphoreTake(fio_sem, portMAX_DELAY); + memset(fio_fds + fd, 0, sizeof(struct fddef_t)); + xSemaphoreGive(fio_sem); + } else { + r = -2; + } + return r; +} diff --git a/os/src/fstat.c b/os/src/fstat.c index a756206..b10194c 100644 --- a/os/src/fstat.c +++ b/os/src/fstat.c @@ -1,8 +1,25 @@ #include <reent.h> #include <sys/stat.h> -#include "osdebug.h" +#include <string.h> +#include <errno.h> +#include "fio.h" + +int _fstat_r(struct _reent * reent, int fd, struct stat * buf) { + off_t c; + memset(buf, 0, sizeof(struct stat)); + + if (!fio_is_open(fd)) { + reent->_errno = EBADF; + return -1; + } + + buf->st_mode = S_IFCHR; + buf->st_blksize = 1024; + c = fio_seek(fd, 0, SEEK_CUR); + if (c >= 0) { + buf->st_size = fio_seek(fd, 0, SEEK_END); + fio_seek(fd, c, SEEK_SET); + } -int _fstat_r(struct _reent * ptr, int fildes, struct stat * buf) { - DBGOUT("_fstat_r(%p, %d, %p)\r\n", ptr, fildes, buf); return 0; } diff --git a/os/src/init.c b/os/src/init.c index 6d10950..5ab7899 100644 --- a/os/src/init.c +++ b/os/src/init.c @@ -1,13 +1,13 @@ #include <stdlib.h> #include <BoardConsole.h> -extern void __libc_init_array(); -extern void __libc_fini_array(); -extern int main(int, char **, char **); -extern void BoardEarlyInit(); -extern void BoardLateInit(); -extern void BoardExceptionHandler(int); -extern void BoardShutdown(); +void __libc_init_array(); +void __libc_fini_array(); +int main(int, char **, char **); +void BoardEarlyInit(); +void BoardLateInit(); +void BoardExceptionHandler(int); +void BoardShutdown(); void _exit(int return_code) __attribute__((noreturn)); void _exit(int return_code) { diff --git a/os/src/isatty.c b/os/src/isatty.c index baf78e4..69fef64 100644 --- a/os/src/isatty.c +++ b/os/src/isatty.c @@ -1,8 +1,15 @@ #include <unistd.h> #include <reent.h> +#include <errno.h> +#include "fio.h" #include "osdebug.h" -int _isatty_r(struct _reent * ptr, int fildes) { - DBGOUT("_isatty_r(%p, %d)\r\n", ptr, fildes); +int _isatty_r(struct _reent * reent, int fd) { + DBGOUT("_isatty_r(%p, %d)\r\n", reent, fd); +// if (!fio_is_open(fd)) { +// reent->_errno = EBADF; +// return 0; +// } +// reent->_errno = EINVAL; return 0; } |