summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas "Pixel" Noble <pixel@nobis-crew.org>2011-01-29 03:15:44 +0100
committerNicolas "Pixel" Noble <pixel@nobis-crew.org>2011-01-29 03:15:44 +0100
commit499e349afa57536ce80497aa99f61c5492e3733e (patch)
treefe3308c344659e800172cfaad9793918f24ae4b1
parent5754656f65205ff1fd9b23c2a85778b3671caf68 (diff)
More filesystem stuff working. devfs is now in place with stdin, stdout, and stderr.
-rw-r--r--demo.c10
-rw-r--r--os/Makefile2
-rw-r--r--os/include/filesystem.h14
-rw-r--r--os/include/fio.h2
-rw-r--r--os/include/hash-djb2.h8
-rw-r--r--os/src/close.c10
-rw-r--r--os/src/fclose.c1
-rw-r--r--os/src/filesystem.c60
-rw-r--r--os/src/fio.c37
-rw-r--r--os/src/fopen.c6
-rw-r--r--os/src/fwrite.c5
-rw-r--r--os/src/hash-djb2.c15
-rw-r--r--os/src/isatty.c12
-rw-r--r--os/src/open.c15
-rw-r--r--os/src/printf.c1
-rw-r--r--os/src/write.c19
16 files changed, 203 insertions, 14 deletions
diff --git a/demo.c b/demo.c
index fd9b76a..cde181a 100644
--- a/demo.c
+++ b/demo.c
@@ -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;
}