Skip to content

Commit 50a7362

Browse files
committed
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 <[email protected]>
1 parent 45c36f8 commit 50a7362

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

ports/rp2/mpconfigport.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@
6767
#endif
6868
#endif
6969

70+
// Number of bytes of flash to allocate to the ROMFS partition.
71+
#ifndef MICROPY_HW_ROMFS_BYTES
72+
#define MICROPY_HW_ROMFS_BYTES (0)
73+
#endif
74+
75+
// Number of bytes of flash to allocate to read/write filesystem storage.
76+
#ifndef MICROPY_HW_FLASH_STORAGE_BYTES
77+
#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024)
78+
#endif
79+
7080
#ifndef MICROPY_CONFIG_ROM_LEVEL
7181
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES)
7282
#endif
@@ -170,6 +180,7 @@
170180
#define MICROPY_VFS (1)
171181
#define MICROPY_VFS_LFS2 (1)
172182
#define MICROPY_VFS_FAT (1)
183+
#define MICROPY_VFS_ROM (MICROPY_HW_ROMFS_BYTES > 0)
173184
#define MICROPY_SSL_MBEDTLS (1)
174185
#define MICROPY_PY_LWIP_PPP (MICROPY_PY_NETWORK_PPP_LWIP)
175186
#define MICROPY_PY_LWIP_SOCK_RAW (MICROPY_PY_LWIP)

ports/rp2/rp2_flash.c

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,24 @@
2828

2929
#include "py/mphal.h"
3030
#include "py/runtime.h"
31+
#include "py/mperrno.h"
3132
#include "extmod/vfs.h"
3233
#include "modrp2.h"
3334
#include "hardware/flash.h"
3435
#include "pico/binary_info.h"
3536

3637
#define BLOCK_SIZE_BYTES (FLASH_SECTOR_SIZE)
3738

38-
#ifndef MICROPY_HW_FLASH_STORAGE_BYTES
39-
#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024)
40-
#endif
39+
static_assert(MICROPY_HW_ROMFS_BYTES % 4096 == 0, "ROMFS size must be a multiple of 4K");
4140
static_assert(MICROPY_HW_FLASH_STORAGE_BYTES % 4096 == 0, "Flash storage size must be a multiple of 4K");
4241

4342
#ifndef MICROPY_HW_FLASH_STORAGE_BASE
4443
#define MICROPY_HW_FLASH_STORAGE_BASE (PICO_FLASH_SIZE_BYTES - MICROPY_HW_FLASH_STORAGE_BYTES)
4544
#endif
4645

46+
// Put ROMFS at the upper end of the code space.
47+
#define MICROPY_HW_ROMFS_BASE (MICROPY_HW_FLASH_STORAGE_BASE - MICROPY_HW_ROMFS_BYTES)
48+
4749
static_assert(MICROPY_HW_FLASH_STORAGE_BYTES <= PICO_FLASH_SIZE_BYTES, "MICROPY_HW_FLASH_STORAGE_BYTES too big");
4850
static_assert(MICROPY_HW_FLASH_STORAGE_BASE + MICROPY_HW_FLASH_STORAGE_BYTES <= PICO_FLASH_SIZE_BYTES, "MICROPY_HW_FLASH_STORAGE_BYTES too big");
4951

@@ -53,6 +55,14 @@ typedef struct _rp2_flash_obj_t {
5355
uint32_t flash_size;
5456
} rp2_flash_obj_t;
5557

58+
#if MICROPY_HW_ROMFS_BYTES > 0
59+
static rp2_flash_obj_t rp2_flash_romfs_obj = {
60+
.base = { &rp2_flash_type },
61+
.flash_base = MICROPY_HW_ROMFS_BASE,
62+
.flash_size = MICROPY_HW_ROMFS_BYTES,
63+
};
64+
#endif
65+
5666
static rp2_flash_obj_t rp2_flash_obj = {
5767
.base = { &rp2_flash_type },
5868
.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
138148
return MP_OBJ_FROM_PTR(self);
139149
}
140150

151+
static mp_int_t rp2_flash_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
152+
rp2_flash_obj_t *self = MP_OBJ_TO_PTR(self_in);
153+
if (flags == MP_BUFFER_READ) {
154+
bufinfo->buf = (void *)(XIP_BASE + self->flash_base);
155+
bufinfo->len = self->flash_size;
156+
bufinfo->typecode = 'B';
157+
return 0;
158+
} else {
159+
// Write unsupported.
160+
return 1;
161+
}
162+
}
163+
141164
static mp_obj_t rp2_flash_readblocks(size_t n_args, const mp_obj_t *args) {
142165
rp2_flash_obj_t *self = MP_OBJ_TO_PTR(args[0]);
143166
uint32_t offset = mp_obj_get_int(args[1]) * BLOCK_SIZE_BYTES;
@@ -218,5 +241,21 @@ MP_DEFINE_CONST_OBJ_TYPE(
218241
MP_QSTR_Flash,
219242
MP_TYPE_FLAG_NONE,
220243
make_new, rp2_flash_make_new,
244+
buffer, rp2_flash_get_buffer,
221245
locals_dict, &rp2_flash_locals_dict
222246
);
247+
248+
#if MICROPY_VFS_ROM_IOCTL
249+
mp_obj_t mp_vfs_rom_ioctl(size_t n_args, const mp_obj_t *args) {
250+
switch (mp_obj_get_int(args[0])) {
251+
#if MICROPY_HW_ROMFS_BYTES > 0
252+
case MP_VFS_ROM_IOCTL_GET_NUMBER_OF_SEGMENTS:
253+
return MP_OBJ_NEW_SMALL_INT(1);
254+
case MP_VFS_ROM_IOCTL_GET_SEGMENT:
255+
return MP_OBJ_FROM_PTR(&rp2_flash_romfs_obj);
256+
#endif
257+
default:
258+
return MP_OBJ_NEW_SMALL_INT(-MP_EINVAL);
259+
}
260+
}
261+
#endif

0 commit comments

Comments
 (0)