summaryrefslogtreecommitdiff
path: root/stmhal/modos.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-07-31 23:44:04 +0100
committerDamien George <damien.p.george@gmail.com>2014-07-31 23:44:04 +0100
commit65dd7bc13d2083a7db5a974bf6480b1652a35c82 (patch)
treeaf18c5f8ad6c33a33d7a57e8d495b1890655f15b /stmhal/modos.c
parent5aac6aa445d343074b64bb7fa3ddc9184b0c65be (diff)
stmhal: Change 0:/ and 1:/ to /flash and /sd; add CWD support.
Some important changes to the way the file system is structured on the pyboard: 1. 0: and 1: drive names are now replaced with POSIX inspired directories, namely /flash and /sd. 2. Filesystem now supports the notion of a current working directory. Supports the standard Python way of manipulating it: os.chdir and os.getcwd. 3. On boot up, current directory is /flash if no SD inserted, else /sd if SD inserted. Then runs boot.py and main.py from the current dir. This is the same as the old behaviour, but is much more consistent and flexible (eg you can os.chdir in boot.py to change where main.py is run from). 4. sys.path (for import) is now set to '' (current dir), plus /flash and /flash/lib, and then /sd and /sd/lib if SD inserted. This, along with CWD, means that import now works properly. You can import a file from the current directory. 5. os.listdir is fixed to return just the basename, not the full path. See issue #537 for background and discussion.
Diffstat (limited to 'stmhal/modos.c')
-rw-r--r--stmhal/modos.c91
1 files changed, 71 insertions, 20 deletions
diff --git a/stmhal/modos.c b/stmhal/modos.c
index 35979ae97..67daf9250 100644
--- a/stmhal/modos.c
+++ b/stmhal/modos.c
@@ -38,22 +38,64 @@
#include "storage.h"
#include "ff.h"
#include "file.h"
+#include "sdcard.h"
#include "portmodules.h"
#if _USE_LFN
static char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */
#endif
+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);
+
+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) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(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);
+
STATIC mp_obj_t os_listdir(uint n_args, const mp_obj_t *args) {
- const mp_obj_type_t *local_str_type = &mp_type_str;
+ bool is_str_type = true;
const char *path;
if (n_args == 1) {
if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
- local_str_type = &mp_type_bytes;
+ is_str_type = false;
}
path = mp_obj_str_get_str(args[0]);
} else {
- path = "0:";
+ path = "";
+ }
+
+ // "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 (sdcard_is_present()) { // TODO this is not the correct logic to check for /sd
+ mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_sd));
+ }
+ return dir_list;
}
FRESULT res;
@@ -72,11 +114,6 @@ STATIC mp_obj_t os_listdir(uint n_args, const mp_obj_t *args) {
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
- uint path_len = strlen(path);
- if (path[path_len - 1] == '/') {
- path_len--;
- }
-
for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
@@ -89,20 +126,24 @@ STATIC mp_obj_t os_listdir(uint n_args, const mp_obj_t *args) {
char *fn = fno.fname;
#endif
- if (fno.fattrib & AM_DIR) { /* It is a directory */
- } else { /* It is a file. */
+ /*
+ if (fno.fattrib & AM_DIR) {
+ // dir
+ } else {
+ // file
}
+ */
// make a string object for this entry
- byte *data;
- uint fn_len = strlen(fn);
- mp_obj_t entry_o = mp_obj_str_builder_start(local_str_type, path_len + 1 + fn_len, &data);
- memcpy(data, path, path_len);
- data[path_len] = '/';
- memcpy(data + path_len + 1, fn, fn_len);
+ mp_obj_t entry_o;
+ if (is_str_type) {
+ entry_o = mp_obj_new_str(fn, strlen(fn), false);
+ } else {
+ entry_o = mp_obj_new_bytes((const byte*)fn, strlen(fn));
+ }
// add the entry to the list
- mp_obj_list_append(dir_list, mp_obj_str_builder_end(entry_o));
+ mp_obj_list_append(dir_list, entry_o);
}
f_closedir(&dir);
@@ -161,9 +202,17 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
fno.lfsize = 0;
#endif
- FRESULT res = f_stat(path, &fno);
- if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ if (path[0] == '/' && path[1] == '\0') {
+ // stat root directory
+ fno.fsize = 0;
+ fno.fdate = 0;
+ fno.ftime = 0;
+ fno.fattrib = AM_DIR;
+ } else {
+ FRESULT res = f_stat(path, &fno);
+ if (res != FR_OK) {
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ }
}
mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
@@ -216,6 +265,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
STATIC const mp_map_elem_t os_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_os) },
+ { 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 },