Skip to content

Commit dd2cb5f

Browse files
committed
Make SD cards available over web workflow
This changes storage.mount() to require that a mount point exist on the parent file system. A bug in background tasks is also fixed where the function parameter is cleared on pending callbacks during "reset". Disk usage is shown on the directory listing and changes based on the mounted file system. Writable is also loaded per-directory. Fixes micropython#8108. Fixes micropython#8690. Fixes micropython#8107.
1 parent 156f417 commit dd2cb5f

File tree

19 files changed

+323
-123
lines changed

19 files changed

+323
-123
lines changed

extmod/vfs_blockdev.c

+47-4
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,46 @@
3030
#include "py/mperrno.h"
3131
#include "extmod/vfs.h"
3232

33+
#if CIRCUITPY_SDCARDIO
34+
#include "shared-bindings/sdcardio/SDCard.h"
35+
#endif
36+
#if CIRCUITPY_SDIOIO
37+
#include "shared-bindings/sdioio/SDCard.h"
38+
#endif
39+
40+
#include "esp_log.h"
41+
42+
static const char *TAG = "vfs_blockdev";
43+
3344
#if MICROPY_VFS
3445

3546
void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
3647
mp_load_method(bdev, MP_QSTR_readblocks, self->readblocks);
3748
mp_load_method_maybe(bdev, MP_QSTR_writeblocks, self->writeblocks);
3849
mp_load_method_maybe(bdev, MP_QSTR_ioctl, self->u.ioctl);
50+
ESP_LOGI(TAG, "new vfs blockdev %p around %p", self, MP_OBJ_TO_PTR(bdev));
51+
52+
// CIRCUITPY-CHANGE: Support native SD cards.
53+
#if CIRCUITPY_SDCARDIO
54+
if (mp_obj_get_type(bdev) == &sdcardio_SDCard_type) {
55+
ESP_LOGI(TAG, "sdcardio.SDCard");
56+
self->flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL;
57+
self->readblocks[0] = mp_const_none;
58+
self->readblocks[1] = bdev;
59+
self->readblocks[2] = (mp_obj_t)sdcardio_sdcard_readblocks; // native version
60+
self->writeblocks[0] = mp_const_none;
61+
self->writeblocks[1] = bdev;
62+
self->writeblocks[2] = (mp_obj_t)sdcardio_sdcard_writeblocks; // native version
63+
self->u.ioctl[0] = mp_const_none;
64+
self->u.ioctl[1] = bdev;
65+
self->u.ioctl[2] = (mp_obj_t)sdcardio_sdcard_ioctl; // native version
66+
}
67+
#endif
68+
#if CIRCUITPY_SDIOIO
69+
if (mp_obj_get_type(bdev) == &sdioio_SDCard_type) {
70+
// TODO: Enable native blockdev for SDIO too.
71+
}
72+
#endif
3973
if (self->u.ioctl[0] != MP_OBJ_NULL) {
4074
// Device supports new block protocol, so indicate it
4175
self->flags |= MP_BLOCKDEV_FLAG_HAVE_IOCTL;
@@ -48,8 +82,8 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
4882

4983
int mp_vfs_blockdev_read(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, uint8_t *buf) {
5084
if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) {
51-
mp_uint_t (*f)(uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->readblocks[2];
52-
return f(buf, block_num, num_blocks);
85+
mp_uint_t (*f)(mp_obj_t self, uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->readblocks[2];
86+
return f(self->readblocks[1], buf, block_num, num_blocks);
5387
} else {
5488
mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, buf};
5589
self->readblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
@@ -80,8 +114,8 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_
80114
}
81115

82116
if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) {
83-
mp_uint_t (*f)(const uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->writeblocks[2];
84-
return f(buf, block_num, num_blocks);
117+
mp_uint_t (*f)(mp_obj_t self, const uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->writeblocks[2];
118+
return f(self->writeblocks[1], buf, block_num, num_blocks);
85119
} else {
86120
mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, (void *)buf};
87121
self->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
@@ -112,6 +146,15 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
112146

113147
mp_obj_t mp_vfs_blockdev_ioctl(mp_vfs_blockdev_t *self, uintptr_t cmd, uintptr_t arg) {
114148
if (self->flags & MP_BLOCKDEV_FLAG_HAVE_IOCTL) {
149+
if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) {
150+
size_t out_value;
151+
bool (*f)(mp_obj_t self, uint32_t, uint32_t, size_t *) = (void *)(uintptr_t)self->u.ioctl[2];
152+
bool b = f(self->u.ioctl[1], cmd, arg, &out_value);
153+
if (!b) {
154+
return mp_const_none;
155+
}
156+
return MP_OBJ_NEW_SMALL_INT(out_value);
157+
}
115158
// New protocol with ioctl
116159
self->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(cmd);
117160
self->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(arg);

locale/circuitpython.pot

+4
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,10 @@ msgstr ""
13641364
msgid "Missing jmp_pin. %q[%u] jumps on pin"
13651365
msgstr ""
13661366

1367+
#: shared-module/storage/__init__.c
1368+
msgid "Mount point missing. Create first (maybe via USB)"
1369+
msgstr ""
1370+
13671371
#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c
13681372
msgid "Must be a %q subclass."
13691373
msgstr ""

ports/espressif/supervisor/internal_flash.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ STATIC uint32_t _cache_lba = 0xffffffff;
6060
#define SECSIZE(fs) ((fs)->ssize)
6161
#endif // FF_MAX_SS == FF_MIN_SS
6262
STATIC DWORD fatfs_bytes(void) {
63-
FATFS *fatfs = filesystem_circuitpy();
63+
fs_user_mount_t *fs_mount = filesystem_circuitpy();
64+
FATFS *fatfs = &fs_mount->fatfs;
6465
return (fatfs->csize * SECSIZE(fatfs)) * (fatfs->n_fatent - 2);
6566
}
6667
STATIC bool storage_extended = true;

ports/espressif/supervisor/port.c

+15-15
Original file line numberDiff line numberDiff line change
@@ -284,21 +284,21 @@ safe_mode_t port_init(void) {
284284
#define ENABLE_JTAG (defined(DEBUG) && DEBUG)
285285
#endif
286286

287-
#if ENABLE_JTAG
288-
ESP_LOGI(TAG, "Marking JTAG pins never_reset");
289-
// JTAG
290-
#ifdef CONFIG_IDF_TARGET_ESP32C3
291-
common_hal_never_reset_pin(&pin_GPIO4);
292-
common_hal_never_reset_pin(&pin_GPIO5);
293-
common_hal_never_reset_pin(&pin_GPIO6);
294-
common_hal_never_reset_pin(&pin_GPIO7);
295-
#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
296-
common_hal_never_reset_pin(&pin_GPIO39);
297-
common_hal_never_reset_pin(&pin_GPIO40);
298-
common_hal_never_reset_pin(&pin_GPIO41);
299-
common_hal_never_reset_pin(&pin_GPIO42);
300-
#endif
301-
#endif
287+
// #if ENABLE_JTAG
288+
// ESP_LOGI(TAG, "Marking JTAG pins never_reset");
289+
// // JTAG
290+
// #ifdef CONFIG_IDF_TARGET_ESP32C3
291+
// common_hal_never_reset_pin(&pin_GPIO4);
292+
// common_hal_never_reset_pin(&pin_GPIO5);
293+
// common_hal_never_reset_pin(&pin_GPIO6);
294+
// common_hal_never_reset_pin(&pin_GPIO7);
295+
// #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
296+
// common_hal_never_reset_pin(&pin_GPIO39);
297+
// common_hal_never_reset_pin(&pin_GPIO40);
298+
// common_hal_never_reset_pin(&pin_GPIO41);
299+
// common_hal_never_reset_pin(&pin_GPIO42);
300+
// #endif
301+
// #endif
302302

303303
_never_reset_spi_ram_flash();
304304

shared-bindings/sdcardio/SDCard.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_deinit_obj, sdcardio_sdcard_deinit);
131131
//|
132132
//| :return: None"""
133133

134-
STATIC mp_obj_t sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
134+
STATIC mp_obj_t _sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
135135
uint32_t start_block = mp_obj_get_int(start_block_in);
136136
mp_buffer_info_t bufinfo;
137137
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
@@ -143,7 +143,7 @@ STATIC mp_obj_t sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_bloc
143143
return mp_const_none;
144144
}
145145

146-
MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_readblocks_obj, sdcardio_sdcard_readblocks);
146+
MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_readblocks_obj, _sdcardio_sdcard_readblocks);
147147

148148
//| def sync(self) -> None:
149149
//| """Ensure all blocks written are actually committed to the SD card
@@ -171,7 +171,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_sync_obj, sdcardio_sdcard_sync);
171171
//| :return: None"""
172172
//|
173173

