Skip to content
Snippets Groups Projects
Commit e5b3e196 authored by swym's avatar swym Committed by rahix
Browse files

fix(fatfs): Refactor fatfs implementation

parent 0d8be9c3
No related branches found
No related tags found
No related merge requests found
Pipeline #1667 passed
......@@ -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
*
......
......@@ -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;
}
#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;
}
module_sources = files(
'display.c',
'fatfs.c',
'fatfs_fileops.c',
'leds.c',
'log.c',
'pmic.c',
......
......@@ -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);
......
/*
* 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);
......@@ -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);
}
......
......@@ -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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment