cc3200: Enable long filename support in FatFS.

This has implications all over the place. I have to admit that
you can instantly see that usability improves, but it costs 3K.
At the same time I took the oportunity to rename the '/SFLASH'
drive to '/flash' which improves compatibility with the pyboard.
This commit is contained in:
Daniel Campora 2015-04-10 21:02:07 +02:00
parent d35ac956d1
commit 6e25d955f4
13 changed files with 153 additions and 81 deletions

View File

@ -83,7 +83,7 @@
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 72 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16384 ) )
#define configMAX_TASK_NAME_LEN ( 8 )
#define configUSE_TRACE_FACILITY 0

View File

@ -139,8 +139,9 @@ APP_MAIN_SRC_C = \
serverstask.c
APP_LIB_SRC_C = $(addprefix lib/,\
libc/string0.c \
fatfs/ff.c \
fatfs/option/ccsbcs.c \
libc/string0.c \
mp-readline/readline.c \
)
@ -206,7 +207,7 @@ endif
SHELL = bash
APP_SIGN = appsign.sh
all: $(BUILD)/MCUIMG.BIN
all: $(BUILD)/mcuimg.bin
$(BUILD)/application.axf: $(OBJ) $(LINKER_SCRIPT)
$(ECHO) "LINK $@"
@ -217,7 +218,7 @@ $(BUILD)/application.bin: $(BUILD)/application.axf
$(ECHO) "Create $@"
$(Q)$(OBJCOPY) -O binary $< $@
$(BUILD)/MCUIMG.BIN: $(BUILD)/application.bin
$(BUILD)/mcuimg.bin: $(BUILD)/application.bin
$(ECHO) "Create $@"
$(Q)$(SHELL) $(APP_SIGN) $(BOARD) $(BTYPE)

View File

@ -16,13 +16,13 @@ BUILD=build/${BOARD}/${BTYPE}
echo -n `md5sum --binary $BUILD/application.bin | awk '{ print $1 }'` > __md5hash.bin
# Concatenate it with the application binary
cat $BUILD/application.bin __md5hash.bin > $BUILD/MCUIMG.BIN
cat $BUILD/application.bin __md5hash.bin > $BUILD/mcuimg.bin
RET=$?
# Remove the tmp files
rm -f __md5hash.bin
# Remove hte unsigned binary
# Remove the unsigned binary
rm -f $BUILD/application.bin
exit $RET

View File

