diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 9942ddeb55..0076df2626 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -69,9 +69,28 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_load_method(args[0], MP_QSTR_count, vfs->u.old.count); } + // mount the block device so the VFS methods can be used + FRESULT res = f_mount(&vfs->fatfs); + if (res == FR_NO_FILESYSTEM) { + // don't error out if no filesystem, to let mkfs()/mount() create one if wanted + vfs->flags |= FSUSER_NO_FILESYSTEM; + } else if (res != FR_OK) { + mp_raise_OSError(fresult_to_errno_table[res]); + } + return MP_OBJ_FROM_PTR(vfs); } +#if _FS_REENTRANT +STATIC mp_obj_t fat_vfs_del(mp_obj_t self_in) { + mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(self_in); + // f_umount only needs to be called to release the sync object + f_umount(&self->fatfs); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_del_obj, fat_vfs_del); +#endif + STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) { // create new object fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, 0, &bdev_in)); @@ -291,10 +310,8 @@ STATIC mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs self->writeblocks[0] = MP_OBJ_NULL; } - // mount the block device - FRESULT res = f_mount(&self->fatfs); - // check if we need to make the filesystem + FRESULT res = (self->flags & FSUSER_NO_FILESYSTEM) ? FR_NO_FILESYSTEM : FR_OK; if (res == FR_NO_FILESYSTEM && mp_obj_is_true(mkfs)) { uint8_t working_buf[_MAX_SS]; res = f_mkfs(&self->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf)); @@ -302,22 +319,23 @@ STATIC mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs if (res != FR_OK) { mp_raise_OSError(fresult_to_errno_table[res]); } + self->flags &= ~FSUSER_NO_FILESYSTEM; return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_3(vfs_fat_mount_obj, vfs_fat_mount); STATIC mp_obj_t vfs_fat_umount(mp_obj_t self_in) { - fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in); - FRESULT res = f_umount(&self->fatfs); - if (res != FR_OK) { - mp_raise_OSError(fresult_to_errno_table[res]); - } + (void)self_in; + // keep the FAT filesystem mounted internally so the VFS methods can still be used return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, vfs_fat_umount); STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = { + #if _FS_REENTRANT + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&fat_vfs_del_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) }, { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&fat_vfs_open_obj) }, { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&fat_vfs_ilistdir_obj) }, diff --git a/extmod/vfs_fat.h b/extmod/vfs_fat.h index 443e4eda82..688452973c 100644 --- a/extmod/vfs_fat.h +++ b/extmod/vfs_fat.h @@ -35,6 +35,7 @@ #define FSUSER_NATIVE (0x0001) // readblocks[2]/writeblocks[2] contain native func #define FSUSER_FREE_OBJ (0x0002) // fs_user_mount_t obj should be freed on umount #define FSUSER_HAVE_IOCTL (0x0004) // new protocol with ioctl +#define FSUSER_NO_FILESYSTEM (0x0008) // the block device has no filesystem on it typedef struct _fs_user_mount_t { mp_obj_base_t base;