174-
STATIC mp_obj_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
174+
STATIC mp_obj_t _sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
175175
uint32_t start_block = mp_obj_get_int(start_block_in);
176176
mp_buffer_info_t bufinfo;
177177
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
@@ -182,7 +182,7 @@ STATIC mp_obj_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_blo
182182
}
183183
return mp_const_none;
184184
}
185-
MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_writeblocks_obj, sdcardio_sdcard_writeblocks);
185+
MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_writeblocks_obj, _sdcardio_sdcard_writeblocks);
186186

187187
STATIC const mp_rom_map_elem_t sdcardio_sdcard_locals_dict_table[] = {
188188
{ MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&sdcardio_sdcard_count_obj) },

shared-bindings/sdcardio/SDCard.h

+15
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,19 @@
2727

2828
#pragma once
2929

30+
#include "shared-module/sdcardio/SDCard.h"
31+
3032
extern const mp_obj_type_t sdcardio_SDCard_type;
33+
34+
void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *cs, int baudrate);
35+
void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self);
36+
void common_hal_sdcardio_sdcard_check_for_deinit(sdcardio_sdcard_obj_t *self);
37+
int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self);
38+
int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf);
39+
int common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self);
40+
int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf);
41+
42+
// Used by native vfs blockdev.
43+
mp_uint_t sdcardio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen);
44+
mp_uint_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen);
45+
bool sdcardio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value);

