8000 stm32: Generalise flash mounting code so it supports arbitrary FS. · rlangoy/micropython@7723dac · GitHub
[go: up one dir, main page]

Skip to content

Commit 7723dac

Browse files
committed
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.
1 parent 0527baf commit 7723dac

File tree

5 files changed

+72
-55
lines changed

5 files changed

+72
-55
lines changed

ports/stm32/factoryreset.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
*/
2626

2727
#include "py/runtime.h"
28+
#include "py/mperrno.h"
29+
#include "extmod/vfs_fat.h"
30+
#include "systick.h"
31+
#include "led.h"
32+
#include "storage.h"
2833
#include "factoryreset.h"
2934

3035
#if MICROPY_HW_ENABLE_STORAGE
@@ -96,4 +101,31 @@ MP_WEAK void factory_reset_make_files(FATFS *fatfs) {
96101
}
97102
}
98103

104+
MP_WEAK int factory_reset_create_filesystem(void) {
105+
// LED on to indicate creation of local filesystem
106+
led_state(PYB_LED_GREEN, 1);
107+
uint32_t start_tick = HAL_GetTick();
108+
109+
fs_user_mount_t vfs;
110+
pyb_flash_init_vfs(&vfs);
111+
uint8_t working_buf[FF_MAX_SS];
112+
FRESULT res = f_mkfs(&vfs.fatfs, FM_FAT, 0, working_buf, sizeof(working_buf));
113+
if (res != FR_OK) {
114+
mp_printf(&mp_plat_print, "MPY: can't create flash filesystem\n");
115+
return -MP_ENODEV;
116+
}
117+
118+
// Set label
119+
f_setlabel(&vfs.fatfs, MICROPY_HW_FLASH_FS_LABEL);
120+
121+
// Populate the filesystem with factory files
122+
factory_reset_make_files(&vfs.fatfs);
123+
124+
// Keep LED on for at least 200ms
125+
systick_wait_at_least(start_tick, 200);
126+
led_state(PYB_LED_GREEN, 0);
127+
128+
return 0; // success
129+
}
130+
99131
#endif // MICROPY_HW_ENABLE_STORAGE

ports/stm32/factoryreset.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@
2929
#include "lib/oofatfs/ff.h"
3030

3131
void factory_reset_make_files(FATFS *fatfs);
32+
int factory_reset_create_filesystem(void);
3233

3334
#endif // MICROPY_INCLUDED_STM32_FACTORYRESET_H

ports/stm32/main.c

Lines changed: 37 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "py/runtime.h"
3131
#include "py/stackctrl.h"
3232
#include "py/gc.h"
33+
#include "py/mperrno.h"
3334
#include "py/mphal.h"
3435
#include "lib/mp-readline/readline.h"
3536
#include "lib/utils/pyexec.h"
@@ -81,10 +82,6 @@
8182
STATIC pyb_thread_t pyb_thread_main;
8283
#endif
8384

84-
#if MICROPY_HW_ENABLE_STORAGE
85-
STATIC fs_user_mount_t fs_user_mount_flash;
86-
#endif
87-
8885
#if defined(MICROPY_HW_UART_REPL)
8986
#ifndef MICROPY_HW_UART_REPL_RXBUF
9087
#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
159156
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_main_obj, 1, pyb_main);
160157

