aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George2019-11-06 13:48:35 +1100
committerDamien George2019-11-25 18:10:58 +1100
commit7723dac3371ccf081c2490b33b69492dc42818bd (patch)
treec09dc284ad02414235fb86a750f87d33e27758a4
parent0527baf7fa2056e62ca605dedc739a6275307923 (diff)
stm32: Generalise flash mounting code so it supports arbitrary FS.
This commit refactors and generalises the boot-mount routine on stm32 so that it can mount filesystems of arbitrary type. That is, it no longer assumes that the filesystem is FAT. It does this by using mp_vfs_mount() which does auto-detection of the filesystem type.
-rw-r--r--ports/stm32/factoryreset.c32
-rw-r--r--ports/stm32/factoryreset.h1
-rw-r--r--ports/stm32/main.c91
-rw-r--r--ports/stm32/storage.c2
-rw-r--r--ports/stm32/storage.h1
5 files changed, 72 insertions, 55 deletions
diff --git a/ports/stm32/factoryreset.c b/ports/stm32/factoryreset.c
index 24e0ff88c..513b52163 100644
--- a/ports/stm32/factoryreset.c
+++ b/ports/stm32/factoryreset.c
@@ -25,6 +25,11 @@
*/
#include "py/runtime.h"
+#include "py/mperrno.h"
+#include "extmod/vfs_fat.h"
+#include "systick.h"
+#include "led.h"
+#include "storage.h"
#include "factoryreset.h"
#if MICROPY_HW_ENABLE_STORAGE
@@ -96,4 +101,31 @@ MP_WEAK void factory_reset_make_files(FATFS *fatfs) {
}
}
+MP_WEAK int factory_reset_create_filesystem(void) {
+ // LED on to indicate creation of local filesystem
+ led_state(PYB_LED_GREEN, 1);
+ uint32_t start_tick = HAL_GetTick();
+
+ fs_user_mount_t vfs;
+ pyb_flash_init_vfs(&vfs);
+ uint8_t working_buf[FF_MAX_SS];
+ FRESULT res = f_mkfs(&vfs.fatfs, FM_FAT, 0, working_buf, sizeof(working_buf));
+ if (res != FR_OK) {
+ mp_printf(&mp_plat_print, "MPY: can't create flash filesystem\n");
+ return -MP_ENODEV;
+ }
+
+ // Set label
+ f_setlabel(&vfs.fatfs, MICROPY_HW_FLASH_FS_LABEL);
+
+ // Populate the filesystem with factory files
+ factory_reset_make_files(&vfs.fatfs);
+
+ // Keep LED on for at least 200ms
+ systick_wait_at_least(start_tick, 200);
+ led_state(PYB_LED_GREEN, 0);
+
+ return 0; // success
+}
+
#endif // MICROPY_HW_ENABLE_STORAGE
diff --git a/ports/stm32/factoryreset.h b/ports/stm32/factoryreset.h
index 85226f880..1d1f4b857 100644
--- a/ports/stm32/factoryreset.h
+++ b/ports/stm32/factoryreset.h
@@ -29,5 +29,6 @@
#include "lib/oofatfs/ff.h"
void factory_reset_make_files(FATFS *fatfs);
+int factory_reset_create_filesystem(void);
#endif // MICROPY_INCLUDED_STM32_FACTORYRESET_H
diff --git a/ports/stm32/main.c b/ports/stm32/main.c
index 3c6420d50..707b1fc68 100644
--- a/ports/stm32/main.c
+++ b/ports/stm32/main.c
@@ -30,6 +30,7 @@
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "py/gc.h"
+#include "py/mperrno.h"
#include "py/mphal.h"
#include "lib/mp-readline/readline.h"
#include "lib/utils/pyexec.h"
@@ -81,10 +82,6 @@
STATIC pyb_thread_t pyb_thread_main;
#endif
-#if MICROPY_HW_ENABLE_STORAGE
-STATIC fs_user_mount_t fs_user_mount_flash;
-#endif
-
#if defined(MICROPY_HW_UART_REPL)
#ifndef MICROPY_HW_UART_REPL_RXBUF
#define MICROPY_HW_UART_REPL_RXBUF (260)
@@ -159,65 +156,51 @@ STATIC mp_obj_t pyb_main(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_main_obj, 1, pyb_main);
#if MICROPY_HW_ENABLE_STORAGE
+STATIC int vfs_mount_and_chdir(mp_obj_t bdev, mp_obj_t mount_point) {
+ nlr_buf_t nlr;
+ mp_int_t ret = -MP_EIO;
+ if (nlr_push(&nlr) == 0) {
+ mp_obj_t args[] = { bdev, mount_point };
+ mp_vfs_mount(2, args, (mp_map_t*)&mp_const_empty_map);
+ mp_vfs_chdir(mount_point);
+ ret = 0; // success
+ nlr_pop();
+ } else {
+ mp_obj_base_t *exc = nlr.ret_val;
+ if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(exc->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) {
+ mp_obj_t v = mp_obj_exception_get_value(MP_OBJ_FROM_PTR(exc));
+ mp_obj_get_int_maybe(v, &ret); // get errno value
+ ret = -ret;
+ }
+ }
+ return ret;
+}
+
// avoid inlining to avoid stack usage within main()
MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) {
- // init the vfs object
- fs_user_mount_t *vfs_fat = &fs_user_mount_flash;
- vfs_fat->blockdev.flags = 0;
- pyb_flash_init_vfs(vfs_fat);
-
- // try to mount the flash
- FRESULT res = f_mount(&vfs_fat->fatfs);
+ if (reset_mode == 3) {
+ // Asked by user to reset filesystem
+ factory_reset_create_filesystem();
+ }
- if (reset_mode == 3 || res == FR_NO_FILESYSTEM) {
- // no filesystem, or asked to reset it, so create a fresh one
+ // Try to mount the flash on "/flash" and chdir to it for the boot-up directory.
+ mp_obj_t bdev = MP_OBJ_FROM_PTR(&pyb_flash_obj);
+ mp_obj_t mount_point = MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash);
+ int ret = vfs_mount_and_chdir(bdev, mount_point);
- // LED on to indicate creation of LFS
- led_state(PYB_LED_GREEN, 1);
- uint32_t start_tick = HAL_GetTick();
-
- uint8_t working_buf[FF_MAX_SS];
- res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf));
- if (res == FR_OK) {
- // success creating fresh LFS
- } else {
- printf("MPY: can't create flash filesystem\n");
- return false;
+ if (ret == -MP_ENODEV && reset_mode != 3) {
+ // No filesystem (and didn't already create one), try to create a fresh one
+ ret = factory_reset_create_filesystem();
+ if (ret == 0) {
+ ret = vfs_mount_and_chdir(bdev, mount_point);
}
+ }
- // set label
- f_setlabel(&vfs_fat->fatfs, MICROPY_HW_FLASH_FS_LABEL);
-
- // populate the filesystem with factory files
- factory_reset_make_files(&vfs_fat->fatfs);
-
- // keep LED on for at least 200ms
- systick_wait_at_least(start_tick, 200);
- led_state(PYB_LED_GREEN, 0);
- } else if (res == FR_OK) {
- // mount sucessful
- } else {
- fail:
+ if (ret != 0) {
printf("MPY: can't mount flash\n");
return false;
}
- // mount the flash device (there should be no other devices mounted at this point)
- // we allocate this structure on the heap because vfs->next is a root pointer
- mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
- if (vfs == NULL) {
- goto fail;
- }
- vfs->str = "/flash";
- vfs->len = 6;
- vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
- vfs->next = NULL;
- MP_STATE_VM(vfs_mount_table) = vfs;
-
- // The current directory is used as the boot up directory.
- // It is set to the internal flash filesystem by default.
- MP_STATE_PORT(vfs_cur) = vfs;
-
return true;
}
#endif
@@ -616,7 +599,7 @@ soft_reset:
// if an SD card is present then mount it on /sd/
if (sdcard_is_present()) {
// if there is a file in the flash called "SKIPSD", then we don't mount the SD card
- if (!mounted_flash || f_stat(&fs_user_mount_flash.fatfs, "/SKIPSD", NULL) != FR_OK) {
+ if (!mounted_flash || mp_vfs_import_stat("SKIPSD") == MP_IMPORT_STAT_FILE) {
mounted_sdcard = init_sdcard_fs();
}
}
diff --git a/ports/stm32/storage.c b/ports/stm32/storage.c
index d9d546485..905d51f32 100644
--- a/ports/stm32/storage.c
+++ b/ports/stm32/storage.c
@@ -234,7 +234,7 @@ mp_uint_t storage_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t
// Expose the flash as an object with the block protocol.
// there is a singleton Flash object
-STATIC const mp_obj_base_t pyb_flash_obj = {&pyb_flash_type};
+const mp_obj_base_t pyb_flash_obj = {&pyb_flash_type};
STATIC mp_obj_t pyb_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
// check arguments
diff --git a/ports/stm32/storage.h b/ports/stm32/storage.h
index 826b465a6..0ba3497a1 100644
--- a/ports/stm32/storage.h
+++ b/ports/stm32/storage.h
@@ -63,6 +63,7 @@ int spi_bdev_readblocks(spi_bdev_t *bdev, uint8_t *dest, uint32_t block_num, uin
int spi_bdev_writeblocks(spi_bdev_t *bdev, const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
extern const struct _mp_obj_type_t pyb_flash_type;
+extern const struct _mp_obj_base_t pyb_flash_obj;
struct _fs_user_mount_t;
void pyb_flash_init_vfs(struct _fs_user_mount_t *vfs);