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.
pull/5299/head
Damien George 2019-11-06 13:48:35 +11:00
rodzic 0527baf7fa
commit 7723dac337
5 zmienionych plików z 72 dodań i 55 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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);
if (reset_mode == 3) {
// Asked by user to reset filesystem
factory_reset_create_filesystem();
}
// try to mount the flash
FRESULT res = f_mount(&vfs_fat->fatfs);
// 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);
if (reset_mode == 3 || res == FR_NO_FILESYSTEM) {
// no filesystem, or asked to reset it, so create a fresh one
// 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();
}
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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);