161158
#if MICROPY_HW_ENABLE_STORAGE
159+
STATIC int vfs_mount_and_chdir(mp_obj_t bdev, mp_obj_t mount_point) {
160+
nlr_buf_t nlr;
161+
mp_int_t ret = -MP_EIO;
162+
if (nlr_push(&nlr) == 0) {
163+
mp_obj_t args[] = { bdev, mount_point };
164+
mp_vfs_mount(2, args, (mp_map_t*)&mp_const_empty_map);
165+
mp_vfs_chdir(mount_point);
166+
ret = 0; // success
167+
nlr_pop();
168+
} else {
169+
mp_obj_base_t *exc = nlr.ret_val;
170+
if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(exc->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) {
171+
mp_obj_t v = mp_obj_exception_get_value(MP_OBJ_FROM_PTR(exc));
172+
mp_obj_get_int_maybe(v, &ret); // get errno value
173+
ret = -ret;
174+
}
175+
}
176+
return ret;
177+
}
178+
162179
// avoid inlining to avoid stack usage within main()
163180
MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) {
164-
// init the vfs object
165-
fs_user_mount_t *vfs_fat = &fs_user_mount_flash;
166-
vfs_fat->blockdev.flags = 0;
167-
pyb_flash_init_vfs(vfs_fat);
168-
169-
// try to mount the flash
170-
FRESULT res = f_mount(&vfs_fat->fatfs);
181+
if (reset_mode == 3) {
182+
// Asked by user to reset filesystem
183+
factory_reset_create_filesystem();
184+
}
171185

172-
if (reset_mode == 3 || res == FR_NO_FILESYSTEM) {
173-
// no filesystem, or asked to reset it, so create a fresh one
186+
// Try to mount the flash on "/flash" and chdir to it for the boot-up directory.
187+
mp_obj_t bdev = MP_OBJ_FROM_ E413 PTR(&pyb_flash_obj);
188+
mp_obj_t mount_point = MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash);
189+
int ret = vfs_mount_and_chdir(bdev, mount_point);
174190

175-
// LED on to indicate creation of LFS
176-
led_state(PYB_LED_GREEN, 1);
177-
uint32_t start_tick = HAL_GetTick();
178-
179-
uint8_t working_buf[FF_MAX_SS];
180-
res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf));
181-
if (res == FR_OK) {
182-
// success creating fresh LFS
183-
} else {
184-
printf("MPY: can't create flash filesystem\n");
185-
return false;
191+
if (ret == -MP_ENODEV && reset_mode != 3) {
192+
// No filesystem (and didn't already create one), try to create a fresh one
193+
ret = factory_reset_create_filesystem();
194+
if (ret == 0) {
195+
ret = vfs_mount_and_chdir(bdev, mount_point);
186196
}
197+
}
187198

188-
// set label
189-
f_setlabel(&vfs_fat->fatfs, MICROPY_HW_FLASH_FS_LABEL);
190-
191-
// populate the filesystem with factory files
192-
factory_reset_make_files(&vfs_fat->fatfs);
193-
194-
// keep LED on for at least 200ms
195-
systick_wait_at_least(start_tick, 200);
196-
led_state(PYB_LED_GREEN, 0);
197-
} else if (res == FR_OK) {
198-
// mount sucessful
199-
} else {
200-
fail:
199+
if (ret != 0) {
201200
printf("MPY: can't mount flash\n");
202201
return false;
203202
}
204203

205-
// mount the flash device (there should be no other devices mounted at this point)
206-
// we allocate this structure on the heap because vfs->next is a root pointer
207-
mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
208-
if (vfs == NULL) {
209-
goto fail;
210-
}
211-
vfs->str = "/flash";
212-
vfs->len = 6;
213-
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
214-
vfs->next = NULL;
215-
MP_STATE_VM(vfs_mount_table) = vfs;
216-
217-
// The current directory is used as the boot up directory.
218-
// It is set to the internal flash filesystem by default.
219-
MP_STATE_PORT(vfs_cur) = vfs;
220-
221204
return true;
222205
}
223206
#endif
@@ -616,7 +599,7 @@ void stm32_main(uint32_t reset_mode) {
616599
// if an SD card is present then mount it on /sd/
617600
if (sdcard_is_present()) {
618601
// if there is a file in the flash called "SKIPSD", then we don't mount the SD card
619-
if (!mounted_flash || f_stat(&fs_user_mount_flash.fatfs, "/SKIPSD", NULL) != FR_OK) {
602+
if (!mounted_flash || mp_vfs_import_stat("SKIPSD") == MP_IMPORT_STAT_FILE) {
620603
mounted_sdcard = init_sdcard_fs();
621604
}
622605
}

ports/stm32/storage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ mp_uint_t storage_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t
234234
// Expose the flash as an object with the block protocol.
235235

236236
// there is a singleton Flash object
237-
STATIC const mp_obj_base_t pyb_flash_obj = {&pyb_flash_type};
237+
const mp_obj_base_t pyb_flash_obj = {&pyb_flash_type};
238238

239239
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) {
240240
// check arguments

ports/stm32/storage.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ int spi_bdev_readblocks(spi_bdev_t *bdev, uint8_t *dest, uint32_t block_num, uin
6363
int spi_bdev_writeblocks(spi_bdev_t *bdev, const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
6464

6565
extern const struct _mp_obj_type_t pyb_flash_type;
66+
extern const struct _mp_obj_base_t pyb_flash_obj;
6667

6768
struct _fs_user_mount_t;
6869
void pyb_flash_init_vfs(struct _fs_user_mount_t *vfs);

0 commit comments

Comments
 (0)
0