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_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)
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