From 3667ee1b8870ddc76f47260eb87d7d13736c9ad2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 31 Jan 2017 12:18:08 +1100 Subject: [PATCH] stmhal: On boot, mount all available partitions of the SD card. The first partition is mounted as "/sd" and subsequent partitions are mounted as "/sd". This is backwards compatible with the previous behaviour, which just mounted the first partition on "/sd". At this point, only FatFs filesystems are mounted. --- stmhal/main.c | 125 +++++++++++++++++++++++++++++++----------------- stmhal/sdcard.c | 4 +- stmhal/sdcard.h | 2 +- 3 files changed, 83 insertions(+), 48 deletions(-) diff --git a/stmhal/main.c b/stmhal/main.c index 94b8bd7f76..e19adb3dda 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -261,6 +261,85 @@ MP_NOINLINE STATIC void init_flash_fs(uint reset_mode) { } } +STATIC void init_sdcard_fs(bool first_soft_reset) { + bool first_part = true; + for (int part_num = 1; part_num <= 4; ++part_num) { + // create vfs object + fs_user_mount_t *vfs_fat = m_new_obj_maybe(fs_user_mount_t); + mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t); + if (vfs == NULL || vfs_fat == NULL) { + break; + } + vfs_fat->str = NULL; + vfs_fat->len = 0; + vfs_fat->flags = FSUSER_FREE_OBJ; + sdcard_init_vfs(vfs_fat, part_num); + + // try to mount the partition + FRESULT res = f_mount(&vfs_fat->fatfs); + + if (res != FR_OK) { + // couldn't mount + m_del_obj(fs_user_mount_t, vfs_fat); + m_del_obj(mp_vfs_mount_t, vfs); + } else { + // mounted via FatFs, now mount the SD partition in the VFS + if (first_part) { + // the first available partition is traditionally called "sd" for simplicity + vfs->str = "/sd"; + vfs->len = 3; + } else { + // subsequent partitions are numbered by their index in the partition table + if (part_num == 2) { + vfs->str = "/sd2"; + } else if (part_num == 2) { + vfs->str = "/sd3"; + } else { + vfs->str = "/sd4"; + } + vfs->len = 4; + } + vfs->obj = MP_OBJ_FROM_PTR(vfs_fat); + vfs->next = NULL; + for (mp_vfs_mount_t **m = &MP_STATE_VM(vfs_mount_table);; m = &(*m)->next) { + if (*m == NULL) { + *m = vfs; + break; + } + } + + if (first_part) { + // TODO these should go before the /flash entries in the path + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd)); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib)); + } + + if (first_soft_reset) { + // use SD card as medium for the USB MSD + #if defined(USE_DEVICE_MODE) + pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_SDCARD; + #endif + } + + #if defined(USE_DEVICE_MODE) + // only use SD card as current directory if that's what the USB medium is + if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_SDCARD) + #endif + { + if (first_part) { + // use SD card as current directory + MP_STATE_PORT(vfs_cur) = vfs; + } + } + first_part = false; + } + } + + if (first_part) { + printf("PYB: can't mount SD card\n"); + } +} + STATIC uint update_reset_mode(uint reset_mode) { #if MICROPY_HW_HAS_SWITCH if (switch_get()) { @@ -478,51 +557,7 @@ soft_reset: #if MICROPY_HW_HAS_SDCARD // if an SD card is present then mount it on /sd/ if (sdcard_is_present()) { - // create vfs object - fs_user_mount_t *vfs_fat = m_new_obj_maybe(fs_user_mount_t); - mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t); - if (vfs == NULL || vfs_fat == NULL) { - goto no_mem_for_sd; - } - vfs_fat->str = NULL; - vfs_fat->len = 0; - vfs_fat->flags = FSUSER_FREE_OBJ; - sdcard_init_vfs(vfs_fat); - - FRESULT res = f_mount(&vfs_fat->fatfs); - if (res != FR_OK) { - printf("PYB: can't mount SD card\n"); - m_del_obj(fs_user_mount_t, vfs_fat); - m_del_obj(mp_vfs_mount_t, vfs); - } else { - // mount the sd device after the internal flash - vfs->str = "/sd"; - vfs->len = 3; - vfs->obj = MP_OBJ_FROM_PTR(vfs_fat); - vfs->next = NULL; - MP_STATE_VM(vfs_mount_table)->next = vfs; - - // TODO these should go before the /flash entries in the path - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd)); - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib)); - - if (first_soft_reset) { - // use SD card as medium for the USB MSD -#if defined(USE_DEVICE_MODE) - pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_SDCARD; -#endif - } - - #if defined(USE_DEVICE_MODE) - // only use SD card as current directory if that's what the USB medium is - if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_SDCARD) - #endif - { - // use SD card as current directory - MP_STATE_PORT(vfs_cur) = vfs; - } - } - no_mem_for_sd:; + init_sdcard_fs(first_soft_reset); } #endif diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c index f4ad985048..6e9c46df54 100644 --- a/stmhal/sdcard.c +++ b/stmhal/sdcard.c @@ -443,11 +443,11 @@ const mp_obj_type_t pyb_sdcard_type = { .locals_dict = (mp_obj_t)&pyb_sdcard_locals_dict, }; -void sdcard_init_vfs(fs_user_mount_t *vfs) { +void sdcard_init_vfs(fs_user_mount_t *vfs, int part) { vfs->base.type = &mp_fat_vfs_type; vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL; vfs->fatfs.drv = vfs; - vfs->fatfs.part = 0; // autodetect partition + vfs->fatfs.part = part; vfs->readblocks[0] = (mp_obj_t)&pyb_sdcard_readblocks_obj; vfs->readblocks[1] = (mp_obj_t)&pyb_sdcard_obj; vfs->readblocks[2] = (mp_obj_t)sdcard_read_blocks; // native version diff --git a/stmhal/sdcard.h b/stmhal/sdcard.h index ccc24927e5..237e48d8b9 100644 --- a/stmhal/sdcard.h +++ b/stmhal/sdcard.h @@ -41,4 +41,4 @@ extern const struct _mp_obj_type_t pyb_sdcard_type; extern const struct _mp_obj_base_t pyb_sdcard_obj; struct _fs_user_mount_t; -void sdcard_init_vfs(struct _fs_user_mount_t *vfs); +void sdcard_init_vfs(struct _fs_user_mount_t *vfs, int part);