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 <damien@micropython.org>
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)
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