Skip to content

Commit 65dd7bc

Browse files
committed
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 adafruit#537 for background and discussion.
1 parent 5aac6aa commit 65dd7bc

9 files changed

Lines changed: 202 additions & 60 deletions

File tree

stmhal/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ SRC_C = \
104104
file.c \
105105
sdcard.c \
106106
diskio.c \
107+
ffconf.c \
107108
lcd.c \
108109
accel.c \
109110
servo.c \

stmhal/fatfs/src/ff.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@
106106
/ Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
107107
/---------------------------------------------------------------------------*/
108108

109+
#include <string.h>
110+
109111
#include "ff.h" /* Declarations of FatFs API */
110112
#include "diskio.h" /* Declarations of disk I/O functions */
111113

@@ -485,7 +487,7 @@ static
485487
WORD Fsid; /* File system mount ID */
486488

487489
#if _FS_RPATH && _VOLUMES >= 2
488-
static
490+
//static
489491
BYTE CurrVol; /* Current drive */
490492
#endif
491493

@@ -1992,6 +1994,8 @@ void get_fileinfo ( /* No return code */
19921994
/* Get logical drive number from path name */
19931995
/*-----------------------------------------------------------------------*/
19941996

1997+
/* now implemented by us for configurability of path names */
1998+
#if 0
19951999
static
19962000
int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */
19972001
const TCHAR** path /* Pointer to pointer to the path name */
@@ -2016,7 +2020,7 @@ int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */
20162020

20172021
return vol;
20182022
}
2019-
2023+
#endif
20202024

20212025

20222026

@@ -2131,7 +2135,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
21312135

21322136
/* Get logical drive number from the path name */
21332137
*rfs = 0;
2134-
vol = get_ldnumber(path);
2138+
vol = ff_get_ldnumber(path);
21352139
if (vol < 0) return FR_INVALID_DRIVE;
21362140

