diff --git a/.gitmodules b/.gitmodules index 00dadd8..d3fc285 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,3 +14,6 @@ [submodule "extras/spiffs/spiffs"] path = extras/spiffs/spiffs url = https://github.com/pellepl/spiffs.git +[submodule "examples/posix_fs/fs-test"] + path = examples/posix_fs/fs-test + url = https://github.com/sheinz/fs-test diff --git a/core/newlib_syscalls.c b/core/newlib_syscalls.c index 023872c..c8104a9 100644 --- a/core/newlib_syscalls.c +++ b/core/newlib_syscalls.c @@ -41,7 +41,7 @@ IRAM caddr_t _sbrk_r (struct _reent *r, int incr) } /* syscall implementation for stdio write to UART */ -long _write_r(struct _reent *r, int fd, const char *ptr, int len ) +__attribute__((weak)) long _write_r(struct _reent *r, int fd, const char *ptr, int len ) { if(fd != r->_stdout->_file) { r->_errno = EBADF; @@ -79,10 +79,20 @@ __attribute__((weak)) long _read_r( struct _reent *r, int fd, char *ptr, int len /* Stub syscall implementations follow, to allow compiling newlib functions that pull these in via various codepaths */ -__attribute__((alias("syscall_returns_enosys"))) int _open_r(struct _reent *r, const char *pathname, int flags, int mode); -__attribute__((alias("syscall_returns_enosys"))) int _fstat_r(struct _reent *r, int fd, void *buf); -__attribute__((alias("syscall_returns_enosys"))) int _close_r(struct _reent *r, int fd); -__attribute__((alias("syscall_returns_enosys"))) off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence); +__attribute__((weak, alias("syscall_returns_enosys"))) +int _open_r(struct _reent *r, const char *pathname, int flags, int mode); + +__attribute__((weak, alias("syscall_returns_enosys"))) +int _close_r(struct _reent *r, int fd); + +__attribute__((weak, alias("syscall_returns_enosys"))) +int _unlink_r(struct _reent *r, const char *path); + +__attribute__((alias("syscall_returns_enosys"))) +int _fstat_r(struct _reent *r, int fd, void *buf); + +__attribute__((alias("syscall_returns_enosys"))) +off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence); /* Generic stub for any newlib syscall that fails with errno ENOSYS ("Function not implemented") and a return value equivalent to diff --git a/examples/posix_fs/Makefile b/examples/posix_fs/Makefile new file mode 100644 index 0000000..bf45ed7 --- /dev/null +++ b/examples/posix_fs/Makefile @@ -0,0 +1,11 @@ +PROGRAM=posix_fs_example +PROGRAM_EXTRA_SRC_FILES=./fs-test/fs_test.c + +EXTRA_COMPONENTS = extras/spiffs +FLASH_SIZE = 32 + +# spiffs configuration +SPIFFS_BASE_ADDR = 0x200000 +SPIFFS_SIZE = 0x100000 + +include ../../common.mk diff --git a/examples/posix_fs/fs-test b/examples/posix_fs/fs-test new file mode 160000 index 0000000..983ed83 --- /dev/null +++ b/examples/posix_fs/fs-test @@ -0,0 +1 @@ +Subproject commit 983ed830a8d2bd1a3eaa586ed608530f9d29201e diff --git a/examples/posix_fs/posix_fs_example.c b/examples/posix_fs/posix_fs_example.c new file mode 100644 index 0000000..7e3ad8f --- /dev/null +++ b/examples/posix_fs/posix_fs_example.c @@ -0,0 +1,41 @@ +#include "espressif/esp_common.h" +#include "esp/uart.h" +#include "FreeRTOS.h" +#include "task.h" +#include "esp8266.h" +#include + +#include "esp_spiffs.h" +#include "spiffs.h" + +#include "fs-test/fs_test.h" + + +void test_task(void *pvParameters) +{ + esp_spiffs_mount(); + esp_spiffs_unmount(); // FS must be unmounted before formating + if (SPIFFS_format(&fs) == SPIFFS_OK) { + printf("Format complete\n"); + } else { + printf("Format failed\n"); + } + esp_spiffs_mount(); + + while (1) { + vTaskDelay(5000 / portTICK_RATE_MS); + + if (fs_test_run(10000)) { + printf("PASS\n"); + } else { + printf("FAIL\n"); + } + } +} + +void user_init(void) +{ + uart_set_baud(0, 115200); + + xTaskCreate(test_task, (signed char *)"test_task", 1024, NULL, 2, NULL); +} diff --git a/extras/spiffs/esp_spiffs.c b/extras/spiffs/esp_spiffs.c index d6ec7d6..194d697 100644 --- a/extras/spiffs/esp_spiffs.c +++ b/extras/spiffs/esp_spiffs.c @@ -9,6 +9,7 @@ #include "spiffs.h" #include #include +#include spiffs fs; @@ -185,3 +186,53 @@ void esp_spiffs_unmount() fds_buf = 0; cache_buf = 0; } + +/* syscall implementation for stdio write to UART */ +long _write_r(struct _reent *r, int fd, const char *ptr, int len ) +{ + if(fd != r->_stdout->_file) { + return SPIFFS_write(&fs, (spiffs_file)fd, (char*)ptr, len); + } + for(int i = 0; i < len; i++) { + /* Auto convert CR to CRLF, ignore other LFs (compatible with Espressif SDK behaviour) */ + if(ptr[i] == '\r') + continue; + if(ptr[i] == '\n') + uart_putc(0, '\r'); + uart_putc(0, ptr[i]); + } + return len; +} + +/* syscall implementation for stdio read from UART */ +long _read_r( struct _reent *r, int fd, char *ptr, int len ) +{ + int ch, i; + + if(fd != r->_stdin->_file) { + return SPIFFS_read(&fs, (spiffs_file)fd, ptr, len); + } + uart_rxfifo_wait(0, 1); + for(i = 0; i < len; i++) { + ch = uart_getc_nowait(0); + if (ch < 0) break; + ptr[i] = ch; + } + return i; +} + +/* syscall implementation for stdio write to UART */ +int _open_r(struct _reent *r, const char *pathname, int flags, int mode) +{ + return SPIFFS_open(&fs, pathname, flags, mode); +} + +int _close_r(struct _reent *r, int fd) +{ + return SPIFFS_close(&fs, (spiffs_file)fd); +} + +int _unlink_r(struct _reent *r, const char *path) +{ + return SPIFFS_remove(&fs, path); +}