summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal
diff options
context:
space:
mode:
Diffstat (limited to 'stmhal')
-rw-r--r--stmhal/diskio.c322
-rw-r--r--stmhal/fatfs_port.c3
-rw-r--r--stmhal/ffconf.c28
-rw-r--r--stmhal/main.c49
-rw-r--r--stmhal/moduos.c52
-rw-r--r--stmhal/mpconfigport.h6
-rw-r--r--stmhal/sdcard.c12
-rw-r--r--stmhal/sdcard.h3
-rw-r--r--stmhal/storage.c12
-rw-r--r--stmhal/storage.h3
10 files changed, 237 insertions, 253 deletions
diff --git a/stmhal/diskio.c b/stmhal/diskio.c
index 9a4efd1a4d..998729a70d 100644
--- a/stmhal/diskio.c
+++ b/stmhal/diskio.c
@@ -35,17 +35,23 @@
#include "py/runtime.h"
#include "lib/fatfs/ff.h" /* FatFs lower layer API */
#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
-#include "storage.h"
-#include "sdcard.h"
#include "extmod/fsusermount.h"
// constants for block protocol ioctl
-//#define BP_IOCTL_INIT (1) // unused
+#define BP_IOCTL_INIT (1)
//#define BP_IOCTL_DEINIT (2) // unused
#define BP_IOCTL_SYNC (3)
#define BP_IOCTL_SEC_COUNT (4)
#define BP_IOCTL_SEC_SIZE (5)
+STATIC fs_user_mount_t *disk_get_device(uint id) {
+ if (id < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
+ return MP_STATE_PORT(fs_user_mount)[id];
+ } else {
+ return NULL;
+ }
+}
+
/*-----------------------------------------------------------------------*/
/* Initialize a Drive */
/*-----------------------------------------------------------------------*/
@@ -54,33 +60,27 @@ DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber (0..) */
)
{
- switch (pdrv) {
-#if MICROPY_HW_HAS_FLASH
- case PD_FLASH:
- storage_init();
- return 0;
-#endif
-
-#if MICROPY_HW_HAS_SDCARD
- case PD_SDCARD:
- if (!sdcard_power_on()) {
- return STA_NODISK;
- }
- // TODO return STA_PROTECT if SD card is read only
- return 0;
-#endif
+ fs_user_mount_t *vfs = disk_get_device(pdrv);
+ if (vfs == NULL) {
+ return STA_NOINIT;
+ }
- case PD_USER:
- if (MP_STATE_PORT(fs_user_mount) == NULL) {
- return STA_NODISK;
- }
- if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) {
- return STA_PROTECT;
- }
- return 0;
+ if (vfs->flags & FSUSER_HAVE_IOCTL) {
+ // new protocol with ioctl; call ioctl(INIT, 0)
+ vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_INIT);
+ vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
+ mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl);
+ if (MP_OBJ_SMALL_INT_VALUE(ret) != 0) {
+ // error initialising
+ return STA_NOINIT;
+ }
}
- return STA_NOINIT;
+ if (vfs->writeblocks[0] == MP_OBJ_NULL) {
+ return STA_PROTECT;
+ } else {
+ return 0;
+ }
}
/*-----------------------------------------------------------------------*/
@@ -91,28 +91,16 @@ DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber (0..) */
)
{
- switch (pdrv) {
- case PD_FLASH :
- // flash is ready
- return 0;
-
-#if MICROPY_HW_HAS_SDCARD
- case PD_SDCARD:
- // TODO return STA_PROTECT if SD card is read only
- return 0;
-#endif
-
- case PD_USER:
- if (MP_STATE_PORT(fs_user_mount) == NULL) {
- return STA_NODISK;
- }
- if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) {
- return STA_PROTECT;
- }
- return 0;
+ fs_user_mount_t *vfs = disk_get_device(pdrv);
+ if (vfs == NULL) {
+ return STA_NOINIT;
}
- return STA_NOINIT;
+ if (vfs->writeblocks[0] == MP_OBJ_NULL) {
+ return STA_PROTECT;
+ } else {
+ return 0;
+ }
}
/*-----------------------------------------------------------------------*/
@@ -126,37 +114,24 @@ DRESULT disk_read (
UINT count /* Number of sectors to read (1..128) */
)
{
- switch (pdrv) {
-#if MICROPY_HW_HAS_FLASH
- case PD_FLASH:
- for (int i = 0; i < count; i++) {
- if (!storage_read_block(buff + i * FLASH_BLOCK_SIZE, sector + i)) {
- return RES_ERROR;
- }
- }
- return RES_OK;
-#endif
-
-#if MICROPY_HW_HAS_SDCARD
- case PD_SDCARD:
- if (sdcard_read_blocks(buff, sector, count) != 0) {
- return RES_ERROR;
- }
- return RES_OK;
-#endif
+ fs_user_mount_t *vfs = disk_get_device(pdrv);
+ if (vfs == NULL) {
+ return RES_PARERR;
+ }
- case PD_USER:
- if (MP_STATE_PORT(fs_user_mount) == NULL) {
- // nothing mounted
- return RES_ERROR;
- }
- MP_STATE_PORT(fs_user_mount)->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
- MP_STATE_PORT(fs_user_mount)->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
- mp_call_method_n_kw(2, 0, MP_STATE_PORT(fs_user_mount)->readblocks);
- return RES_OK;
+ if (vfs->flags & FSUSER_NATIVE) {
+ mp_uint_t (*f)(uint8_t*, uint32_t, uint32_t) = (void*)vfs->readblocks[2];
+ if (f(buff, sector, count) != 0) {
+ return RES_ERROR;
+ }
+ } else {
+ vfs->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
+ vfs->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
+ mp_call_method_n_kw(2, 0, vfs->readblocks);
+ // TODO handle error return
}
- return RES_PARERR;
+ return RES_OK;
}
/*-----------------------------------------------------------------------*/
@@ -171,41 +146,29 @@ DRESULT disk_write (
UINT count /* Number of sectors to write (1..128) */
)
{
- switch (pdrv) {
-#if MICROPY_HW_HAS_FLASH
- case PD_FLASH:
- for (int i = 0; i < count; i++) {
- if (!storage_write_block(buff + i * FLASH_BLOCK_SIZE, sector + i)) {
- return RES_ERROR;
- }
- }
- return RES_OK;
-#endif
+ fs_user_mount_t *vfs = disk_get_device(pdrv);
+ if (vfs == NULL) {
+ return RES_PARERR;
+ }
-#if MICROPY_HW_HAS_SDCARD
- case PD_SDCARD:
- if (sdcard_write_blocks(buff, sector, count) != 0) {
- return RES_ERROR;
- }
- return RES_OK;
-#endif
+ if (vfs->writeblocks[0] == MP_OBJ_NULL) {
+ // read-only block device
+ return RES_WRPRT;
+ }
- case PD_USER:
- if (MP_STATE_PORT(fs_user_mount) == NULL) {
- // nothing mounted
- return RES_ERROR;
- }
- if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) {
- // read-only block device
- return RES_ERROR;
- }
- MP_STATE_PORT(fs_user_mount)->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
- MP_STATE_PORT(fs_user_mount)->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void*)buff);
- mp_call_method_n_kw(2, 0, MP_STATE_PORT(fs_user_mount)->writeblocks);
- return RES_OK;
+ if (vfs->flags & FSUSER_NATIVE) {
+ mp_uint_t (*f)(const uint8_t*, uint32_t, uint32_t) = (void*)vfs->writeblocks[2];
+ if (f(buff, sector, count) != 0) {
+ return RES_ERROR;
+ }
+ } else {
+ vfs->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
+ vfs->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void*)buff);
+ mp_call_method_n_kw(2, 0, vfs->writeblocks);
+ // TODO handle error return
}
- return RES_PARERR;
+ return RES_OK;
}
#endif
@@ -221,100 +184,69 @@ DRESULT disk_ioctl (
void *buff /* Buffer to send/receive control data */
)
{
- switch (pdrv) {
-#if MICROPY_HW_HAS_FLASH
- case PD_FLASH:
- switch (cmd) {
- case CTRL_SYNC:
- storage_flush();
- return RES_OK;
-
- case GET_BLOCK_SIZE:
- *((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size
- return RES_OK;
- }
- break;
-#endif
+ fs_user_mount_t *vfs = disk_get_device(pdrv);
+ if (vfs == NULL) {
+ return RES_PARERR;
+ }
-#if MICROPY_HW_HAS_SDCARD
- case PD_SDCARD:
- switch (cmd) {
- case CTRL_SYNC:
- return RES_OK;
+ if (vfs->flags & FSUSER_HAVE_IOCTL) {
+ // new protocol with ioctl
+ switch (cmd) {
+ case CTRL_SYNC:
+ vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SYNC);
+ vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
+ mp_call_method_n_kw(2, 0, vfs->u.ioctl);
+ return RES_OK;
+
+ case GET_SECTOR_COUNT: {
+ vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SEC_COUNT);
+ vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
+ mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl);
+ *((DWORD*)buff) = mp_obj_get_int(ret);
+ return RES_OK;
+ }
+
+ case GET_SECTOR_SIZE: {
+ vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SEC_SIZE);
+ vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
+ mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl);
+ *((WORD*)buff) = mp_obj_get_int(ret);
+ return RES_OK;
+ }
+
+ case GET_BLOCK_SIZE:
+ *((DWORD*)buff) = 1; // erase block size in units of sector size
+ return RES_OK;
+
+ default:
+ return RES_PARERR;
+ }
+ } else {
+ // old protocol with sync and count
+ switch (cmd) {
+ case CTRL_SYNC:
+ if (vfs->u.old.sync[0] != MP_OBJ_NULL) {
+ mp_call_method_n_kw(0, 0, vfs->u.old.sync);
+ }
+ return RES_OK;
- case GET_BLOCK_SIZE:
- *((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size
- return RES_OK;
+ case GET_SECTOR_COUNT: {
+ mp_obj_t ret = mp_call_method_n_kw(0, 0, vfs->u.old.count);
+ *((DWORD*)buff) = mp_obj_get_int(ret);
+ return RES_OK;
}
- break;
-#endif
- case PD_USER: {
- fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount);
- if (vfs == NULL) {
- // nothing mounted
- return RES_ERROR;
- }
- if (vfs->u.old.count[1] == MP_OBJ_SENTINEL) {
- // new protocol with ioctl
- switch (cmd) {
- case CTRL_SYNC:
- vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SYNC);
- vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
- mp_call_method_n_kw(2, 0, vfs->u.ioctl);
- vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol
- return RES_OK;
-
- case GET_SECTOR_COUNT: {
- vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SEC_COUNT);
- vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
- mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl);
- *((DWORD*)buff) = mp_obj_get_int(ret);
- vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol
- return RES_OK;
- }
-
- case GET_SECTOR_SIZE: {
- vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(BP_IOCTL_SEC_SIZE);
- vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
- mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl);
- *((WORD*)buff) = mp_obj_get_int(ret);
- vfs->u.ioctl[3] = MP_OBJ_SENTINEL; // indicate new protocol
- return RES_OK;
- }
-
- case GET_BLOCK_SIZE:
- *((DWORD*)buff) = 1; // erase block size in units of sector size
- return RES_OK;
- }
- } else {
- // old protocol with sync and count
- switch (cmd) {
- case CTRL_SYNC:
- if (vfs->u.old.sync[0] != MP_OBJ_NULL) {
- mp_call_method_n_kw(0, 0, vfs->u.old.sync);
- }
- return RES_OK;
-
- case GET_SECTOR_COUNT: {
- mp_obj_t ret = mp_call_method_n_kw(0, 0, vfs->u.old.count);
- *((DWORD*)buff) = mp_obj_get_int(ret);
- return RES_OK;
- }
-
- case GET_SECTOR_SIZE:
- *((WORD*)buff) = 512; // old protocol had fixed sector size
- return RES_OK;
-
- case GET_BLOCK_SIZE:
- *((DWORD*)buff) = 1; // erase block size in units of sector size
- return RES_OK;
- }
- }
- break;
+ case GET_SECTOR_SIZE:
+ *((WORD*)buff) = 512; // old protocol had fixed sector size
+ return RES_OK;
+
+ case GET_BLOCK_SIZE:
+ *((DWORD*)buff) = 1; // erase block size in units of sector size
+ return RES_OK;
+
+ default:
+ return RES_PARERR;
}
}
-
- return RES_PARERR;
}
#endif
diff --git a/stmhal/fatfs_port.c b/stmhal/fatfs_port.c
index a1435eaa3f..421ceddbaf 100644
--- a/stmhal/fatfs_port.c
+++ b/stmhal/fatfs_port.c
@@ -30,10 +30,11 @@
#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
#include "rtc.h"
-const PARTITION VolToPart[] = {
+const PARTITION VolToPart[MICROPY_FATFS_VOLUMES] = {
{0, 1}, // Logical drive 0 ==> Physical drive 0, 1st partition
{1, 0}, // Logical drive 1 ==> Physical drive 1 (auto detection)
{2, 0}, // Logical drive 2 ==> Physical drive 2 (auto detection)
+ {3, 0}, // Logical drive 3 ==> Physical drive 3 (auto detection)
/*
{0, 2}, // Logical drive 2 ==> Physical drive 0, 2nd partition
{0, 3}, // Logical drive 3 ==> Physical drive 0, 3rd partition
diff --git a/stmhal/ffconf.c b/stmhal/ffconf.c
index 74336310a7..6cd140f227 100644
--- a/stmhal/ffconf.c
+++ b/stmhal/ffconf.c
@@ -60,26 +60,18 @@ int ff_get_ldnumber (const TCHAR **path) {
#endif
}
- if (check_path(path, "/flash", 6)) {
- return PD_FLASH;
- } else if (check_path(path, "/sd", 3)) {
- return PD_SDCARD;
- } else if (MP_STATE_PORT(fs_user_mount) != NULL && check_path(path, MP_STATE_PORT(fs_user_mount)->str, MP_STATE_PORT(fs_user_mount)->len)) {
- return PD_USER;
- } else {
- return -1;
+ for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
+ fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
+ if (vfs != NULL && check_path(path, vfs->str, vfs->len)) {
+ return i;
+ }
}
+
+ return -1;
}
void ff_get_volname(BYTE vol, TCHAR **dest) {
- if (vol == PD_FLASH) {
- memcpy(*dest, "/flash", 6);
- *dest += 6;
- } else if (vol == PD_SDCARD) {
- memcpy(*dest, "/sd", 3);
- *dest += 3;
- } else {
- memcpy(*dest, MP_STATE_PORT(fs_user_mount)->str, MP_STATE_PORT(fs_user_mount)->len);
- *dest += MP_STATE_PORT(fs_user_mount)->len;
- }
+ fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[vol];
+ memcpy(*dest, vfs->str, vfs->len);
+ *dest += vfs->len;
}
diff --git a/stmhal/main.c b/stmhal/main.c
index 882de6e1a4..02dcc76174 100644
--- a/stmhal/main.c
+++ b/stmhal/main.c
@@ -38,6 +38,7 @@
#include "lib/utils/pyexec.h"
#include "lib/fatfs/ff.h"
+#include "extmod/fsusermount.h"
#include "systick.h"
#include "pendsv.h"
@@ -64,10 +65,7 @@
void SystemClock_Config(void);
-static FATFS fatfs0;
-#if MICROPY_HW_HAS_SDCARD
-static FATFS fatfs1;
-#endif
+fs_user_mount_t fs_user_mount_flash;
void flash_error(int n) {
for (int i = 0; i < n; i++) {
@@ -169,8 +167,18 @@ static const char fresh_readme_txt[] =
// we don't make this function static because it needs a lot of stack and we
// want it to be executed without using stack within main() function
void init_flash_fs(uint reset_mode) {
+ // init the vfs object
+ fs_user_mount_t *vfs = &fs_user_mount_flash;
+ vfs->str = "/flash";
+ vfs->len = 6;
+ vfs->flags = 0;
+ pyb_flash_init_vfs(vfs);
+
+ // put the flash device in slot 0 (it will be unused at this point)
+ MP_STATE_PORT(fs_user_mount)[0] = vfs;
+
// try to mount the flash
- FRESULT res = f_mount(&fatfs0, "/flash", 1);
+ FRESULT res = f_mount(&vfs->fatfs, vfs->str, 1);
if (reset_mode == 3 || res == FR_NO_FILESYSTEM) {
// no filesystem, or asked to reset it, so create a fresh one
@@ -183,7 +191,9 @@ void init_flash_fs(uint reset_mode) {
if (res == FR_OK) {
// success creating fresh LFS
} else {
- __fatal_error("could not create LFS");
+ printf("PYB: can't create flash filesystem\n");
+ MP_STATE_PORT(fs_user_mount)[0] = NULL;
+ return;
}
// set label
@@ -213,7 +223,9 @@ void init_flash_fs(uint reset_mode) {
} else if (res == FR_OK) {
// mount sucessful
} else {
- __fatal_error("could not access LFS");
+ printf("PYB: can't mount flash\n");
+ MP_STATE_PORT(fs_user_mount)[0] = NULL;
+ return;
}
// The current directory is used as the boot up directory.
@@ -448,6 +460,9 @@ soft_reset:
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib));
mp_obj_list_init(mp_sys_argv, 0);
+ // zero out the pointers to the mounted devices
+ memset(MP_STATE_PORT(fs_user_mount), 0, sizeof(MP_STATE_PORT(fs_user_mount)));
+
// Initialise low-level sub-systems. Here we need to very basic things like
// zeroing out memory and resetting any of the sub-systems. Following this
// we can run Python scripts (eg boot.py), but anything that is configurable
@@ -493,9 +508,24 @@ soft_reset:
#if MICROPY_HW_HAS_SDCARD
// if an SD card is present then mount it on /sd/
if (sdcard_is_present()) {
- FRESULT res = f_mount(&fatfs1, "/sd", 1);
+ // create vfs object
+ fs_user_mount_t *vfs = m_new_obj_maybe(fs_user_mount_t);
+ if (vfs == NULL) {
+ goto no_mem_for_sd;
+ }
+ vfs->str = "/sd";
+ vfs->len = 3;
+ vfs->flags = FSUSER_FREE_OBJ;
+ sdcard_init_vfs(vfs);
+
+ // put the sd device in slot 1 (it will be unused at this point)
+ MP_STATE_PORT(fs_user_mount)[1] = vfs;
+
+ FRESULT res = f_mount(&vfs->fatfs, vfs->str, 1);
if (res != FR_OK) {
- printf("[SD] could not mount SD card\n");
+ printf("PYB: can't mount SD card\n");
+ MP_STATE_PORT(fs_user_mount)[1] = NULL;
+ m_del_obj(fs_user_mount_t, vfs);
} else {
// TODO these should go before the /flash entries in the path
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
@@ -517,6 +547,7 @@ soft_reset:
f_chdrive("/sd");
}
}
+ no_mem_for_sd:;
}
#endif
diff --git a/stmhal/moduos.c b/stmhal/moduos.c
index cb2a73c116..293fbabafc 100644
--- a/stmhal/moduos.c
+++ b/stmhal/moduos.c
@@ -58,15 +58,6 @@
static char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */
#endif
-STATIC bool sd_in_root(void) {
-#if MICROPY_HW_HAS_SDCARD
- // TODO this is not the correct logic to check for /sd
- return sdcard_is_present();
-#else
- return false;
-#endif
-}
-
STATIC const qstr os_uname_info_fields[] = {
MP_QSTR_sysname, MP_QSTR_nodename,
MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
@@ -144,12 +135,11 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
// "hack" to list root directory
if (path[0] == '/' && path[1] == '\0') {
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
- mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_flash));
- if (sd_in_root()) {
- mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_sd));
- }
- if (MP_STATE_PORT(fs_user_mount) != NULL) {
- mp_obj_list_append(dir_list, mp_obj_new_str(MP_STATE_PORT(fs_user_mount)->str + 1, MP_STATE_PORT(fs_user_mount)->len - 1, false));
+ for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
+ fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
+ if (vfs != NULL) {
+ mp_obj_list_append(dir_list, mp_obj_new_str(vfs->str + 1, vfs->len - 1, false));
+ }
}
return dir_list;
}
@@ -298,21 +288,32 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
#endif
FRESULT res;
- if (path_equal(path, "/") || path_equal(path, "/flash") || path_equal(path, "/sd")) {
- // stat built-in directory
- if (path[1] == 's' && !sd_in_root()) {
- // no /sd directory
- res = FR_NO_PATH;
- goto error;
- }
+ if (path_equal(path, "/")) {
+ // stat root directory
fno.fsize = 0;
fno.fdate = 0;
fno.ftime = 0;
fno.fattrib = AM_DIR;
} else {
- res = f_stat(path, &fno);
+ res = FR_NO_PATH;
+ for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
+ fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
+ if (vfs != NULL && path_equal(path, vfs->str)) {
+ // stat mounted device directory
+ fno.fsize = 0;
+ fno.fdate = 0;
+ fno.ftime = 0;
+ fno.fattrib = AM_DIR;
+ res = FR_OK;
+ }
+ }
+ if (res == FR_NO_PATH) {
+ // stat normal file
+ res = f_stat(path, &fno);
+ }
if (res != FR_OK) {
- goto error;
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError,
+ MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
}
}
@@ -343,9 +344,6 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
t->items[9] = MP_OBJ_NEW_SMALL_INT(seconds); // st_ctime
return t;
-
-error:
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h
index cea8a3ecb4..8d12397361 100644
--- a/stmhal/mpconfigport.h
+++ b/stmhal/mpconfigport.h
@@ -53,7 +53,7 @@
#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
#define MICROPY_FATFS_USE_LABEL (1)
#define MICROPY_FATFS_RPATH (2)
-#define MICROPY_FATFS_VOLUMES (3)
+#define MICROPY_FATFS_VOLUMES (4)
#define MICROPY_FATFS_MULTI_PARTITION (1)
#define MICROPY_FSUSERMOUNT (1)
@@ -183,8 +183,8 @@ extern const struct _mp_obj_module_t mp_module_network;
/* pointers to all CAN objects (if they have been created) */ \
struct _pyb_can_obj_t *pyb_can_obj_all[2]; \
\
- /* for user-mountable block device */ \
- struct _fs_user_mount_t *fs_user_mount; \
+ /* for user-mountable block device (max fixed at compile time) */ \
+ struct _fs_user_mount_t *fs_user_mount[MICROPY_FATFS_VOLUMES]; \
\
/* list of registered NICs */ \
mp_obj_list_t mod_network_nic_list; \
diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c
index fb480bbec8..ae96de953f 100644
--- a/stmhal/sdcard.c
+++ b/stmhal/sdcard.c
@@ -424,4 +424,16 @@ const mp_obj_type_t pyb_sdcard_type = {
.locals_dict = (mp_obj_t)&pyb_sdcard_locals_dict,
};
+void sdcard_init_vfs(fs_user_mount_t *vfs) {
+ vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
+ vfs->readblocks[0] = (mp_obj_t)&pyb_sdcard_readblocks_obj;
+ vfs->readblocks[1] = (mp_obj_t)&pyb_sdcard_obj;
+ vfs->readblocks[2] = (mp_obj_t)sdcard_read_blocks; // native version
+ vfs->writeblocks[0] = (mp_obj_t)&pyb_sdcard_writeblocks_obj;
+ vfs->writeblocks[1] = (mp_obj_t)&pyb_sdcard_obj;
+ vfs->writeblocks[2] = (mp_obj_t)sdcard_write_blocks; // native version
+ vfs->u.ioctl[0] = (mp_obj_t)&pyb_sdcard_ioctl_obj;
+ vfs->u.ioctl[1] = (mp_obj_t)&pyb_sdcard_obj;
+}
+
#endif // MICROPY_HW_HAS_SDCARD
diff --git a/stmhal/sdcard.h b/stmhal/sdcard.h
index 06ca5ef1b3..ccc24927e5 100644
--- a/stmhal/sdcard.h
+++ b/stmhal/sdcard.h
@@ -39,3 +39,6 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n
extern const struct _mp_obj_type_t pyb_sdcard_type;
extern const struct _mp_obj_base_t pyb_sdcard_obj;
+
+struct _fs_user_mount_t;
+void sdcard_init_vfs(struct _fs_user_mount_t *vfs);
diff --git a/stmhal/storage.c b/stmhal/storage.c
index 7bd55a2b20..f6075c43c4 100644
--- a/stmhal/storage.c
+++ b/stmhal/storage.c
@@ -387,3 +387,15 @@ const mp_obj_type_t pyb_flash_type = {
.make_new = pyb_flash_make_new,
.locals_dict = (mp_obj_t)&pyb_flash_locals_dict,
};
+
+void pyb_flash_init_vfs(fs_user_mount_t *vfs) {
+ vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
+ vfs->readblocks[0] = (mp_obj_t)&pyb_flash_readblocks_obj;
+ vfs->readblocks[1] = (mp_obj_t)&pyb_flash_obj;
+ vfs->readblocks[2] = (mp_obj_t)storage_read_blocks; // native version
+ vfs->writeblocks[0] = (mp_obj_t)&pyb_flash_writeblocks_obj;
+ vfs->writeblocks[1] = (mp_obj_t)&pyb_flash_obj;
+ vfs->writeblocks[2] = (mp_obj_t)storage_write_blocks; // native version
+ vfs->u.ioctl[0] = (mp_obj_t)&pyb_flash_ioctl_obj;
+ vfs->u.ioctl[1] = (mp_obj_t)&pyb_flash_obj;
+}
diff --git a/stmhal/storage.h b/stmhal/storage.h
index 30aa483095..4d3de77eda 100644
--- a/stmhal/storage.h
+++ b/stmhal/storage.h
@@ -42,3 +42,6 @@ mp_uint_t storage_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_bl
mp_uint_t storage_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
extern const struct _mp_obj_type_t pyb_flash_type;
+
+struct _fs_user_mount_t;
+void pyb_flash_init_vfs(struct _fs_user_mount_t *vfs);