summaryrefslogtreecommitdiff
path: root/os/src/fio.c
diff options
context:
space:
mode:
Diffstat (limited to 'os/src/fio.c')
-rw-r--r--os/src/fio.c140
1 files changed, 140 insertions, 0 deletions
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;
+}