diff options
-rw-r--r-- | demo.c | 10 | ||||
-rw-r--r-- | os/Makefile | 2 | ||||
-rw-r--r-- | os/include/filesystem.h | 14 | ||||
-rw-r--r-- | os/include/fio.h | 2 | ||||
-rw-r--r-- | os/include/hash-djb2.h | 8 | ||||
-rw-r--r-- | os/src/close.c | 10 | ||||
-rw-r--r-- | os/src/fclose.c | 1 | ||||
-rw-r--r-- | os/src/filesystem.c | 60 | ||||
-rw-r--r-- | os/src/fio.c | 37 | ||||
-rw-r--r-- | os/src/fopen.c | 6 | ||||
-rw-r--r-- | os/src/fwrite.c | 5 | ||||
-rw-r--r-- | os/src/hash-djb2.c | 15 | ||||
-rw-r--r-- | os/src/isatty.c | 12 | ||||
-rw-r--r-- | os/src/open.c | 15 | ||||
-rw-r--r-- | os/src/printf.c | 1 | ||||
-rw-r--r-- | os/src/write.c | 19 |
16 files changed, 203 insertions, 14 deletions
@@ -5,6 +5,7 @@ #include <BoardConsole.h> #include <osdebug.h> #include <stdio.h> +#include <fio.h> #define LED1_wire 18 #define LED2_wire 20 @@ -59,9 +60,18 @@ static void badTask(void *x) { *p = 42; } +static const char msg[] = "Hello world - from fwrite!\r\n"; + int main() { + FILE * f; + register_devfs(); handle = xSemaphoreCreateMutex(); printf("Hello world - from stdio!\r\n"); + fflush(stdout); + f = fopen("/dev/stdout", "w"); + fwrite(msg, 1, sizeof(msg), f); + fflush(f); + fclose(f); setupLEDs(); litLED(1, 0); litLED(2, 0); diff --git a/os/Makefile b/os/Makefile index bb74b34..909fd53 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/fio.c +src/printf.c src/fstat.c src/isatty.c src/fprintf.c src/fio.c src/fflush.c src/fopen.c src/open.c src/hash-djb2.c src/filesystem.c src/fwrite.c include $(ROOTDIR)/target-rules.mk diff --git a/os/include/filesystem.h b/os/include/filesystem.h new file mode 100644 index 0000000..4b50600 --- /dev/null +++ b/os/include/filesystem.h @@ -0,0 +1,14 @@ +#ifndef __FILESYSTEM_H__ +#define __FILESYSTEM_H__ + +#include <stdint.h> +#include <hash-djb2.h> + +#define MAX_FS 16 + +typedef int (*fs_open_t)(void * opaque, const char * fname, int flags, int mode); + +int register_fs(const char * mountpoint, fs_open_t callback, void * opaque); +int fs_open(const char * path, int flags, int mode); + +#endif diff --git a/os/include/fio.h b/os/include/fio.h index a1a1c1f..e4ba659 100644 --- a/os/include/fio.h +++ b/os/include/fio.h @@ -25,4 +25,6 @@ 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); +void register_devfs(); + #endif diff --git a/os/include/hash-djb2.h b/os/include/hash-djb2.h new file mode 100644 index 0000000..413222e --- /dev/null +++ b/os/include/hash-djb2.h @@ -0,0 +1,8 @@ +#ifndef __HASH_DJB2_H__ +#define __HASH_DJB2_H__ + +#include <unistd.h> + +uint32_t hash_djb2(const uint8_t * str, ssize_t max); + +#endif diff --git a/os/src/close.c b/os/src/close.c index aa4002b..90b22ed 100644 --- a/os/src/close.c +++ b/os/src/close.c @@ -1,7 +1,13 @@ #include <reent.h> #include <osdebug.h> +#include <errno.h> +#include "fio.h" int _close_r(struct _reent * reent, int fd) { - DBGOUT("_close_r(%p, %d)\r\n", reent, fd); - return 0; + if (!fio_is_open(fd)) { + reent->_errno = EBADF; + return -1; + } + + return fio_close(fd); } diff --git a/os/src/fclose.c b/os/src/fclose.c index 4721fde..76cf51d 100644 --- a/os/src/fclose.c +++ b/os/src/fclose.c @@ -3,6 +3,5 @@ #include <osdebug.h> int fclose(FILE * fp) { - DBGOUT("fclose(%p)\r\n", fp); return _fclose_r(_impure_ptr, fp); } diff --git a/os/src/filesystem.c b/os/src/filesystem.c new file mode 100644 index 0000000..64d7e0d --- /dev/null +++ b/os/src/filesystem.c @@ -0,0 +1,60 @@ +#include "filesystem.h" +#include "fio.h" +#include "osdebug.h" + +#include <stdint.h> +#include <string.h> +#include <hash-djb2.h> + +#define MAX_FS 16 + +struct fs_t { + uint32_t hash; + fs_open_t cb; + void * opaque; +}; + +static struct fs_t fss[MAX_FS]; + +__attribute__((constructor)) void fs_init() { + memset(fss, 0, sizeof(fss)); +} + +int register_fs(const char * mountpoint, fs_open_t callback, void * opaque) { + int i; + + for (i = 0; i < MAX_FS; i++) { + if (!fss[i].cb) { + fss[i].hash = hash_djb2((const uint8_t *) mountpoint, -1); + fss[i].cb = callback; + fss[i].opaque = opaque; + return 0; + } + } + + return -1; +} + +int fs_open(const char * path, int flags, int mode) { + const char * slash; + uint32_t hash; + int i; + + while (path[0] == '/') + path++; + + slash = strchr(path, '/'); + + if (!slash) + return -2; + + hash = hash_djb2((const uint8_t *) path, slash - path); + path = slash + 1; + + for (i = 0; i < MAX_FS; i++) { + if (fss[i].hash == hash) + return fss[i].cb(fss[i].opaque, path, flags, mode); + } + + return -2; +} diff --git a/os/src/fio.c b/os/src/fio.c index bd3f8ae..b7e225a 100644 --- a/os/src/fio.c +++ b/os/src/fio.c @@ -2,7 +2,14 @@ #include <string.h> #include <FreeRTOS.h> #include <semphr.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include "fio.h" +#include "filesystem.h" +#include "osdebug.h" +#include "hash-djb2.h" static struct fddef_t fio_fds[MAX_FDS]; @@ -138,3 +145,33 @@ int fio_close(int fd) { } return r; } + +#define stdin_hash 0x0BA00421 +#define stdout_hash 0x7FA08308 +#define stderr_hash 0x7FA058A3 + +static int devfs_open(void * opaque, const char * path, int flags, int mode) { + uint32_t h = hash_djb2((const uint8_t *) path, -1); + switch (h) { + case stdin_hash: + if (flags & (O_WRONLY | O_RDWR)) + return -1; + return fio_open(stdin_read, NULL, NULL, NULL, NULL); + break; + case stdout_hash: + if (flags & O_RDONLY) + return -1; + return fio_open(NULL, stdout_write, NULL, NULL, NULL); + break; + case stderr_hash: + if (flags & O_RDONLY) + return -1; + return fio_open(NULL, stdout_write, NULL, NULL, NULL); + break; + } + return -1; +} + +void register_devfs() { + register_fs("dev", devfs_open, NULL); +} diff --git a/os/src/fopen.c b/os/src/fopen.c new file mode 100644 index 0000000..e8b4246 --- /dev/null +++ b/os/src/fopen.c @@ -0,0 +1,6 @@ +#include <stdio.h> +#include <reent.h> + +FILE * fopen(const char * path, const char * mode) { + return _fopen_r(_impure_ptr, path, mode); +} diff --git a/os/src/fwrite.c b/os/src/fwrite.c new file mode 100644 index 0000000..c6890dc --- /dev/null +++ b/os/src/fwrite.c @@ -0,0 +1,5 @@ +#include <stdio.h> + +size_t fwrite(const void * ptr, size_t size, size_t nmemb, FILE * file) { + return _fwrite_r(_impure_ptr, ptr, size, nmemb, file); +} diff --git a/os/src/hash-djb2.c b/os/src/hash-djb2.c new file mode 100644 index 0000000..82dd741 --- /dev/null +++ b/os/src/hash-djb2.c @@ -0,0 +1,15 @@ +#include <stdint.h> +#include "hash-djb2.h" +#include "osdebug.h" + +uint32_t hash_djb2(const uint8_t * str, ssize_t _max) { + uint32_t hash = 5381; + uint32_t max = (uint32_t) _max; + int c; + + while (((c = *str++)) && max--) { + hash = ((hash << 5) + hash) ^ c; + } + + return hash; +} diff --git a/os/src/isatty.c b/os/src/isatty.c index 69fef64..051284f 100644 --- a/os/src/isatty.c +++ b/os/src/isatty.c @@ -2,14 +2,12 @@ #include <reent.h> #include <errno.h> #include "fio.h" -#include "osdebug.h" 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; + if (!fio_is_open(fd)) { + reent->_errno = EBADF; + return 0; + } + reent->_errno = EINVAL; return 0; } diff --git a/os/src/open.c b/os/src/open.c new file mode 100644 index 0000000..7a2c147 --- /dev/null +++ b/os/src/open.c @@ -0,0 +1,15 @@ +#include <stdio.h> +#include <reent.h> +#include <errno.h> +#include "fio.h" +#include "filesystem.h" + +int _open_r(struct _reent * reent, const char * path, int flags, int mode) { + int r = fs_open(path, flags, mode); + + if (r >= 0) + return r; + + reent->_errno = EACCES; + return -1; +} diff --git a/os/src/printf.c b/os/src/printf.c index 599857c..83f7539 100644 --- a/os/src/printf.c +++ b/os/src/printf.c @@ -6,7 +6,6 @@ int printf(const char * fmt, ...) { int r; va_list ap; - DBGOUT("printf(%p, ...)\r\n", fmt); va_start(ap, fmt); r = _vprintf_r(_impure_ptr, fmt, ap); va_end(ap); diff --git a/os/src/write.c b/os/src/write.c index 50fadc6..268c0f1 100644 --- a/os/src/write.c +++ b/os/src/write.c @@ -1,7 +1,22 @@ #include <reent.h> #include <osdebug.h> +#include <errno.h> +#include "fio.h" _ssize_t _write_r(struct _reent * reent, int fd, const void * buf, size_t size) { - DBGOUT("_write_r(%p, %d, %p, %u)\r\n", reent, fd, buf, size); - return 0; + int r; + + if (!fio_is_open(fd)) { + reent->_errno = EBADF; + return -1; + } + + r = fio_write(fd, buf, size); + + if (r < 0) { + reent->_errno = EINVAL; + return -1; + } + + return r; } |