diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index ac1eb09aff02856ef8eda652607dbb8e07c3599e..8b0b20deee2754510a6b1dd51b62f351b83d8d5a 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -554,26 +554,47 @@ API(API_FILE_TELL, int epic_file_tell(int fd)); /** */ enum epic_stat_type { - /** */ + /** basically NOENT + * although epic_file_stat returns an error for 'none', the type will still be set + * to none additinally. + * This is also used internally to track open FS objects, where we use ``EPICSTAT_NONE`` + * to mark free objects. + */ + EPICSTAT_NONE, + /** normal file */ EPICSTAT_FILE, - /** */ + /** directory */ EPICSTAT_DIR, }; /** */ typedef struct epic_stat_t { - /** */ + /** type: file, directory or none */ enum epic_stat_type type; + /* note about padding & placement of uint32_t size: + * to accomodate for future expansion, we want padding at the end of + * this struct. Since sizeof(enum epic_stat_type) can not be + * assumed to be have a certain size, + * we're placing uint32_t size here so we can be sure it will be at + * offset 4, and therefore the layout of the other fields is predictable. + */ + /** size in bytes */ + uint32_t size; + /** the FAT volume (will be needed later once we distinguish + * between system and user volume)*/ + uint8_t volume; + uint8_t _reserved[9]; } epic_stat_t; +#ifndef __cplusplus +#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +_Static_assert(sizeof(epic_stat_t) == 20, ""); +#endif +#endif + /** * stat path * - * This does not follow posix convention, but rather takes - * a path as parameter. This aligns more with libff's API and - * also this has been implemented for python import support, which - * passes the filename as well. - * * :param const char* filename: path to stat * :param epic_stat_t* stat: pointer to result * diff --git a/epicardium/modules/fatfs.c b/epicardium/modules/fatfs.c index e9f7205d771f98bf153b3fc3bec3b6b8a996581a..1962f4939781097178602e7646c5f1af0f6886b9 100644 --- a/epicardium/modules/fatfs.c +++ b/epicardium/modules/fatfs.c @@ -26,61 +26,21 @@ static const TCHAR *rcstrings = _T("NOT_ENABLED\0NO_FILESYSTEM\0MKFS_ABORTED\0TIMEOUT\0LOCKED\0") _T("NOT_ENOUGH_CORE\0TOO_MANY_OPEN_FILES\0INVALID_PARAMETER\0"); -// this table converts from FRESULT to POSIX errno -const int fresult_to_errno_table[20] = { - [FR_OK] = 0, - [FR_DISK_ERR] = EIO, - [FR_INT_ERR] = EIO, - [FR_NOT_READY] = EBUSY, - [FR_NO_FILE] = ENOENT, - [FR_NO_PATH] = ENOENT, - [FR_INVALID_NAME] = EINVAL, - [FR_DENIED] = EACCES, - [FR_EXIST] = EEXIST, - [FR_INVALID_OBJECT] = EINVAL, - [FR_WRITE_PROTECTED] = EROFS, - [FR_INVALID_DRIVE] = ENODEV, - [FR_NOT_ENABLED] = ENODEV, - [FR_NO_FILESYSTEM] = ENODEV, - [FR_MKFS_ABORTED] = EIO, - [FR_TIMEOUT] = EIO, - [FR_LOCKED] = EIO, - [FR_NOT_ENOUGH_CORE] = ENOMEM, - [FR_TOO_MANY_OPEN_FILES] = EMFILE, - [FR_INVALID_PARAMETER] = EINVAL, -}; - -enum FatObjectType { FO_Nil, FO_File, FO_Dir }; -struct FatObject { - enum FatObjectType type; - union { - FIL file; - DIR dir; - }; -}; - static bool mount(void); -static int -get_fat_object(int i, enum FatObjectType expected, struct FatObject **res); DIR dir; FATFS FatFs; -static struct FatObject s_openedObjects[EPIC_FAT_MAX_OPENED]; #if (EPIC_FAT_STATIC_SEMAPHORE == 1) StaticSemaphore_t xSemaphoreBuffer; #endif -static volatile struct { - bool initiaized; -} s_state = { - .initiaized = false, -}; +static volatile bool s_fatfs_initiaized = false; void fatfs_init() { if (mount()) { - s_state.initiaized = true; + s_fatfs_initiaized = true; printf("FatFs mounted\n"); } } @@ -188,195 +148,3 @@ void ff_rel_grant(FF_SYNC_t sobj) /* FreeRTOS */ xSemaphoreGive(sobj); } - -int get_fat_object(int i, enum FatObjectType expected, struct FatObject **res) -{ - if (i < 0 || i >= EPIC_FAT_MAX_OPENED) { - *res = NULL; - return EBADF; - } - if (s_openedObjects[i].type != expected) { - *res = NULL; - return EBADF; - } - *res = &s_openedObjects[i]; - return 0; -} - -int epic_file_open(const char *filename, const char *modeString) -{ - struct FatObject *o = NULL; - const char *mode_s = modeString; - int i; - int mode = 0; - - //find free object to use - for (i = 0; i < EPIC_FAT_MAX_OPENED; ++i) { - if (s_openedObjects[i].type == FO_Nil) { - break; - } - } - if (i == EPIC_FAT_MAX_OPENED) { - return -fresult_to_errno_table[FR_TOO_MANY_OPEN_FILES]; - } - o = &s_openedObjects[i]; - - while (*mode_s) { - switch (*mode_s++) { - case 'r': - mode |= FA_READ; - break; - case 'w': - mode |= FA_WRITE | FA_CREATE_ALWAYS; - break; - case 'x': - mode |= FA_WRITE | FA_CREATE_NEW; - break; - case 'a': - mode |= FA_WRITE | FA_OPEN_ALWAYS; - break; - case '+': - mode |= FA_READ | FA_WRITE; - break; - } - } - - int res = f_open(&o->file, filename, mode); - if (res != FR_OK) { - return -fresult_to_errno_table[res]; - } - o->type = FO_File; - - // for 'a' mode, we must begin at the end of the file - if ((mode & FA_OPEN_ALWAYS) != 0) { - f_lseek(&o->file, f_size(&o->file)); - } - - return i; -} - -int epic_file_close(int fd) -{ - int res; - struct FatObject *o; - res = get_fat_object(fd, FO_File, &o); - if (res) { - return -res; - } - - res = f_close(&o->file); - if (res != FR_OK) { - return -fresult_to_errno_table[res]; - } - - o->type = FO_Nil; - return 0; -} - -int epic_file_read(int fd, void *buf, size_t nbytes) -{ - unsigned int nread = 0; - - int res; - struct FatObject *o; - res = get_fat_object(fd, FO_File, &o); - if (res) { - return -res; - } - - res = f_read(&o->file, buf, nbytes, &nread); - if (res != FR_OK) { - return -fresult_to_errno_table[res]; - } - - return nread; -} - -int epic_file_write(int fd, const void *buf, size_t nbytes) -{ - unsigned int nwritten = 0; - - int res; - struct FatObject *o; - res = get_fat_object(fd, FO_File, &o); - if (res) { - return -res; - } - res = f_write(&o->file, buf, nbytes, &nwritten); - if (res != FR_OK) { - return -fresult_to_errno_table[res]; - } - - return nwritten; -} - -int epic_file_flush(int fd) -{ - int res; - struct FatObject *o; - res = get_fat_object(fd, FO_File, &o); - if (res) { - return -res; - } - res = f_sync(&o->file); - if (res != FR_OK) { - return -fresult_to_errno_table[res]; - } - - return 0; -} - -int epic_file_seek(int fd, long offset, int whence) -{ - int res; - struct FatObject *o; - res = get_fat_object(fd, FO_File, &o); - if (res) { - return -res; - } - - switch (whence) { - case SEEK_SET: - res = f_lseek(&o->file, offset); - return -fresult_to_errno_table[res]; - case SEEK_CUR: - res = f_lseek(&o->file, f_tell(&o->file) + offset); - return -fresult_to_errno_table[res]; - case SEEK_END: - res = f_lseek(&o->file, f_size(&o->file) + offset); - return -fresult_to_errno_table[res]; - default: - return -EINVAL; - } - return 0; -} - -int epic_file_tell(int fd) -{ - int res; - struct FatObject *o; - res = get_fat_object(fd, FO_File, &o); - if (res) { - return -1; - } - - return f_tell(&o->file); -} - -int epic_file_stat(const char *filename, epic_stat_t *stat) -{ - int res; - FILINFO finfo; - res = f_stat(filename, &finfo); - if (res != FR_OK) { - return -fresult_to_errno_table[res]; - } - - if (finfo.fattrib & AM_DIR) { - stat->type = EPICSTAT_DIR; - } else { - stat->type = EPICSTAT_FILE; - } - - return 0; -} diff --git a/epicardium/modules/fatfs_fileops.c b/epicardium/modules/fatfs_fileops.c new file mode 100644 index 0000000000000000000000000000000000000000..dadc22c682a27961ed51f78fd8b39b52c8fd9406 --- /dev/null +++ b/epicardium/modules/fatfs_fileops.c @@ -0,0 +1,299 @@ +#include <errno.h> +#include <stddef.h> +#include <stdbool.h> +#include <stdio.h> + +#include <ff.h> + +#include "modules.h" +#include "epicardium.h" + +#define EPIC_FAT_FD_GENERATION_BITS (31 - (EPIC_FAT_FD_INDEX_BITS)) +#define EPIC_FAT_MAX_OPENED (1 << (EPIC_FAT_FD_INDEX_BITS)) +#define EPIC_FAT_FD_INDEX_MASK (uint32_t)((1u << EPIC_FAT_FD_INDEX_BITS) - 1) +#define EPIC_FAT_FD_INDEX(fd) ((uint32_t)(fd)&EPIC_FAT_FD_INDEX_MASK) +#define EPIC_FAT_FD_GENERATION(fd) ((uint32_t)(fd) >> EPIC_FAT_FD_INDEX_BITS) +#define EPIC_FAT_FD_MAX_GENERATION \ + (uint32_t)((1u << EPIC_FAT_FD_GENERATION_BITS) - 1) +#define EPIC_FAT_FD(idx, gen) \ + (int)(((uint32_t)(gen) << EPIC_FAT_FD_INDEX_BITS) | \ + ((uint32_t)(idx)&EPIC_FAT_FD_INDEX_MASK)) + +// this table converts from FRESULT to POSIX errno +const int fresult_to_errno_table[20] = { + [FR_OK] = 0, + [FR_DISK_ERR] = EIO, + [FR_INT_ERR] = EIO, + [FR_NOT_READY] = EBUSY, + [FR_NO_FILE] = ENOENT, + [FR_NO_PATH] = ENOENT, + [FR_INVALID_NAME] = EINVAL, + [FR_DENIED] = EACCES, + [FR_EXIST] = EEXIST, + [FR_INVALID_OBJECT] = EINVAL, + [FR_WRITE_PROTECTED] = EROFS, + [FR_INVALID_DRIVE] = ENODEV, + [FR_NOT_ENABLED] = ENODEV, + [FR_NO_FILESYSTEM] = ENODEV, + [FR_MKFS_ABORTED] = EIO, + [FR_TIMEOUT] = EIO, + [FR_LOCKED] = EIO, + [FR_NOT_ENOUGH_CORE] = ENOMEM, + [FR_TOO_MANY_OPEN_FILES] = EMFILE, + [FR_INVALID_PARAMETER] = EINVAL, +}; + +struct FatObject { + uint32_t generation; + enum epic_stat_type type; + union { + FIL file; + DIR dir; + }; +}; + +static int +get_fat_object(int i, enum epic_stat_type expected, struct FatObject **res); + +static struct FatObject s_openedObjects[EPIC_FAT_MAX_OPENED]; +static uint32_t s_fatfs_generationCount = 1; + +int get_fat_object(int fd, enum epic_stat_type expected, struct FatObject **res) +{ + uint32_t index = EPIC_FAT_FD_INDEX(fd); + uint32_t generation = EPIC_FAT_FD_GENERATION(fd); + if (index >= EPIC_FAT_MAX_OPENED) { + *res = NULL; + return EBADF; + } + if (generation >= EPIC_FAT_FD_MAX_GENERATION) { + *res = NULL; + return EBADF; + } + if (s_openedObjects[index].type != expected) { + *res = NULL; + return EBADF; + } + if (s_openedObjects[index].generation != generation) { + *res = NULL; + return EBADF; + } + *res = &s_openedObjects[index]; + return 0; +} + +/* here we're trying to mirror glibc's behaviour: + * any combination of rwax parses but only the first of those flags wins: + * - rw, ra, rr all open read-only + * a `+` at any position but the first turns into read-write + * any other character at any position yields EINVAL + */ +static inline bool parse_mode(const char *mstring, int *mode) +{ + switch (mstring[0]) { + case 'r': + *mode = FA_READ; + break; + case 'w': + *mode = FA_CREATE_ALWAYS | FA_WRITE; + break; + case 'x': + //in constrast to FA_CREATE_ALWAYS, FA_CREATE_NEW fails for existing files + *mode = FA_WRITE | FA_CREATE_NEW; + break; + case 'a': + //in constrast to FA_CREATE_ALWAYS, FA_CREATE_NEW fails for existing files + *mode = FA_WRITE | FA_OPEN_APPEND; + break; + default: + return false; + } + while (*mstring) { + switch (*mstring++) { + case '+': //turns any of r,w,x into read&write + *mode |= FA_READ | FA_WRITE; + break; + case 'r': //fallthrough intentional + case 'w': //fallthrough intentional + case 'a': //fallthrough intentional + case 'x': //fallthrough intentional + break; + default: + return false; + } + } + return true; +} + +int epic_file_open(const char *filename, const char *modeString) +{ + struct FatObject *o = NULL; + uint32_t index, generation; + int mode = 0; + int res; + + //find free object to use + for (index = 0; index < EPIC_FAT_MAX_OPENED; ++index) { + if (s_openedObjects[index].type == EPICSTAT_NONE) { + break; + } + } + if (index == EPIC_FAT_MAX_OPENED) { + return -fresult_to_errno_table[FR_TOO_MANY_OPEN_FILES]; + } + generation = s_fatfs_generationCount++; + if (generation == EPIC_FAT_FD_MAX_GENERATION) { + s_fatfs_generationCount = 1; + } + o = &s_openedObjects[index]; + + if (!parse_mode(modeString, &mode)) { + return -EINVAL; + } + + res = f_open(&o->file, filename, mode); + if (res != FR_OK) { + return -fresult_to_errno_table[res]; + } + o->type = EPICSTAT_FILE; + o->generation = generation; + + // for 'a' mode, we must begin at the end of the file + if ((mode & FA_OPEN_APPEND) != 0) { + f_lseek(&o->file, f_size(&o->file)); + } + + return EPIC_FAT_FD(index, generation); +} + +int epic_file_close(int fd) +{ + int res; + struct FatObject *o; + res = get_fat_object(fd, EPICSTAT_FILE, &o); + if (res) { + return -res; + } + + res = f_close(&o->file); + if (res != FR_OK) { + return -fresult_to_errno_table[res]; + } + + o->type = EPICSTAT_NONE; + o->generation = 0; + return 0; +} + +int epic_file_read(int fd, void *buf, size_t nbytes) +{ + unsigned int nread = 0; + + int res; + struct FatObject *o; + res = get_fat_object(fd, EPICSTAT_FILE, &o); + if (res) { + return -res; + } + + res = f_read(&o->file, buf, nbytes, &nread); + if (res != FR_OK) { + return -fresult_to_errno_table[res]; + } + + return (int)nread; +} + +int epic_file_write(int fd, const void *buf, size_t nbytes) +{ + unsigned int nwritten = 0; + + int res; + struct FatObject *o; + res = get_fat_object(fd, EPICSTAT_FILE, &o); + if (res) { + return -res; + } + res = f_write(&o->file, buf, nbytes, &nwritten); + if (res != FR_OK) { + return -fresult_to_errno_table[res]; + } + + return (int)nwritten; +} + +int epic_file_flush(int fd) +{ + int res; + struct FatObject *o; + res = get_fat_object(fd, EPICSTAT_FILE, &o); + if (res) { + return -res; + } + res = f_sync(&o->file); + if (res != FR_OK) { + return -fresult_to_errno_table[res]; + } + + return 0; +} + +int epic_file_seek(int fd, long offset, int whence) +{ + int res; + struct FatObject *o; + res = get_fat_object(fd, EPICSTAT_FILE, &o); + if (res) { + return -res; + } + switch (whence) { + case SEEK_SET: + res = f_lseek(&o->file, offset); + break; + + case SEEK_CUR: + res = f_lseek(&o->file, f_tell(&o->file) + offset); + break; + + case SEEK_END: + res = f_lseek(&o->file, f_size(&o->file) + offset); + break; + default: + return -EINVAL; + } + if (res != FR_OK) { + return -fresult_to_errno_table[res]; + } + + return 0; +} + +int epic_file_tell(int fd) +{ + int res; + struct FatObject *o; + res = get_fat_object(fd, EPICSTAT_FILE, &o); + if (res) { + return -res; + } + //f_tell simply accesses fp->fptr so no errors are expected - return directly + return f_tell(&o->file); +} + +int epic_file_stat(const char *filename, epic_stat_t *stat) +{ + int res; + FILINFO finfo; + res = f_stat(filename, &finfo); + if (res != FR_OK) { + return -fresult_to_errno_table[res]; + } + + if (finfo.fattrib & AM_DIR) { + stat->type = EPICSTAT_DIR; + } else { + stat->type = EPICSTAT_FILE; + } + + return 0; +} diff --git a/epicardium/modules/meson.build b/epicardium/modules/meson.build index 807e9b8c77f386b3894288d2b9765a9d61b397df..113e3cb8ecaebc932a65ce9e6124cc2ff3be60ce 100644 --- a/epicardium/modules/meson.build +++ b/epicardium/modules/meson.build @@ -1,6 +1,7 @@ module_sources = files( 'display.c', 'fatfs.c', + 'fatfs_fileops.c', 'leds.c', 'log.c', 'pmic.c', diff --git a/epicardium/modules/modules.h b/epicardium/modules/modules.h index f02298e36b2e538237fc75bfe0710517c11e33ab..e273146fdd0d97bae3cfbfad3de3b5a510fa4a53 100644 --- a/epicardium/modules/modules.h +++ b/epicardium/modules/modules.h @@ -2,8 +2,12 @@ #define MODULES_H /* ---------- FAT fs ------------------------------------------------------ */ -/* max no. of descriptors (file & directory) that can be open at a time */ -#define EPIC_FAT_MAX_OPENED 16 +/* Number of bits to use for indexing into our internal pool of files/directories + * This indirectly specifies the size of the pool as 1^EPIC_FAT_FD_INDEX_BITS + * Increase if number of open file descriptors is not enough, but be aware of + * memory usage of the pool! + */ +#define EPIC_FAT_FD_INDEX_BITS 8 #define EPIC_FAT_STATIC_SEMAPHORE 1 void fatfs_init(void); diff --git a/pycardium/modules/fat_file.c b/pycardium/modules/fat_file.c index e1d42f3efcc33c16f1425d23e061767d1eb6d5ad..a5ddcd8ae7684f183b00a38ff5c3eba64568d5ca 100644 --- a/pycardium/modules/fat_file.c +++ b/pycardium/modules/fat_file.c @@ -1,27 +1,5 @@ /* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * based on micropytohn/ports/unix/file.c */ #include <stdio.h> @@ -34,15 +12,15 @@ #include "epicardium.h" -extern const mp_obj_type_t mp_type_fat_textio; +extern const mp_obj_type_t mp_type_textio; #if MICROPY_PY_IO_FILEIO -extern const mp_obj_type_t mp_type_fat_fileio; +extern const mp_obj_type_t mp_type_fileio; #endif -typedef struct _pyb_file_obj_t { +typedef struct _fat_py_file_obj_t { mp_obj_base_t base; int fd; -} pyb_file_obj_t; +} fat_py_file_obj_t; STATIC void file_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) @@ -59,8 +37,8 @@ file_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) STATIC mp_uint_t file_obj_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) { - pyb_file_obj_t *self = MP_OBJ_TO_PTR(self_in); - int res = epic_file_read(self->fd, buf, size); + fat_py_file_obj_t *self = MP_OBJ_TO_PTR(self_in); + int res = epic_file_read(self->fd, buf, size); if (res < 0) { *errcode = -res; return MP_STREAM_ERROR; @@ -71,8 +49,8 @@ file_obj_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) STATIC mp_uint_t file_obj_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) { - pyb_file_obj_t *self = MP_OBJ_TO_PTR(self_in); - int res = epic_file_write(self->fd, buf, size); + fat_py_file_obj_t *self = MP_OBJ_TO_PTR(self_in); + int res = epic_file_write(self->fd, buf, size); if (res < 0) { *errcode = -res; return MP_STREAM_ERROR; @@ -92,7 +70,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) { - pyb_file_obj_t *self = MP_OBJ_TO_PTR(o_in); + fat_py_file_obj_t *self = MP_OBJ_TO_PTR(o_in); int res; switch (request) { case MP_STREAM_FLUSH: @@ -109,29 +87,22 @@ file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) return MP_STREAM_ERROR; } return 0; + case MP_STREAM_SEEK: { + struct mp_stream_seek_t *s = + (struct mp_stream_seek_t *)(uintptr_t)arg; + //it "just so happens" that MP's whence values are 0,1,2 for SET,CUR,END, just like in epicardium + res = epic_file_seek(self->fd, s->offset, s->whence); + if (res < 0) { + *errcode = -res; + return MP_STREAM_ERROR; + } + s->offset = epic_file_tell(self->fd); + return 0; + } } //every valid case returns either success or error, so this is EINVAL land: *errcode = MP_EINVAL; return MP_STREAM_ERROR; - // if (request == MP_STREAM_SEEK) { - // struct mp_stream_seek_t *s = (struct mp_stream_seek_t*)(uintptr_t)arg; - - // switch (s->whence) { - // case 0: // SEEK_SET - // f_lseek(&self->fp, s->offset); - // break; - - // case 1: // SEEK_CUR - // f_lseek(&self->fp, f_tell(&self->fp) + s->offset); - // break; - - // case 2: // SEEK_END - // f_lseek(&self->fp, f_size(&self->fp) + s->offset); - // break; - // } - - // s->offset = f_tell(&self->fp); - // return 0; } // Note: encoding is ignored for now; it's also not a valid kwarg for CPython's FileIO, @@ -157,22 +128,22 @@ STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args) switch (*mode_s++) { #if MICROPY_PY_IO_FILEIO case 'b': - type = &mp_type_fat_fileio; + type = &mp_type_fileio; break; #endif case 't': - type = &mp_type_fat_textio; + type = &mp_type_textio; break; } } - pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t); - o->base.type = type; + fat_py_file_obj_t *o = m_new_obj_with_finaliser(fat_py_file_obj_t); + o->base.type = type; const char *fname = mp_obj_str_get_str(args[0].u_obj); int res = epic_file_open(fname, modeString); if (res < 0) { - m_del_obj(pyb_file_obj_t, o); + m_del_obj(fat_py_file_obj_t, o); mp_raise_OSError(-res); } o->fd = res; @@ -226,7 +197,7 @@ STATIC const mp_stream_p_t fileio_stream_p = { .ioctl = file_obj_ioctl, }; -const mp_obj_type_t mp_type_fat_fileio = { +const mp_obj_type_t mp_type_fileio = { { &mp_type_type }, .name = MP_QSTR_FileIO, .print = file_obj_print, @@ -245,7 +216,7 @@ STATIC const mp_stream_p_t textio_stream_p = { .is_text = true, }; -const mp_obj_type_t mp_type_fat_textio = { +const mp_obj_type_t mp_type_textio = { { &mp_type_type }, .name = MP_QSTR_TextIOWrapper, .print = file_obj_print, @@ -269,6 +240,6 @@ mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) file_open_args, arg_vals ); - return file_open(&mp_type_fat_textio, arg_vals); + return file_open(&mp_type_textio, arg_vals); } MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); diff --git a/pycardium/modules/fat_reader_import.c b/pycardium/modules/fat_reader_import.c index bb35aec22ff8cd66c11c02924b8ce3eeb944b430..656cbe236925dbb619f3f3c0b9012c13175db236 100644 --- a/pycardium/modules/fat_reader_import.c +++ b/pycardium/modules/fat_reader_import.c @@ -4,14 +4,13 @@ #include <py/reader.h> #include <py/lexer.h> -/** ported from picropython's posic implementation */ +#define EPICFAT_READER_BUFFER_SIZE 128 typedef struct _mp_reader_epicfat_t { - bool close_fd; int fd; size_t len; size_t pos; - byte buf[20]; + byte buf[EPICFAT_READER_BUFFER_SIZE]; } mp_reader_epicfat_t; STATIC mp_uint_t mp_reader_epicfat_readbyte(void *data) @@ -50,7 +49,7 @@ void mp_reader_new_file(mp_reader_t *reader, const char *filename) } mp_reader_epicfat_t *rp = m_new_obj(mp_reader_epicfat_t); rp->fd = fd; - int n = epic_file_read(rp->fd, rp->buf, sizeof(rp->buf)); + int n = epic_file_read(rp->fd, rp->buf, sizeof(rp->buf)); if (n < 0) { epic_file_close(fd); } diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h index 9bed1f600fd79535f4f53d6792f0ded869cf99d0..233c01bbb82dd986e9ec54c53275ffef96631269 100644 --- a/pycardium/mpconfigport.h +++ b/pycardium/mpconfigport.h @@ -35,6 +35,7 @@ #define MICROPY_PY_URE_MATCH_SPAN_START_END (1) #define MICROPY_PY_URE_SUB (1) #define MICROPY_PY_UTIME_MP_HAL (1) +#define MICROPY_PY_IO_FILEIO (1) /* Modules */ #define MODULE_UTIME_ENABLED (1)