@ -38,7 +38,6 @@ extern BYTE ff_CurrVol;
#endif
STATIC bool check_path(const TCHAR **path, const char *mount_point_str, mp_uint_t mount_point_len) {
stoupper ((char *)(*path));
if (strncmp(*path, mount_point_str, mount_point_len) == 0) {
if ((*path)[mount_point_len] == '/') {
*path += mount_point_len;
@ -66,11 +65,11 @@ int ff_get_ldnumber (const TCHAR **path) {
#endif
}
if (check_path(path, "/SFLASH", 7)) {
if (check_path(path, "/flash", 6)) {
return 0;
}
#if MICROPY_HW_HAS_SDCARD
else if (check_path(path, "/SD", 3)) {
else if (check_path(path, "/sd", 3)) {
return 1;
}
#endif
@ -84,13 +83,13 @@ void ff_get_volname(BYTE vol, TCHAR **dest) {
if (vol == 0)
#endif
{
memcpy(*dest, "/SFLASH", 7);
memcpy(*dest, "/flash", 6);
*dest += 7;
}
#if MICROPY_HW_HAS_SDCARD
else
{
memcpy(*dest, "/SD", 3);
memcpy(*dest, "/sd", 3);
*dest += 3;
}
#endif

View File

@ -3,8 +3,6 @@
/* (C)ChaN, 2014 */
/*------------------------------------------------------------------------*/
#include "py/mpconfig.h"
#include MICROPY_HAL_H
#include "ff.h"
@ -134,7 +132,7 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block */
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
return pvPortMalloc(msize); /* Allocate a new memory block with POSIX API */
}
@ -146,7 +144,7 @@ void ff_memfree (
void* mblock /* Pointer to the memory block to free */
)
{
free(mblock); /* Discard the memory block with POSIX API */
vPortFree(mblock); /* Discard the memory block with POSIX API */
}
#endif

View File

@ -301,19 +301,21 @@ void ftp_run (void) {
if (SOCKETFIFO_IsEmpty()) {
uint32_t readsize;
ftp_result_t result;
ftp_data.ctimeout = 0;
result = ftp_read_file ((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, &readsize);
if (readsize > 0 && result != E_FTP_RESULT_FAILED) {
ftp_send_data(readsize);
ftp_data.ctimeout = 0;
if (result == E_FTP_RESULT_FAILED) {
ftp_send_reply(451, NULL);
ftp_data.state = E_FTP_STE_END_TRANSFER;
}
else {
if (readsize > 0) {
ftp_send_data(readsize);
}
if (result == E_FTP_RESULT_OK) {
ftp_send_reply(226, NULL);
ftp_data.state = E_FTP_STE_END_TRANSFER;
}
}
else {
ftp_send_reply(451, NULL);
ftp_data.state = E_FTP_STE_END_TRANSFER;
}
}
break;
case E_FTP_STE_CONTINUE_FILE_RX:
@ -588,8 +590,12 @@ static void ftp_process_cmd (void) {
char *bufptr = (char *)ftp_cmd_buffer;
ftp_result_t result;
uint32_t listsize;
FILINFO fno;
FRESULT fres;
FILINFO fno;
#if _USE_LFN
fno.lfname = NULL;
fno.lfsize = 0;
#endif
ftp_data.closechild = false;
// also use the reply buffer to receive new commands
@ -887,12 +893,20 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - fseconds) {
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
#if _USE_LFN
1980 + ((fno->fdate >> 9) & 0x7f), *fno->lfname ? fno->lfname : fno->fname);
#else
1980 + ((fno->fdate >> 9) & 0x7f), fno->fname);
#endif
}
else {
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %02u:%02u %s\r\n",
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
#if _USE_LFN
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, *fno->lfname ? fno->lfname : fno->fname);
#else
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, fno->fname);
#endif
}
}
@ -956,10 +970,10 @@ static ftp_result_t ftp_open_dir_for_listing (const char *path, char *list, uint
uint next = 0;
// "hack" to list root directory
if (path[0] == '/' && path[1] == '\0') {
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "SFLASH");
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
#if MICROPY_HW_HAS_SDCARD
if (sd_disk_ready()) {
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "SD");
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "sd");
}
#endif
*listsize = next;
@ -979,11 +993,18 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
uint next = 0;
uint count = 0;
FRESULT res;
FILINFO fno;
ftp_result_t result = E_FTP_RESULT_CONTINUE;
FILINFO fno;
#if _USE_LFN
fno.lfname = mem_Malloc(_MAX_LFN);
fno.lfsize = _MAX_LFN;
/* read up to 4 directory items */
while (count++ < 4) {
// read up to 2 directory items
while (count < 2) {
#else
// read up to 4 directory items
while (count < 4) {
#endif
res = f_readdir(&ftp_data.dp, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) {
result = E_FTP_RESULT_OK;
@ -992,13 +1013,17 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
// Add the entry to the list
// add the entry to the list
next += ftp_print_eplf_item((list + next), (maxlistsize - next), &fno);
count++;
}
if (result == E_FTP_RESULT_OK) {
ftp_close_files();
}
*listsize = next;
#if _USE_LFN
mem_Free(fno.lfname);
#endif
return result;
}

View File

@ -14,9 +14,9 @@
/******************************************************************************
DEFINE PRIVATE CONSTANTS
******************************************************************************/
#define UPDATER_IMG_PATH "/SFLASH/SYS/MCUIMG.BIN"
#define UPDATER_SRVPACK_PATH "/SFLASH/SYS/SRVPCK.UCF"
#define UPDATER_SIGN_PATH "/SFLASH/SYS/SRVPCK.SIG"
#define UPDATER_IMG_PATH "/flash/sys/mcuimg.bin"
#define UPDATER_SRVPACK_PATH "/flash/sys/servicepack.ucf"
#define UPDATER_SIGN_PATH "/flash/sys/servicepack.sig"
/******************************************************************************
DEFINE TYPES
@ -37,8 +37,6 @@ static updater_data_t updater_data;
DEFINE PUBLIC FUNCTIONS
******************************************************************************/
bool updater_check_path (void *path) {
// conert the path supplied to upper case
stoupper (path);
if (!strcmp(UPDATER_IMG_PATH, path)) {
updater_data.path = IMG_UPDATE;
updater_data.fsize = IMG_SIZE;

View File

@ -49,11 +49,11 @@
/// The filesystem has `/` as the root directory, and the available physical
/// drives are accessible from here. They are currently:
///
/// /SFLASH -- the serial flash filesystem
/// /SD -- the SD card (if it exists)
/// /flash -- the serial flash filesystem
/// /sd -- the SD card (if it exists)
///
/// On boot up, the current directory is `/SFLASH` if no SD card is inserted,
/// otherwise it is `/SD`.
/// On boot up, the current directory is `/flash` if no SD card is inserted,
/// otherwise it is `/sd`.
/******************************************************************************
DEFINE PRIVATE FUNCTIONS
@ -109,6 +109,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
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;
@ -121,16 +122,21 @@ 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_SFLASH));
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));
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_sd));
}
return dir_list;
}
FRESULT res;
FILINFO fno;
DIR dir;
FILINFO fno;
#if _USE_LFN
char lfn_buf[_MAX_LFN + 1];
fno.lfname = lfn_buf;
fno.lfsize = sizeof(lfn_buf);
#endif
res = f_opendir(&dir, path); /* Open the directory */
if (res != FR_OK) {
@ -145,7 +151,11 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
#if _USE_LFN
char *fn = *fno.lfname ? fno.lfname : fno.fname;
#else
char *fn = fno.fname;
#endif
// make a string object for this entry
mp_obj_t entry_o;
@ -215,14 +225,18 @@ STATIC bool path_equal(const char *path, const char *path_canonical) {
/// 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);
stoupper((char *)path);
FILINFO fno;
FRESULT res;
if (path_equal(path, "/") || path_equal(path, "/SFLASH") || path_equal(path, "/SD")) {
FILINFO fno;
#if _USE_LFN
fno.lfname = NULL;
fno.lfsize = 0;
#endif
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
if (path[1] == 's' && !sd_in_root()) {
// no /sd directory
res = FR_NO_PATH;
goto error;
}

View File

@ -148,13 +148,13 @@ STATIC mp_obj_t pybsd_enable (mp_obj_t self_in) {
// do the init first
pybsd_init (self);
// try to mount the sd card on /SD
if (FR_OK != f_mount(self->fatfs, "/SD", 1)) {
// try to mount the sd card on /sd
if (FR_OK != f_mount(self->fatfs, "/sd", 1)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
}
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));
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));
// register it with the sleep module
pybsleep_add ((const mp_obj_t)&pybsd_obj, (WakeUpCB_t)pybsd_init);
@ -172,10 +172,10 @@ STATIC mp_obj_t pybsd_disable (mp_obj_t self_in) {
if (self->enabled) {
self->enabled = false;
// unmount the sd card
f_mount (NULL, "/SD", 1);
f_mount (NULL, "/sd", 1);
// remove sd paths from mp_sys_path
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD));
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD_slash_LIB));
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
// disable the peripheral
MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
@ -186,8 +186,8 @@ STATIC mp_obj_t pybsd_disable (mp_obj_t self_in) {
// unregister it with the sleep module
pybsleep_remove (self);
// change the drive in case it was /SD
f_chdrive("/SFLASH");
// change the drive in case it was /sd
f_chdrive("/flash");
}
return mp_const_none;
}

View File

@ -54,8 +54,8 @@
2: Enable LFN with dynamic working buffer on the STACK.
3: Enable LFN with dynamic working buffer on the HEAP.
*/
#define MICROPY_ENABLE_LFN (0)
#define MICROPY_LFN_CODE_PAGE (1)
#define MICROPY_ENABLE_LFN (2)
#define MICROPY_LFN_CODE_PAGE (437) // 1=SFN/ANSI 437=LFN/U.S.(OEM)
#define MICROPY_STREAMS_NON_BLOCK (1)
#define MICROPY_MODULE_WEAK_LINKS (0)
#define MICROPY_CAN_OVERRIDE_BUILTINS (0)

View File

@ -174,16 +174,16 @@ soft_reset:
// initialize the serial flash file system
mptask_init_sflash_filesystem();
// append the SFLASH paths to the system path
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SFLASH));
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SFLASH_slash_LIB));
// append the flash paths to the system path
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash));
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib));
// reset config variables; they should be set by boot.py
MP_STATE_PORT(pyb_config_main) = MP_OBJ_NULL;
if (!safeboot) {
// run boot.py, if it exists
const char *boot_py = "BOOT.PY";
const char *boot_py = "boot.py";
res = f_stat(boot_py, NULL);
if (res == FR_OK) {
int ret = pyexec_file(boot_py);
@ -208,7 +208,7 @@ soft_reset:
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
const char *main_py;
if (MP_STATE_PORT(pyb_config_main) == MP_OBJ_NULL) {
main_py = "MAIN.PY";
main_py = "main.py";
} else {
main_py = mp_obj_str_get_str(MP_STATE_PORT(pyb_config_main));
}
@ -290,38 +290,42 @@ STATIC void mptask_pre_init (void) {
}
STATIC void mptask_init_sflash_filesystem (void) {
FILINFO fno;
#if _USE_LFN
fno.lfname = NULL;
fno.lfsize = 0;
#endif
// Initialise the local flash filesystem.
// Create it if needed, and mount in on /sflash.
// Create it if needed, and mount in on /flash.
// try to mount the flash
FRESULT res = f_mount(sflash_fatfs, "/SFLASH", 1);
FRESULT res = f_mount(sflash_fatfs, "/flash", 1);
if (res == FR_NO_FILESYSTEM) {
// no filesystem, so create a fresh one
res = f_mkfs("/SFLASH", 1, 0);
res = f_mkfs("/flash", 1, 0);
if (res == FR_OK) {
// success creating fresh LFS
} else {
__fatal_error("failed to create /SFLASH");
__fatal_error("failed to create /flash");
}
// create empty main.py
mptask_create_main_py();
} else if (res == FR_OK) {
// mount sucessful
FILINFO fno;
if (FR_OK != f_stat("/SFLASH/MAIN.PY", &fno)) {
if (FR_OK != f_stat("/flash/main.py", &fno)) {
// create empty main.py
mptask_create_main_py();
}
} else {
__fatal_error("failed to create /SFLASH");
__fatal_error("failed to create /flash");
}
// The current directory is used as the boot up directory.
// It is set to the internal flash filesystem by default.
f_chdrive("/SFLASH");
f_chdrive("/flash");
// Make sure we have a /flash/boot.py. Create it if needed.
FILINFO fno;
res = f_stat("/SFLASH/BOOT.PY", &fno);
res = f_stat("/flash/boot.py", &fno);
if (res == FR_OK) {
if (fno.fattrib & AM_DIR) {
// exists as a directory
@ -333,7 +337,7 @@ STATIC void mptask_init_sflash_filesystem (void) {
} else {
// doesn't exist, create fresh file
FIL fp;
f_open(&fp, "/SFLASH/BOOT.PY", FA_WRITE | FA_CREATE_ALWAYS);
f_open(&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
@ -350,7 +354,7 @@ STATIC void mptask_enter_ap_mode (void) {
STATIC void mptask_create_main_py (void) {
// create empty main.py
FIL fp;
f_open(&fp, "/SFLASH/MAIN.PY", FA_WRITE | FA_CREATE_ALWAYS);
f_open(&fp, "/flash/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);
f_close(&fp);

View File

@ -1,3 +1,30 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
* Copyright (c) 2015 Daniel Campora
*
* 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.
*/
// qstrs specific to this port
Q(__name__)
Q(help)
@ -36,10 +63,12 @@ Q(mkdisk)
Q(enable)
Q(disable)
// Entries for sys.path
Q(/SFLASH)
Q(/SFLASH/LIB)
Q(/SD)
Q(/SD/LIB)
Q(/flash)
Q(/flash/lib)
#if MICROPY_HW_HAS_SDCARD
Q(/sd)
Q(/sd/lib)
#endif
// for module weak links
Q(re)
@ -50,8 +79,10 @@ Q(heapq)
Q(uos)
Q(os)
Q(/)
Q(SFLASH)
Q(SD)
Q(flash)
#if MICROPY_HW_HAS_SDCARD
Q(sd)
#endif
Q(chdir)
Q(getcwd)
Q(listdir)
@ -144,10 +175,12 @@ Q(mem_write)
Q(ADC)
Q(read)
#if MICROPY_HW_HAS_SDCARD
// for SD class
Q(SD)
Q(enable)
Q(disable)
#endif
// for RTC class
Q(RTC)

View File

@ -31,7 +31,7 @@
DEFINE CONSTANTS
******************************************************************************/
#define SERVERS_PRIORITY 2
#define SERVERS_STACK_SIZE 944
#define SERVERS_STACK_SIZE 1072
#define SERVERS_SSID_LEN_MAX 16
#define SERVERS_KEY_LEN_MAX 16