rp2: Implement vfs.rom_ioctl with support for external flash.
Not enabled by default on any board. A board can enable a ROMFS partition
by defining `MICROPY_HW_ROMFS_BYTES` in its `mpconfigboard.h` file. For
example:
#define MICROPY_HW_ROMFS_BYTES (128 * 1024)
The ROMFS partition is placed at the end of the flash allocated for the
firmware, giving less space for the firmware. It then lives between the
firmware and the read/write filesystem.
Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -67,6 +67,16 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Number of bytes of flash to allocate to the ROMFS partition.
|
||||||
|
#ifndef MICROPY_HW_ROMFS_BYTES
|
||||||
|
#define MICROPY_HW_ROMFS_BYTES (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Number of bytes of flash to allocate to read/write filesystem storage.
|
||||||
|
#ifndef MICROPY_HW_FLASH_STORAGE_BYTES
|
||||||
|
#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef MICROPY_CONFIG_ROM_LEVEL
|
#ifndef MICROPY_CONFIG_ROM_LEVEL
|
||||||
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES)
|
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES)
|
||||||
#endif
|
#endif
|
||||||
@@ -170,6 +180,7 @@
|
|||||||
#define MICROPY_VFS (1)
|
#define MICROPY_VFS (1)
|
||||||
#define MICROPY_VFS_LFS2 (1)
|
#define MICROPY_VFS_LFS2 (1)
|
||||||
#define MICROPY_VFS_FAT (1)
|
#define MICROPY_VFS_FAT (1)
|
||||||
|
#define MICROPY_VFS_ROM (MICROPY_HW_ROMFS_BYTES > 0)
|
||||||
#define MICROPY_SSL_MBEDTLS (1)
|
#define MICROPY_SSL_MBEDTLS (1)
|
||||||
#define MICROPY_PY_LWIP_PPP (MICROPY_PY_NETWORK_PPP_LWIP)
|
#define MICROPY_PY_LWIP_PPP (MICROPY_PY_NETWORK_PPP_LWIP)
|
||||||
#define MICROPY_PY_LWIP_SOCK_RAW (MICROPY_PY_LWIP)
|
#define MICROPY_PY_LWIP_SOCK_RAW (MICROPY_PY_LWIP)
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
#include "py/mperrno.h"
|
||||||
#include "extmod/vfs.h"
|
#include "extmod/vfs.h"
|
||||||
#include "modrp2.h"
|
#include "modrp2.h"
|
||||||
#include "hardware/flash.h"
|
#include "hardware/flash.h"
|
||||||
@@ -35,15 +36,16 @@
|
|||||||
|
|
||||||
#define BLOCK_SIZE_BYTES (FLASH_SECTOR_SIZE)
|
#define BLOCK_SIZE_BYTES (FLASH_SECTOR_SIZE)
|
||||||
|
|
||||||
#ifndef MICROPY_HW_FLASH_STORAGE_BYTES
|
static_assert(MICROPY_HW_ROMFS_BYTES % 4096 == 0, "ROMFS size must be a multiple of 4K");
|
||||||
#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024)
|
|
||||||
#endif
|
|
||||||
static_assert(MICROPY_HW_FLASH_STORAGE_BYTES % 4096 == 0, "Flash storage size must be a multiple of 4K");
|
static_assert(MICROPY_HW_FLASH_STORAGE_BYTES % 4096 == 0, "Flash storage size must be a multiple of 4K");
|
||||||
|
|
||||||
#ifndef MICROPY_HW_FLASH_STORAGE_BASE
|
#ifndef MICROPY_HW_FLASH_STORAGE_BASE
|
||||||
#define MICROPY_HW_FLASH_STORAGE_BASE (PICO_FLASH_SIZE_BYTES - MICROPY_HW_FLASH_STORAGE_BYTES)
|
#define MICROPY_HW_FLASH_STORAGE_BASE (PICO_FLASH_SIZE_BYTES - MICROPY_HW_FLASH_STORAGE_BYTES)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Put ROMFS at the upper end of the code space.
|
||||||
|
#define MICROPY_HW_ROMFS_BASE (MICROPY_HW_FLASH_STORAGE_BASE - MICROPY_HW_ROMFS_BYTES)
|
||||||
|
|
||||||
static_assert(MICROPY_HW_FLASH_STORAGE_BYTES <= PICO_FLASH_SIZE_BYTES, "MICROPY_HW_FLASH_STORAGE_BYTES too big");
|
static_assert(MICROPY_HW_FLASH_STORAGE_BYTES <= PICO_FLASH_SIZE_BYTES, "MICROPY_HW_FLASH_STORAGE_BYTES too big");
|
||||||
static_assert(MICROPY_HW_FLASH_STORAGE_BASE + MICROPY_HW_FLASH_STORAGE_BYTES <= PICO_FLASH_SIZE_BYTES, "MICROPY_HW_FLASH_STORAGE_BYTES too big");
|
static_assert(MICROPY_HW_FLASH_STORAGE_BASE + MICROPY_HW_FLASH_STORAGE_BYTES <= PICO_FLASH_SIZE_BYTES, "MICROPY_HW_FLASH_STORAGE_BYTES too big");
|
||||||
|
|
||||||
@@ -53,6 +55,14 @@ typedef struct _rp2_flash_obj_t {
|
|||||||
uint32_t flash_size;
|
uint32_t flash_size;
|
||||||
} rp2_flash_obj_t;
|
} rp2_flash_obj_t;
|
||||||
|
|
||||||
|
#if MICROPY_HW_ROMFS_BYTES > 0
|
||||||
|
static rp2_flash_obj_t rp2_flash_romfs_obj = {
|
||||||
|
.base = { &rp2_flash_type },
|
||||||
|
.flash_base = MICROPY_HW_ROMFS_BASE,
|
||||||
|
.flash_size = MICROPY_HW_ROMFS_BYTES,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static rp2_flash_obj_t rp2_flash_obj = {
|
static rp2_flash_obj_t rp2_flash_obj = {
|
||||||
.base = { &rp2_flash_type },
|
.base = { &rp2_flash_type },
|
||||||
.flash_base = MICROPY_HW_FLASH_STORAGE_BASE,
|
.flash_base = MICROPY_HW_FLASH_STORAGE_BASE,
|
||||||
@@ -138,6 +148,19 @@ static mp_obj_t rp2_flash_make_new(const mp_obj_type_t *type, size_t n_args, siz
|
|||||||
return MP_OBJ_FROM_PTR(self);
|
return MP_OBJ_FROM_PTR(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mp_int_t rp2_flash_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
||||||
|
rp2_flash_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
if (flags == MP_BUFFER_READ) {
|
||||||
|
bufinfo->buf = (void *)(XIP_BASE + self->flash_base);
|
||||||
|
bufinfo->len = self->flash_size;
|
||||||
|
bufinfo->typecode = 'B';
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
// Write unsupported.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static mp_obj_t rp2_flash_readblocks(size_t n_args, const mp_obj_t *args) {
|
static mp_obj_t rp2_flash_readblocks(size_t n_args, const mp_obj_t *args) {
|
||||||
rp2_flash_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
rp2_flash_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||||
uint32_t offset = mp_obj_get_int(args[1]) * BLOCK_SIZE_BYTES;
|
uint32_t offset = mp_obj_get_int(args[1]) * BLOCK_SIZE_BYTES;
|
||||||
@@ -218,5 +241,21 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
|||||||
MP_QSTR_Flash,
|
MP_QSTR_Flash,
|
||||||
MP_TYPE_FLAG_NONE,
|
MP_TYPE_FLAG_NONE,
|
||||||
make_new, rp2_flash_make_new,
|
make_new, rp2_flash_make_new,
|
||||||
|
buffer, rp2_flash_get_buffer,
|
||||||
locals_dict, &rp2_flash_locals_dict
|
locals_dict, &rp2_flash_locals_dict
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#if MICROPY_VFS_ROM_IOCTL
|
||||||
|
mp_obj_t mp_vfs_rom_ioctl(size_t n_args, const mp_obj_t *args) {
|
||||||
|
switch (mp_obj_get_int(args[0])) {
|
||||||
|
#if MICROPY_HW_ROMFS_BYTES > 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(&rp2_flash_romfs_obj);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(-MP_EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user