summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extmod/vfs_fat.c34
-rw-r--r--extmod/vfs_fat.h1
2 files changed, 27 insertions, 8 deletions
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index 9942ddeb5..0076df262 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 443e4eda8..688452973 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;