summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--stmhal/Makefile8
-rw-r--r--stmhal/builtin_open.c30
-rw-r--r--stmhal/fatfs_port.c15
-rw-r--r--stmhal/import.c35
-rw-r--r--stmhal/main.c99
-rw-r--r--stmhal/modmachine.c20
-rw-r--r--stmhal/modpyb.c8
-rw-r--r--stmhal/moduos.c294
-rw-r--r--stmhal/mpconfigport.h16
-rw-r--r--stmhal/sdcard.c5
-rw-r--r--stmhal/storage.c5
11 files changed, 114 insertions, 421 deletions
diff --git a/stmhal/Makefile b/stmhal/Makefile
index 87236068ba..3431c31050 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -26,7 +26,7 @@ CMSIS_DIR=cmsis
HAL_DIR=hal/$(MCU_SERIES)
USBDEV_DIR=usbdev
#USBHOST_DIR=usbhost
-FATFS_DIR=lib/fatfs
+FATFS_DIR=lib/oofatfs
DFU=../tools/dfu.py
# may need to prefix dfu-util with sudo
USE_PYDFU ?= 1
@@ -109,8 +109,8 @@ SRC_LIB = $(addprefix lib/,\
libm/sf_erf.c \
libm/wf_lgamma.c \
libm/wf_tgamma.c \
- fatfs/ff.c \
- fatfs/option/ccsbcs.c \
+ oofatfs/ff.c \
+ oofatfs/option/unicode.c \
mp-readline/readline.c \
netutils/netutils.c \
timeutils/timeutils.c \
@@ -159,14 +159,12 @@ SRC_C = \
modutime.c \
modusocket.c \
modnetwork.c \
- import.c \
extint.c \
usrsw.c \
rng.c \
rtc.c \
flash.c \
storage.c \
- builtin_open.c \
sdcard.c \
fatfs_port.c \
lcd.c \
diff --git a/stmhal/builtin_open.c b/stmhal/builtin_open.c
deleted file mode 100644
index 56b98ea61c..0000000000
--- a/stmhal/builtin_open.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2013, 2014 Damien P. George
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "py/runtime.h"
-#include "extmod/vfs_fat.h"
-
-MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, fatfs_builtin_open);
diff --git a/stmhal/fatfs_port.c b/stmhal/fatfs_port.c
index 421ceddbaf..17ec3f7266 100644
--- a/stmhal/fatfs_port.c
+++ b/stmhal/fatfs_port.c
@@ -24,23 +24,10 @@
* THE SOFTWARE.
*/
-#include "py/mphal.h"
#include "py/runtime.h"
-#include "lib/fatfs/ff.h" /* FatFs lower layer API */
-#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
+#include "lib/oofatfs/ff.h"
#include "rtc.h"
-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
- */
-};
-
DWORD get_fattime(void) {
rtc_init_finalise();
RTC_TimeTypeDef time;
diff --git a/stmhal/import.c b/stmhal/import.c
deleted file mode 100644
index 2bc282e7b7..0000000000
--- a/stmhal/import.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is part of the Micro Python project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2013, 2014 Damien P. George
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <stdio.h>
-
-#include "py/lexer.h"
-#include "lib/fatfs/ff.h"
-#include "extmod/vfs_fat.h"
-
-mp_import_stat_t mp_import_stat(const char *path) {
- return fat_vfs_import_stat(NULL, path);
-}
diff --git a/stmhal/main.c b/stmhal/main.c
index 78afe54ef6..1918658b7b 100644
--- a/stmhal/main.c
+++ b/stmhal/main.c
@@ -37,7 +37,8 @@
#include "py/mphal.h"
#include "lib/utils/pyexec.h"
-#include "lib/fatfs/ff.h"
+#include "lib/oofatfs/ff.h"
+#include "extmod/vfs.h"
#include "extmod/fsusermount.h"
#include "systick.h"
@@ -67,6 +68,7 @@
void SystemClock_Config(void);
fs_user_mount_t fs_user_mount_flash;
+mp_vfs_mount_t mp_vfs_mount_flash;
void flash_error(int n) {
for (int i = 0; i < n; i++) {
@@ -168,17 +170,14 @@ static const char fresh_readme_txt[] =
// avoid inlining to avoid stack usage within main()
MP_NOINLINE STATIC 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;
+ fs_user_mount_t *vfs_fat = &fs_user_mount_flash;
+ vfs_fat->str = NULL;
+ vfs_fat->len = 0;
+ vfs_fat->flags = 0;
+ pyb_flash_init_vfs(vfs_fat);
// try to mount the flash
- FRESULT res = f_mount(&vfs->fatfs, vfs->str, 1);
+ FRESULT res = f_mount(&vfs_fat->fatfs);
if (reset_mode == 3 || res == FR_NO_FILESYSTEM) {
// no filesystem, or asked to reset it, so create a fresh one
@@ -187,33 +186,33 @@ MP_NOINLINE STATIC void init_flash_fs(uint reset_mode) {
led_state(PYB_LED_R2, 1);
uint32_t start_tick = HAL_GetTick();
- res = f_mkfs("/flash", 0, 0);
+ uint8_t working_buf[_MAX_SS];
+ res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf));
if (res == FR_OK) {
// success creating fresh LFS
} else {
printf("PYB: can't create flash filesystem\n");
- MP_STATE_PORT(fs_user_mount)[0] = NULL;
return;
}
// set label
- f_setlabel("/flash/pybflash");
+ f_setlabel(&vfs_fat->fatfs, "pybflash");
// create empty main.py
FIL fp;
- f_open(&fp, "/flash/main.py", FA_WRITE | FA_CREATE_ALWAYS);
+ f_open(&vfs_fat->fatfs, &fp, "/main.py", FA_WRITE | FA_CREATE_ALWAYS);
UINT n;
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
// TODO check we could write n bytes
f_close(&fp);
// create .inf driver file
- f_open(&fp, "/flash/pybcdc.inf", FA_WRITE | FA_CREATE_ALWAYS);
+ f_open(&vfs_fat->fatfs, &fp, "/pybcdc.inf", FA_WRITE | FA_CREATE_ALWAYS);
f_write(&fp, fresh_pybcdc_inf, sizeof(fresh_pybcdc_inf) - 1 /* don't count null terminator */, &n);
f_close(&fp);
// create readme file
- f_open(&fp, "/flash/README.txt", FA_WRITE | FA_CREATE_ALWAYS);
+ f_open(&vfs_fat->fatfs, &fp, "/README.txt", FA_WRITE | FA_CREATE_ALWAYS);
f_write(&fp, fresh_readme_txt, sizeof(fresh_readme_txt) - 1 /* don't count null terminator */, &n);
f_close(&fp);
@@ -224,30 +223,25 @@ MP_NOINLINE STATIC void init_flash_fs(uint reset_mode) {
// mount sucessful
} else {
printf("PYB: can't mount flash\n");
- MP_STATE_PORT(fs_user_mount)[0] = NULL;
return;
}
+ // mount the flash device (there should be no other devices mounted at this point)
+ mp_vfs_mount_t *vfs = &mp_vfs_mount_flash;
+ vfs->str = "/flash";
+ vfs->len = 6;
+ vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
+ vfs->next = NULL;
+ MP_STATE_VM(vfs_mount_table) = vfs;
+
// The current directory is used as the boot up directory.
// It is set to the internal flash filesystem by default.
- f_chdrive("/flash");
+ MP_STATE_PORT(vfs_cur) = vfs;
// Make sure we have a /flash/boot.py. Create it if needed.
FILINFO fno;
-#if _USE_LFN
- fno.lfname = NULL;
- fno.lfsize = 0;
-#endif
- res = f_stat("/flash/boot.py", &fno);
- if (res == FR_OK) {
- if (fno.fattrib & AM_DIR) {
- // exists as a directory
- // TODO handle this case
- // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation
- } else {
- // exists as a file, good!
- }
- } else {
+ res = f_stat(&vfs_fat->fatfs, "/boot.py", &fno);
+ if (res != FR_OK) {
// doesn't exist, create fresh file
// LED on to indicate creation of boot.py
@@ -255,7 +249,7 @@ MP_NOINLINE STATIC void init_flash_fs(uint reset_mode) {
uint32_t start_tick = HAL_GetTick();
FIL fp;
- f_open(&fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
+ f_open(&vfs_fat->fatfs, &fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
UINT n;
f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
// TODO check we could write n bytes
@@ -485,24 +479,29 @@ soft_reset:
// if an SD card is present then mount it on /sd/
if (sdcard_is_present()) {
// create vfs object
- fs_user_mount_t *vfs = m_new_obj_maybe(fs_user_mount_t);
- if (vfs == NULL) {
+ fs_user_mount_t *vfs_fat = m_new_obj_maybe(fs_user_mount_t);
+ mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
+ if (vfs == NULL || vfs_fat == 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;
+ vfs_fat->str = NULL;
+ vfs_fat->len = 0;
+ vfs_fat->flags = FSUSER_FREE_OBJ;
+ sdcard_init_vfs(vfs_fat);
- FRESULT res = f_mount(&vfs->fatfs, vfs->str, 1);
+ FRESULT res = f_mount(&vfs_fat->fatfs);
if (res != FR_OK) {
printf("PYB: can't mount SD card\n");
- MP_STATE_PORT(fs_user_mount)[1] = NULL;
- m_del_obj(fs_user_mount_t, vfs);
+ m_del_obj(fs_user_mount_t, vfs_fat);
+ m_del_obj(mp_vfs_mount_t, vfs);
} else {
+ // mount the sd device after the internal flash
+ vfs->str = "/sd";
+ vfs->len = 3;
+ vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
+ vfs->next = NULL;
+ MP_STATE_VM(vfs_mount_table)->next = vfs;
+
// 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));
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
@@ -520,7 +519,7 @@ soft_reset:
#endif
{
// use SD card as current directory
- f_chdrive("/sd");
+ MP_STATE_PORT(vfs_cur) = vfs;
}
}
no_mem_for_sd:;
@@ -534,8 +533,8 @@ soft_reset:
// TODO perhaps have pyb.reboot([bootpy]) function to soft-reboot and execute custom boot.py
if (reset_mode == 1 || reset_mode == 3) {
const char *boot_py = "boot.py";
- FRESULT res = f_stat(boot_py, NULL);
- if (res == FR_OK) {
+ mp_import_stat_t stat = mp_import_stat(boot_py);
+ if (stat == MP_IMPORT_STAT_FILE) {
int ret = pyexec_file(boot_py);
if (ret & PYEXEC_FORCED_EXIT) {
goto soft_reset_exit;
@@ -597,8 +596,8 @@ soft_reset:
} else {
main_py = mp_obj_str_get_str(MP_STATE_PORT(pyb_config_main));
}
- FRESULT res = f_stat(main_py, NULL);
- if (res == FR_OK) {
+ mp_import_stat_t stat = mp_import_stat(main_py);
+ if (stat == MP_IMPORT_STAT_FILE) {
int ret = pyexec_file(main_py);
if (ret & PYEXEC_FORCED_EXIT) {
goto soft_reset_exit;
diff --git a/stmhal/modmachine.c b/stmhal/modmachine.c
index 7a337adb69..aec8e29c51 100644
--- a/stmhal/modmachine.c
+++ b/stmhal/modmachine.c
@@ -25,6 +25,7 @@
*/
#include <stdio.h>
+#include <string.h>
#include "modmachine.h"
#include "py/gc.h"
@@ -34,8 +35,9 @@
#include "extmod/machine_pulse.h"
#include "extmod/machine_i2c.h"
#include "lib/utils/pyexec.h"
-#include "lib/fatfs/ff.h"
-#include "lib/fatfs/diskio.h"
+#include "lib/oofatfs/ff.h"
+#include "extmod/vfs.h"
+#include "extmod/fsusermount.h"
#include "gccollect.h"
#include "irq.h"
#include "rng.h"
@@ -144,10 +146,16 @@ STATIC mp_obj_t machine_info(mp_uint_t n_args, const mp_obj_t *args) {
// free space on flash
{
- DWORD nclst;
- FATFS *fatfs;
- f_getfree("/flash", &nclst, &fatfs);
- printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512));
+ for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
+ if (strncmp("/flash", vfs->str, vfs->len) == 0) {
+ // assumes that it's a FatFs filesystem
+ fs_user_mount_t *vfs_fat = MP_OBJ_TO_PTR(vfs->obj);
+ DWORD nclst;
+ f_getfree(&vfs_fat->fatfs, &nclst);
+ printf("LFS free: %u bytes\n", (uint)(nclst * vfs_fat->fatfs.csize * 512));
+ break;
+ }
+ }
}
if (n_args == 1) {
diff --git a/stmhal/modpyb.c b/stmhal/modpyb.c
index e602234fc6..53b4335e79 100644
--- a/stmhal/modpyb.c
+++ b/stmhal/modpyb.c
@@ -35,8 +35,8 @@
#include "py/gc.h"
#include "py/builtin.h"
#include "lib/utils/pyexec.h"
-#include "lib/fatfs/ff.h"
-#include "lib/fatfs/diskio.h"
+#include "lib/oofatfs/ff.h"
+#include "lib/oofatfs/diskio.h"
#include "gccollect.h"
#include "irq.h"
#include "systick.h"
@@ -61,7 +61,7 @@
#include "usb.h"
#include "portmodules.h"
#include "modmachine.h"
-#include "extmod/fsusermount.h"
+#include "extmod/vfs.h"
#include "extmod/utime_mphal.h"
/// \function millis()
@@ -166,7 +166,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&mp_utime_sleep_ms_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&mp_utime_sleep_us_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&mod_os_sync_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&fsuser_mount_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&mp_vfs_mount_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_Timer), (mp_obj_t)&pyb_timer_type },
diff --git a/stmhal/moduos.c b/stmhal/moduos.c
index 158e530ff4..976d7f089d 100644
--- a/stmhal/moduos.c
+++ b/stmhal/moduos.c
@@ -31,15 +31,14 @@
#include "py/runtime.h"
#include "py/objtuple.h"
#include "py/objstr.h"
+#include "lib/oofatfs/ff.h"
+#include "lib/oofatfs/diskio.h"
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
#include "genhdr/mpversion.h"
-#include "lib/fatfs/ff.h"
-#include "lib/fatfs/diskio.h"
#include "timeutils.h"
#include "rng.h"
#include "uart.h"
-#include "extmod/vfs_fat.h"
-#include "sdcard.h"
-#include "extmod/fsusermount.h"
#include "portmodules.h"
/// \module os - basic "operating system" services
@@ -80,263 +79,13 @@ STATIC mp_obj_t os_uname(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
-/// \function chdir(path)
-/// Change current directory.
-STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
- const char *path;
- path = mp_obj_str_get_str(path_in);
-
- FRESULT res = f_chdrive(path);
-
- if (res == FR_OK) {
- res = f_chdir(path);
- }
-
- if (res != FR_OK) {
- // TODO should be mp_type_FileNotFoundError
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
- }
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir);
-
-/// \function getcwd()
-/// Get the current directory.
-STATIC mp_obj_t os_getcwd(void) {
- char buf[MICROPY_ALLOC_PATH_MAX + 1];
- FRESULT res = f_getcwd(buf, sizeof buf);
-
- if (res != FR_OK) {
- mp_raise_OSError(fresult_to_errno_table[res]);
- }
-
- return mp_obj_new_str(buf, strlen(buf), false);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
-
-/// \function listdir([dir])
-/// With no argument, list the current directory. Otherwise list the given directory.
-STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
- bool is_str_type = true;
- const char *path;
- if (n_args == 1) {
- if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
- is_str_type = false;
- }
- path = mp_obj_str_get_str(args[0]);
- } else {
- path = "";
- }
-
- // "hack" to list root directory
- if (path[0] == '/' && path[1] == '\0') {
- mp_obj_t dir_list = mp_obj_new_list(0, NULL);
- 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;
- }
-
- return fat_vfs_listdir(path, is_str_type);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
-
-/// \function mkdir(path)
-/// Create a new directory.
-STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
- const char *path = mp_obj_str_get_str(path_o);
- FRESULT res = f_mkdir(path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- case FR_EXIST:
- // TODO should be FileExistsError
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path));
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
-
-/// \function remove(path)
-/// Remove a file.
-STATIC mp_obj_t os_remove(mp_obj_t path_o) {
- const char *path = mp_obj_str_get_str(path_o);
- // TODO check that path is actually a file before trying to unlink it
- FRESULT res = f_unlink(path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
-
-/// \function rename(old_path, new_path)
-/// Rename a file
-STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
- const char *old_path = mp_obj_str_get_str(path_in);
- const char *new_path = mp_obj_str_get_str(path_out);
- FRESULT res = f_rename(old_path, new_path);
- if (res == FR_EXIST) {
- // if new_path exists then try removing it
- res = f_unlink(new_path);
- if (res == FR_OK) {
- // try to rename again
- res = f_rename(old_path, new_path);
- }
- }
- switch (res) {
- case FR_OK:
- return mp_const_none;
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error renaming file '%s' to '%s'", old_path, new_path));
- }
-
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
-
-/// \function rmdir(path)
-/// Remove a directory.
-STATIC mp_obj_t os_rmdir(mp_obj_t path_o) {
- const char *path = mp_obj_str_get_str(path_o);
- // TODO check that path is actually a directory before trying to unlink it
- FRESULT res = f_unlink(path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
-
-// Checks for path equality, ignoring trailing slashes:
-// path_equal(/, /) -> true
-// path_equal(/flash//, /flash) -> true
-// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
-STATIC bool path_equal(const char *path, const char *path_canonical) {
- for (; *path_canonical != '\0' && *path == *path_canonical; ++path, ++path_canonical) {
- }
- if (*path_canonical != '\0') {
- return false;
- }
- for (; *path == '/'; ++path) {
- }
- return *path == '\0';
-}
-
-/// \function stat(path)
-/// Get the status of a file or directory.
-STATIC mp_obj_t os_stat(mp_obj_t path_in) {
- const char *path = mp_obj_str_get_str(path_in);
-
- FILINFO fno;
-#if _USE_LFN
- fno.lfname = NULL;
- fno.lfsize = 0;
-#endif
-
- FRESULT res;
- if (path_equal(path, "/")) {
- // stat root directory
- fno.fsize = 0;
- fno.fdate = 0;
- fno.ftime = 0;
- fno.fattrib = AM_DIR;
- } else {
- 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) {
- mp_raise_OSError(fresult_to_errno_table[res]);
- }
- }
-
- mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
- mp_int_t mode = 0;
- if (fno.fattrib & AM_DIR) {
- mode |= 0x4000; // stat.S_IFDIR
- } else {
- mode |= 0x8000; // stat.S_IFREG
- }
- mp_int_t seconds = timeutils_seconds_since_2000(
- 1980 + ((fno.fdate >> 9) & 0x7f),
- (fno.fdate >> 5) & 0x0f,
- fno.fdate & 0x1f,
- (fno.ftime >> 11) & 0x1f,
- (fno.ftime >> 5) & 0x3f,
- 2 * (fno.ftime & 0x1f)
- );
- t->items[0] = MP_OBJ_NEW_SMALL_INT(mode); // st_mode
- t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
- t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev
- t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink
- t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
- t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
- t->items[6] = MP_OBJ_NEW_SMALL_INT(fno.fsize); // st_size
- t->items[7] = MP_OBJ_NEW_SMALL_INT(seconds); // st_atime
- t->items[8] = MP_OBJ_NEW_SMALL_INT(seconds); // st_mtime
- t->items[9] = MP_OBJ_NEW_SMALL_INT(seconds); // st_ctime
-
- return t;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
-
-STATIC mp_obj_t os_statvfs(mp_obj_t path_in) {
- const char *path = mp_obj_str_get_str(path_in);
-
- DWORD nclst;
- FATFS *fatfs;
- FRESULT res = f_getfree(path, &nclst, &fatfs);
- if (res != FR_OK) {
- goto error;
- }
-
- mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
-
- t->items[0] = MP_OBJ_NEW_SMALL_INT(fatfs->csize * 512); // f_bsize - block size
- t->items[1] = t->items[0]; // f_frsize - fragment size
- t->items[2] = MP_OBJ_NEW_SMALL_INT((fatfs->n_fatent - 2) * fatfs->csize); // f_blocks - total number of blocks
- t->items[3] = MP_OBJ_NEW_SMALL_INT(nclst); // f_bfree - number of free blocks
- t->items[4] = t->items[3]; // f_bavail - free blocks avail to unpriviledged users
- t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // f_files - # inodes
- t->items[6] = MP_OBJ_NEW_SMALL_INT(0); // f_ffree - # free inodes
- t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // f_favail - # free inodes avail to unpriviledges users
- t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // f_flags
- t->items[9] = MP_OBJ_NEW_SMALL_INT(_MAX_LFN); // f_namemax
-
- return t;
-
-error:
- mp_raise_OSError(fresult_to_errno_table[res]);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_statvfs_obj, os_statvfs);
-
/// \function sync()
/// Sync all filesystems.
STATIC mp_obj_t os_sync(void) {
- disk_ioctl(0, CTRL_SYNC, NULL);
- disk_ioctl(1, CTRL_SYNC, NULL);
- disk_ioctl(2, CTRL_SYNC, NULL);
+ for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
+ // this assumes that vfs->obj is fs_user_mount_t with block device functions
+ disk_ioctl(MP_OBJ_TO_PTR(vfs->obj), CTRL_SYNC, NULL);
+ }
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(mod_os_sync_obj, os_sync);
@@ -384,16 +133,17 @@ STATIC const mp_map_elem_t os_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_uname), (mp_obj_t)&os_uname_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_rename),(mp_obj_t)&os_rename_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_statvfs), (mp_obj_t)&os_statvfs_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
+ { MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&mp_vfs_chdir_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&mp_vfs_chdir_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&mp_vfs_getcwd_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&mp_vfs_listdir_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&mp_vfs_mkdir_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&mp_vfs_remove_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_rename),(mp_obj_t)&mp_vfs_rename_obj},
+ { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&mp_vfs_rmdir_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&mp_vfs_stat_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_statvfs), (mp_obj_t)&mp_vfs_statvfs_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&mp_vfs_remove_obj }, // unlink aliases to remove
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&mod_os_sync_obj },
@@ -406,9 +156,9 @@ STATIC const mp_map_elem_t os_module_globals_table[] = {
// these are MicroPython extensions
{ MP_OBJ_NEW_QSTR(MP_QSTR_dupterm), (mp_obj_t)&mod_os_dupterm_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&fsuser_mount_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_umount), (mp_obj_t)&fsuser_umount_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&fsuser_mkfs_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&mp_vfs_mount_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_umount), (mp_obj_t)&mp_vfs_umount_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_VfsFat), (mp_obj_t)&mp_fat_vfs_type },
};
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h
index 80cc1014bd..53369a1827 100644
--- a/stmhal/mpconfigport.h
+++ b/stmhal/mpconfigport.h
@@ -52,7 +52,7 @@
#define MICROPY_OPT_MPZ_BITWISE (1)
// Python internal features
-#define MICROPY_READER_FATFS (1)
+#define MICROPY_READER_VFS (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_ENABLE_FINALISER (1)
#define MICROPY_STACK_CHECK (1)
@@ -69,6 +69,8 @@
#define MICROPY_MODULE_WEAK_LINKS (1)
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
#define MICROPY_USE_INTERNAL_ERRNO (1)
+#define MICROPY_VFS (1)
+#define MICROPY_VFS_FAT (1)
// control over Python builtins
#define MICROPY_PY_FUNCTION_ATTRS (1)
@@ -133,13 +135,21 @@
#endif
// fatfs configuration used in ffconf.h
+#define MICROPY_FATFS_OO (1)
#define MICROPY_FATFS_ENABLE_LFN (1)
#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 (4)
#define MICROPY_FATFS_MULTI_PARTITION (1)
-#define MICROPY_FSUSERMOUNT (1)
+
+// TODO these should be generic, not bound to fatfs
+#define mp_type_fileio fatfs_type_fileio
+#define mp_type_textio fatfs_type_textio
+
+// use vfs's functions for import stat and builtin open
+#define mp_import_stat mp_vfs_import_stat
+#define mp_builtin_open mp_vfs_open
+#define mp_builtin_open_obj mp_vfs_open_obj
// extra built in names to add to the global namespace
#define MICROPY_PORT_BUILTINS \
diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c
index a93b2b056d..52ede492bb 100644
--- a/stmhal/sdcard.c
+++ b/stmhal/sdcard.c
@@ -28,7 +28,8 @@
#include "py/nlr.h"
#include "py/runtime.h"
-#include "lib/fatfs/ff.h"
+#include "lib/oofatfs/ff.h"
+#include "extmod/vfs_fat.h"
#include "extmod/fsusermount.h"
#include "mphalport.h"
@@ -444,7 +445,9 @@ const mp_obj_type_t pyb_sdcard_type = {
};
void sdcard_init_vfs(fs_user_mount_t *vfs) {
+ vfs->base.type = &mp_fat_vfs_type;
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
+ vfs->fatfs.drv = vfs;
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
diff --git a/stmhal/storage.c b/stmhal/storage.c
index 60a7e9f480..6130d6fb8e 100644
--- a/stmhal/storage.c
+++ b/stmhal/storage.c
@@ -29,7 +29,8 @@
#include "py/obj.h"
#include "py/runtime.h"
-#include "lib/fatfs/ff.h"
+#include "lib/oofatfs/ff.h"
+#include "extmod/vfs_fat.h"
#include "extmod/fsusermount.h"
#include "systick.h"
@@ -504,7 +505,9 @@ const mp_obj_type_t pyb_flash_type = {
};
void pyb_flash_init_vfs(fs_user_mount_t *vfs) {
+ vfs->base.type = &mp_fat_vfs_type;
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
+ vfs->fatfs.drv = vfs;
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