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" );
4140static_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+
4749static_assert (MICROPY_HW_FLASH_STORAGE_BYTES <= PICO_FLASH_SIZE_BYTES , "MICROPY_HW_FLASH_STORAGE_BYTES too big" );
4850static_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+
5666static 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+
141164static 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