diff --git a/ports/nrf/boards/memory.ld b/ports/nrf/boards/memory.ld index 9c4c9c8bd1..df95b951b0 100644 --- a/ports/nrf/boards/memory.ld +++ b/ports/nrf/boards/memory.ld @@ -8,10 +8,12 @@ _head_size = DEFINED(_sd_size) ? _sd_size : _bootloader_head_size; _head_ram = DEFINED(_sd_ram) ? _sd_ram : _bootloader_head_ram_size; _sd_size = DEFINED(_sd_size) ? _sd_size : 0; _sd_ram = DEFINED(_sd_ram) ? _sd_ram : 0; +_micropy_hw_romfs_part0_size = DEFINED(_micropy_hw_romfs_part0_size) ? _micropy_hw_romfs_part0_size : 0; _fs_size = DEFINED(_fs_size) ? _fs_size : 64K; /* TODO: set to 0 if not using the filesystem */ -_app_size = _flash_size - _head_size - _fs_size - _bootloader_tail_size; +_app_size = _flash_size - _head_size - _micropy_hw_romfs_part0_size - _fs_size - _bootloader_tail_size; _app_start = _head_size; -_fs_start = _head_size + _app_size; +_micropy_hw_romfs_part0_start = _head_size + _app_size; +_fs_start = _micropy_hw_romfs_part0_start + _micropy_hw_romfs_part0_size; _fs_end = _fs_start + _fs_size; _app_ram_start = 0x20000000 + _head_ram; _app_ram_size = _ram_size - _head_ram; diff --git a/ports/nrf/boards/nrf51x22_256k_16k.ld b/ports/nrf/boards/nrf51x22_256k_16k.ld index 8a40ae0f17..4c54def8e8 100644 --- a/ports/nrf/boards/nrf51x22_256k_16k.ld +++ b/ports/nrf/boards/nrf51x22_256k_16k.ld @@ -6,6 +6,7 @@ GROUP(-lgcc -lc -lnosys) _flash_size = 256K; _ram_size = 16K; +_micropy_hw_romfs_part0_size = 12K; /* Default stack size when there is no SoftDevice */ _stack_size = 4K; diff --git a/ports/nrf/boards/nrf51x22_256k_32k.ld b/ports/nrf/boards/nrf51x22_256k_32k.ld index 06c0914035..b61c2a5505 100644 --- a/ports/nrf/boards/nrf51x22_256k_32k.ld +++ b/ports/nrf/boards/nrf51x22_256k_32k.ld @@ -6,6 +6,7 @@ GROUP(-lgcc -lc -lnosys) _flash_size = 256K; _ram_size = 32K; +_micropy_hw_romfs_part0_size = 12K; /* Default stack size when there is no SoftDevice */ _stack_size = 4K; diff --git a/ports/nrf/boards/nrf52832_512k_64k.ld b/ports/nrf/boards/nrf52832_512k_64k.ld index 22804df5cd..0599c9bda3 100644 --- a/ports/nrf/boards/nrf52832_512k_64k.ld +++ b/ports/nrf/boards/nrf52832_512k_64k.ld @@ -4,6 +4,7 @@ _flash_size = 512K; _ram_size = 64K; +_micropy_hw_romfs_part0_size = 128K; /* produce a link error if there is not this amount of RAM for these sections */ _stack_size = 8K; diff --git a/ports/nrf/boards/nrf52840_1M_256k.ld b/ports/nrf/boards/nrf52840_1M_256k.ld index 16d61af6a3..21d4518243 100644 --- a/ports/nrf/boards/nrf52840_1M_256k.ld +++ b/ports/nrf/boards/nrf52840_1M_256k.ld @@ -4,6 +4,7 @@ _flash_size = 1M; _ram_size = 256K; +_micropy_hw_romfs_part0_size = 256K; /* produce a link error if there is not this amount of RAM for these sections */ _stack_size = 8K; diff --git a/ports/nrf/boards/nrf9160_1M_256k.ld b/ports/nrf/boards/nrf9160_1M_256k.ld index 6347095a89..d8f0aa5cb0 100644 --- a/ports/nrf/boards/nrf9160_1M_256k.ld +++ b/ports/nrf/boards/nrf9160_1M_256k.ld @@ -7,6 +7,7 @@ _ram_size = 256K; _sd_size = 0x00008000; _sd_ram = 0x00020000; _fs_size = 80K; +_micropy_hw_romfs_part0_size = 256K; /* produce a link error if there is not this amount of RAM for these sections */ _stack_size = 32K; diff --git a/ports/nrf/main.c b/ports/nrf/main.c index 7278a646ab..1013005e19 100644 --- a/ports/nrf/main.c +++ b/ports/nrf/main.c @@ -177,22 +177,8 @@ soft_reset: #if MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE flashbdev_init(); - - // Try to mount the flash on "/flash" and chdir to it for the boot-up directory. - mp_obj_t mount_point = MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash); - int ret = mp_vfs_mount_and_chdir_protected((mp_obj_t)&nrf_flash_obj, mount_point); - - if ((ret == -MP_ENODEV) || (ret == -MP_EIO)) { - pyexec_frozen_module("_mkfs.py", false); // Frozen script for formatting flash filesystem. - ret = mp_vfs_mount_and_chdir_protected((mp_obj_t)&nrf_flash_obj, mount_point); - } - - if (ret != 0) { - printf("MPY: can't mount flash\n"); - } else { - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash)); - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib)); - } + // Execute _boot.py to set up the filesystem. + pyexec_frozen_module("_boot.py", false); #endif #if MICROPY_MBFS diff --git a/ports/nrf/modules/manifest.py b/ports/nrf/modules/manifest.py index 7ba0f80d88..631ad19a8d 100644 --- a/ports/nrf/modules/manifest.py +++ b/ports/nrf/modules/manifest.py @@ -1,2 +1,2 @@ -module("_mkfs.py", base_path="$(PORT_DIR)/modules/scripts", opt=3) +module("_boot.py", base_path="$(PORT_DIR)/modules/scripts", opt=3) include("$(MPY_DIR)/extmod/asyncio") diff --git a/ports/nrf/modules/nrf/flashbdev.c b/ports/nrf/modules/nrf/flashbdev.c index 41833b228e..b28314b4a6 100644 --- a/ports/nrf/modules/nrf/flashbdev.c +++ b/ports/nrf/modules/nrf/flashbdev.c @@ -183,12 +183,26 @@ static mp_obj_t nrf_flashbdev_make_new(const mp_obj_type_t *type, size_t n_args, return MP_OBJ_FROM_PTR(self); } +static mp_int_t nrf_flashbdev_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + nrf_flash_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (flags == MP_BUFFER_READ) { + bufinfo->buf = (void *)self->start; + bufinfo->len = self->len; + bufinfo->typecode = 'B'; + return 0; + } else { + // Unsupported. + return 1; + } +} + MP_DEFINE_CONST_OBJ_TYPE( nrf_flashbdev_type, MP_QSTR_Flash, MP_TYPE_FLAG_NONE, make_new, nrf_flashbdev_make_new, print, nrf_flashbdev_print, + buffer, nrf_flashbdev_get_buffer, locals_dict, &nrf_flashbdev_locals_dict ); @@ -202,4 +216,34 @@ void flashbdev_init(void) { nrf_flash_obj.len = num_pages * FLASH_PAGESIZE; } +#if MICROPY_VFS_ROM + +extern byte _micropy_hw_romfs_part0_start[]; +extern byte _micropy_hw_romfs_part0_size[]; + +#define MICROPY_HW_ROMFS_BASE ((uint32_t)_micropy_hw_romfs_part0_start) +#define MICROPY_HW_ROMFS_BYTES ((uint32_t)_micropy_hw_romfs_part0_size) + +static nrf_flash_obj_t nrf_flash_romfs_obj = { + .base = { &nrf_flashbdev_type }, + .start = MICROPY_HW_ROMFS_BASE, // Get from MCU-Specific loader script. + .len = MICROPY_HW_ROMFS_BYTES, // Get from MCU-Specific loader script. +}; + +mp_obj_t mp_vfs_rom_ioctl(size_t n_args, const mp_obj_t *args) { + if (MICROPY_HW_ROMFS_BYTES <= 0) { + return MP_OBJ_NEW_SMALL_INT(-MP_EINVAL); + } + switch (mp_obj_get_int(args[0])) { + case MP_VFS_ROM_IOCTL_GET_NUMBER_OF_SEGMENTS: + return MP_OBJ_NEW_SMALL_INT(1); + case MP_VFS_ROM_IOCTL_GET_SEGMENT: + return MP_OBJ_FROM_PTR(&nrf_flash_romfs_obj); + default: + return MP_OBJ_NEW_SMALL_INT(-MP_EINVAL); + } +} + +#endif // MICROPY_VFS_ROM + #endif // MICROPY_PY_NRF && MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE diff --git a/ports/nrf/modules/scripts/_boot.py b/ports/nrf/modules/scripts/_boot.py new file mode 100644 index 0000000000..793c56ee14 --- /dev/null +++ b/ports/nrf/modules/scripts/_boot.py @@ -0,0 +1,28 @@ +def setup_fs(): + import gc + import vfs + import sys + import nrf + import os + + fs_type = getattr(vfs, "VfsLfs2", getattr(vfs, "VfsLfs1", getattr(vfs, "VfsFat", None))) + try: + bdev = nrf.Flash() + vfs.mount(bdev, "/flash") + except: + if fs_type is not None: + try: + fs_type.mkfs(bdev) + vfs.mount(bdev, "/flash") + except: + return + + os.chdir("/flash") + sys.path.append("/flash") + sys.path.append("/flash/lib") + + gc.collect() + + +setup_fs() +del setup_fs diff --git a/ports/nrf/modules/scripts/_mkfs.py b/ports/nrf/modules/scripts/_mkfs.py deleted file mode 100644 index 601f9558eb..0000000000 --- a/ports/nrf/modules/scripts/_mkfs.py +++ /dev/null @@ -1,23 +0,0 @@ -import vfs, nrf - -try: - from vfs import VfsLfs1 - - vfs.VfsLfs1.mkfs(nrf.Flash()) -except ImportError: - try: - from vfs import VfsLfs2 - - vfs.VfsLfs2.mkfs(nrf.Flash()) - except ImportError: - try: - from vfs import VfsFat - - vfs.VfsFat.mkfs(nrf.Flash()) - except ImportError: - pass - except OSError as e: - if e.args[0] == 5: # I/O Error - flashbdev_size = (nrf.Flash.ioctl(4, 0) * nrf.Flash.ioctl(5, 0)) // 1024 - print() - print("Is `FS_SIZE=%iK` enough for FAT filesystem?" % flashbdev_size) diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index cce3f86cfd..bb517c19c5 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -69,6 +69,11 @@ #define MICROPY_VFS (CORE_FEAT) #endif +// VfsROM filesystem +#ifndef MICROPY_VFS_ROM +#define MICROPY_VFS_ROM (CORE_FEAT) +#endif + // micro:bit filesystem #ifndef MICROPY_MBFS #define MICROPY_MBFS (!MICROPY_VFS)