shared-bindings/sdioio/SDCard.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_count_obj, sdioio_sdcard_count);
164164
//| :param ~circuitpython_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512.
165165
//|
166166
//| :return: None"""
167-
STATIC mp_obj_t sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
167+
STATIC mp_obj_t _sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
168168
uint32_t start_block = mp_obj_get_int(start_block_in);
169169
mp_buffer_info_t bufinfo;
170170
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
@@ -176,7 +176,7 @@ STATIC mp_obj_t sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_
176176
return mp_const_none;
177177
}
178178

179-
MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, sdioio_sdcard_readblocks);
179+
MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, _sdioio_sdcard_readblocks);
180180

181181
//| def writeblocks(self, start_block: int, buf: ReadableBuffer) -> None:
182182
//| """Write one or more blocks to the card
@@ -185,7 +185,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, sdioio_sdcard_readblocks
185185
//| :param ~circuitpython_typing.ReadableBuffer buf: The buffer to read from. Length must be multiple of 512.
186186
//|
187187
//| :return: None"""
188-
STATIC mp_obj_t sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
188+
STATIC mp_obj_t _sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
189189
uint32_t start_block = mp_obj_get_int(start_block_in);
190190
mp_buffer_info_t bufinfo;
191191
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
@@ -197,7 +197,7 @@ STATIC mp_obj_t sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block
197197
return mp_const_none;
198198
}
199199

200-
MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_writeblocks_obj, sdioio_sdcard_writeblocks);
200+
MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_writeblocks_obj, _sdioio_sdcard_writeblocks);
201201

202202
//| frequency: int
203203
//| """The actual SDIO bus frequency. This may not match the frequency

shared-bindings/sdioio/SDCard.h

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ uint32_t common_hal_sdioio_sdcard_get_count(sdioio_sdcard_obj_t *self);
6060
int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo);
6161
int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo);
6262

63+
// Used by native vfs blockdev.
64+
mp_uint_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen);
65+
mp_uint_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen);
66+
bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value);
67+
6368
// This is used by the supervisor to claim SDIO devices indefinitely.
6469
extern void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self);
6570

shared-module/os/getenv.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,12 @@ STATIC bool open_file(const char *name, file_arg *active_file) {
6262
return false;
6363
}
6464
#else
65-
FATFS *fs = filesystem_circuitpy();
66-
FRESULT result = f_open(fs, active_file, name, FA_READ);
65+
fs_user_mount_t *fs_mount = filesystem_circuitpy();
66+
if (fs_mount == NULL) {
67+
return false;
68+
}
69+
FATFS *fatfs = &fs_mount->fatfs;
70+
FRESULT result = f_open(fatfs, active_file, name, FA_READ);
6771
return result == FR_OK;
6872
#endif
6973
}

0 commit comments

Comments
 (0)