21372141
/* Check if the file system object is valid or not */
@@ -2326,7 +2330,7 @@ FRESULT f_mount (
23262330
FRESULT res;
23272331
const TCHAR *rp = path;
23282332

2329-
vol = get_ldnumber(&rp);
2333+
vol = ff_get_ldnumber(&rp);
23302334
if (vol < 0) return FR_INVALID_DRIVE;
23312335
cfs = FatFs[vol]; /* Pointer to fs object */
23322336

@@ -2813,7 +2817,7 @@ FRESULT f_chdrive (
28132817
int vol;
28142818

28152819

2816-
vol = get_ldnumber(&path);
2820+
vol = ff_get_ldnumber(&path);
28172821
if (vol < 0) return FR_INVALID_DRIVE;
28182822

28192823
CurrVol = (BYTE)vol;
@@ -2912,11 +2916,22 @@ FRESULT f_getcwd (
29122916
tp = buff;
29132917
if (res == FR_OK) {
29142918
#if _VOLUMES >= 2
2919+
#if 0
29152920
*tp++ = '0' + CurrVol; /* Put drive number */
29162921
*tp++ = ':';
2922+
#endif
2923+
if (CurrVol == 0) {
2924+
memcpy(tp, "/flash", 6);
2925+
tp += 6;
2926+
} else {
2927+
memcpy(tp, "/sd", 3);
2928+
tp += 3;
2929+
}
29172930
#endif
29182931
if (i == len) { /* Root-directory */
2932+
#if 0
29192933
*tp++ = '/';
2934+
#endif
29202935
} else { /* Sub-directroy */
29212936
do /* Add stacked path str */
29222937
*tp++ = buff[i++];
@@ -3937,7 +3952,7 @@ FRESULT f_mkfs (
39373952

39383953

39393954
/* Check mounted drive and clear work area */
3940-
vol = get_ldnumber(&path);
3955+
vol = ff_get_ldnumber(&path);
39413956
if (vol < 0) return FR_INVALID_DRIVE;
39423957
if (sfd > 1) return FR_INVALID_PARAMETER;
39433958
if (au & (au - 1)) return FR_INVALID_PARAMETER;

stmhal/fatfs/src/ff.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
288288
#endif
289289

290290

291+
/* Returns logical drive number (-1:invalid drive) */
292+
int ff_get_ldnumber(const TCHAR** path);
291293

292294

293295
/*--------------------------------------------------------------*/

stmhal/ffconf.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013, 2014 Damien P. George
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include <string.h>
28+
29+
#include "mpconfigport.h"
30+
#include "ff.h"
31+
#include "ffconf.h"
32+
33+
extern BYTE CurrVol;
34+
35+
// "path" is the path to lookup; will advance this pointer beyond the volume name.
36+
// Returns logical drive number (-1 means invalid path).
37+
int ff_get_ldnumber (const TCHAR** path) {
38+
if (!(*path)) {
39+
return -1;
40+
}
41+
42+
if (**path != '/') {
43+
#if _FS_RPATH
44+
return CurrVol;
45+
#else
46+
return -1;
47+
#endif
48+
} else if (strncmp(*path, "/flash", 6) == 0) {
49+
if ((*path)[6] == '/') {
50+
*path += 6;
51+
} else if ((*path)[6] == '\0') {
52+
*path = "/";
53+
} else {
54+
return -1;
55+
}
56+
return 0;
57+
} else if (strncmp(*path, "/sd", 3) == 0) {
58+
if ((*path)[3] == '/') {
59+
*path += 3;
60+
} else if ((*path)[3] == '\0') {
61+
*path = "/";
62+
} else {
63+
return -1;
64+
}
65+
return 1;
66+
} else {
67+
return -1;
68+
}
69+
}

stmhal/ffconf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
/ This option has no effect when _LFN_UNICODE is 0. */
144144

145145

146-
#define _FS_RPATH 0 /* 0 to 2 */
146+
#define _FS_RPATH 2 /* 0 to 2 */
147147
/* The _FS_RPATH option configures relative path feature.
148148
/
149149
/ 0: Disable relative path feature and remove related functions.

stmhal/main.c

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,9 @@ int main(void) {
332332
qstr_init();
333333
mp_init();
334334
mp_obj_list_init(mp_sys_path, 0);
335-
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_));
336-
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_lib));
335+
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
336+
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash));
337+
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib));
337338
mp_obj_list_init(mp_sys_argv, 0);
338339

339340
readline_init();
@@ -344,15 +345,15 @@ int main(void) {
344345
// local filesystem init
345346
{
346347
// try to mount the flash
347-
FRESULT res = f_mount(&fatfs0, "0:", 1);
348+
FRESULT res = f_mount(&fatfs0, "/flash", 1);
348349
if (reset_mode == 3 || res == FR_NO_FILESYSTEM) {
349350
// no filesystem, or asked to reset it, so create a fresh one
350351

351352
// LED on to indicate creation of LFS
352353
led_state(PYB_LED_R2, 1);
353354
uint32_t start_tick = HAL_GetTick();
354355

355-
res = f_mkfs("0:", 0, 0);
356+
res = f_mkfs("/flash", 0, 0);
356357
if (res == FR_OK) {
357358
// success creating fresh LFS
358359
} else {
@@ -361,19 +362,19 @@ int main(void) {
361362

362363
// create empty main.py
363364
FIL fp;
364-
f_open(&fp, "0:/main.py", FA_WRITE | FA_CREATE_ALWAYS);
365+
f_open(&fp, "/flash/main.py", FA_WRITE | FA_CREATE_ALWAYS);
365366
UINT n;
366367
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
367368
// TODO check we could write n bytes
368369
f_close(&fp);
369370

370371
// create .inf driver file
371-
f_open(&fp, "0:/pybcdc.inf", FA_WRITE | FA_CREATE_ALWAYS);
372+
f_open(&fp, "/flash/pybcdc.inf", FA_WRITE | FA_CREATE_ALWAYS);
372373
f_write(&fp, fresh_pybcdc_inf, sizeof(fresh_pybcdc_inf) - 1 /* don't count null terminator */, &n);
373374
f_close(&fp);
374375

375376
// create readme file
376-
f_open(&fp, "0:/README.txt", FA_WRITE | FA_CREATE_ALWAYS);
377+
f_open(&fp, "/flash/README.txt", FA_WRITE | FA_CREATE_ALWAYS);
377378
f_write(&fp, fresh_readme_txt, sizeof(fresh_readme_txt) - 1 /* don't count null terminator */, &n);
378379
f_close(&fp);
379380

@@ -387,14 +388,14 @@ int main(void) {
387388
}
388389
}
389390

390-
// make sure we have a 0:/boot.py
391+
// make sure we have a /flash/boot.py
391392
{
392393
FILINFO fno;
393394
#if _USE_LFN
394395
fno.lfname = NULL;
395396
fno.lfsize = 0;
396397
#endif
397-
FRESULT res = f_stat("0:/boot.py", &fno);
398+
FRESULT res = f_stat("/flash/boot.py", &fno);
398399
if (res == FR_OK) {
399400
if (fno.fattrib & AM_DIR) {
400401
// exists as a directory
@@ -411,7 +412,7 @@ int main(void) {
411412
uint32_t start_tick = HAL_GetTick();
412413

413414
FIL fp;
414-
f_open(&fp, "0:/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
415+
f_open(&fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
415416
UINT n;
416417
f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
417418
// TODO check we could write n bytes
@@ -424,21 +425,25 @@ int main(void) {
424425
}
425426

426427
// root device defaults to internal flash filesystem
427-
uint root_device = 0;
428+
f_chdrive("/flash");
428429

429430
#if defined(USE_DEVICE_MODE)
430431
usb_storage_medium_t usb_medium = USB_STORAGE_MEDIUM_FLASH;
431432
#endif
432433

433434
#if MICROPY_HW_HAS_SDCARD
434-
// if an SD card is present then mount it on 1:/
435+
// if an SD card is present then mount it on /sd/
435436
if (reset_mode == 1 && sdcard_is_present()) {
436-
FRESULT res = f_mount(&fatfs1, "1:", 1);
437+
FRESULT res = f_mount(&fatfs1, "/sd", 1);
437438
if (res != FR_OK) {
438439
printf("[SD] could not mount SD card\n");
439440
} else {
440441
// use SD card as root device
441-
root_device = 1;
442+
f_chdrive("/sd");
443+
444+
// TODO these should go before the /flash entries in the path
445+
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
446+
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
442447

443448
if (first_soft_reset) {
444449
// use SD card as medium for the USB MSD
@@ -453,17 +458,12 @@ int main(void) {
453458
(void)first_soft_reset;
454459
#endif
455460

456-
// run <root>:/boot.py, if it exists
461+
// run boot.py, if it exists
457462
if (reset_mode == 1) {
458-
const char *boot_file;
459-
if (root_device == 0) {
460-
boot_file = "0:/boot.py";
461-
} else {
462-
boot_file = "1:/boot.py";
463-
}
464-
FRESULT res = f_stat(boot_file, NULL);
463+
const char *boot_py = "boot.py";
464+
FRESULT res = f_stat(boot_py, NULL);
465465
if (res == FR_OK) {
466-
if (!pyexec_file(boot_file)) {
466+
if (!pyexec_file(boot_py)) {
467467
flash_error(4);
468468
}
469469
}
@@ -518,20 +518,18 @@ int main(void) {
518518

519519
// now that everything is initialised, run main script
520520
if (reset_mode == 1 && pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
521-
vstr_t *vstr = vstr_new();
522-
vstr_printf(vstr, "%d:/", root_device);
521+
const char *main_py;
523522
if (pyb_config_main == MP_OBJ_NULL) {
524-
vstr_add_str(vstr, "main.py");
523+
main_py = "main.py";
525524
} else {
526-
vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_main));
525+
main_py = mp_obj_str_get_str(pyb_config_main);
527526
}
528-
FRESULT res = f_stat(vstr_str(vstr), NULL);
527+
FRESULT res = f_stat(main_py, NULL);
529528
if (res == FR_OK) {
530-
if (!pyexec_file(vstr_str(vstr))) {
529+
if (!pyexec_file(main_py)) {
531530
flash_error(3);
532531
}
533532
}
534-
vstr_free(vstr);
535533
}
536534

537535
#if MICROPY_HW_ENABLE_CC3K

0 commit comments

Comments
 (0)