|
35 | 35 | #include "lib/mp-readline/readline.h"
|
36 | 36 | #include "lib/utils/pyexec.h"
|
37 | 37 | #include "lib/oofatfs/ff.h"
|
| 38 | +#include "lib/littlefs/lfs1.h" |
| 39 | +#include "lib/littlefs/lfs1_util.h" |
| 40 | +#include "lib/littlefs/lfs2.h" |
| 41 | +#include "lib/littlefs/lfs2_util.h" |
38 | 42 | #include "extmod/vfs.h"
|
39 | 43 | #include "extmod/vfs_fat.h"
|
| 44 | +#include "extmod/vfs_lfs.h" |
40 | 45 |
|
41 | 46 | #if MICROPY_PY_LWIP
|
42 | 47 | #include "lwip/init.h"
|
@@ -183,13 +188,53 @@ MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) {
|
183 | 188 | factory_reset_create_filesystem();
|
184 | 189 | }
|
185 | 190 |
|
186 |
| - // Try to mount the flash on "/flash" and chdir to it for the boot-up directory. |
| 191 | + // Default block device to entire flash storage |
187 | 192 | mp_obj_t bdev = MP_OBJ_FROM_PTR(&pyb_flash_obj);
|
| 193 | + |
| 194 | + #if MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2 |
| 195 | + |
| 196 | + // Try to detect the block device used for the main filesystem, based on the first block |
| 197 | + |
| 198 | + uint8_t buf[FLASH_BLOCK_SIZE]; |
| 199 | + storage_read_blocks(buf, FLASH_PART1_START_BLOCK, 1); |
| 200 | + |
| 201 | + mp_int_t len = -1; |
| 202 | + |
| 203 | + #if MICROPY_VFS_LFS1 |
| 204 | + if (memcmp(&buf[40], "littlefs", 8) == 0) { |
| 205 | + // LFS1 |
| 206 | + lfs1_superblock_t *superblock = (void*)&buf[12]; |
| 207 | + uint32_t block_size = lfs1_fromle32(superblock->d.block_size); |
| 208 | + uint32_t block_count = lfs1_fromle32(superblock->d.block_count); |
| 209 | + len = block_count * block_size; |
| 210 | + } |
| 211 | + #endif |
| 212 | + |
| 213 | + #if MICROPY_VFS_LFS2 |
| 214 | + if (memcmp(&buf[8], "littlefs", 8) == 0) { |
| 215 | + // LFS2 |
| 216 | + lfs2_superblock_t *superblock = (void*)&buf[20]; |
| 217 | + uint32_t block_size = lfs2_fromle32(superblock->block_size); |
| 218 | + uint32_t block_count = lfs2_fromle32(superblock->block_count); |
| 219 | + len = block_count * block_size; |
| 220 | + } |
| 221 | + #endif |
| 222 | + |
| 223 | + if (len != -1) { |
| 224 | + // Detected a littlefs filesystem so create correct block device for it |
| 225 | + mp_obj_t args[] = { MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_NEW_SMALL_INT(len) }; |
| 226 | + bdev = pyb_flash_type.make_new(&pyb_flash_type, 2, 0, args); |
| 227 | + } |
| 228 | + |
| 229 | + #endif |
| 230 | + |
| 231 | + // Try to mount the flash on "/flash" and chdir to it for the boot-up directory. |
188 | 232 | mp_obj_t mount_point = MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash);
|
189 | 233 | int ret = vfs_mount_and_chdir(bdev, mount_point);
|
190 | 234 |
|
191 |
| - if (ret == -MP_ENODEV && reset_mode != 3) { |
192 |
| - // No filesystem (and didn't already create one), try to create a fresh one |
| 235 | + if (ret == -MP_ENODEV && bdev == MP_OBJ_FROM_PTR(&pyb_flash_obj) && reset_mode != 3) { |
| 236 | + // No filesystem, bdev is still the default (so didn't detect a possibly corrupt littlefs), |
| 237 | + // and didn't already create a filesystem, so try to create a fresh one now. |
193 | 238 | ret = factory_reset_create_filesystem();
|
194 | 239 | if (ret == 0) {
|
195 | 240 | ret = vfs_mount_and_chdir(bdev, mount_point);
|
|
0 commit comments