Skip to content

stm32: Generalise flash mounting code so it supports arbitrary FS. #5299

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions ports/stm32/factoryreset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions ports/stm32/factoryreset.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
91 changes: 37 additions & 54 deletions ports/stm32/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -616,7 +599,7 @@ void stm32_main(uint32_t reset_mode) {
// 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();
}
}
Expand Down
2 changes: 1 addition & 1 deletion ports/stm32/storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions ports/stm32/storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy