cc3200: Convert to use new VFS sub-system and new ooFatFs library.
This commit is contained in:
parent
6eafa54486
commit
56506fd64a
@ -23,6 +23,7 @@ CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -march=armv7e-m -mabi=aapcs -mcpu=co
|
||||
CFLAGS = -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) -Os
|
||||
CFLAGS += -g -ffunction-sections -fdata-sections -fno-common -fsigned-char -mno-unaligned-access
|
||||
CFLAGS += -Iboards/$(BOARD)
|
||||
CFLAGS += $(CFLAGS_MOD)
|
||||
|
||||
LDFLAGS = -Wl,-nostdlib -Wl,--gc-sections -Wl,-Map=$@.map
|
||||
|
||||
|
@ -18,7 +18,6 @@ APP_INC += -Iutil
|
||||
APP_INC += -Ibootmgr
|
||||
APP_INC += -I$(BUILD)
|
||||
APP_INC += -I$(BUILD)/genhdr
|
||||
APP_INC += -I../lib/fatfs
|
||||
APP_INC += -I../lib/mp-readline
|
||||
APP_INC += -I../lib/netutils
|
||||
APP_INC += -I../lib/timeutils
|
||||
@ -29,9 +28,6 @@ APP_CPPDEFINES = -Dgcc -DTARGET_IS_CC3200 -DSL_FULL -DUSE_FREERTOS
|
||||
APP_FATFS_SRC_C = $(addprefix fatfs/src/,\
|
||||
drivers/sflash_diskio.c \
|
||||
drivers/sd_diskio.c \
|
||||
option/syscall.c \
|
||||
diskio.c \
|
||||
ffconf.c \
|
||||
)
|
||||
|
||||
APP_RTOS_SRC_C = $(addprefix FreeRTOS/Source/,\
|
||||
@ -98,6 +94,7 @@ APP_MODS_SRC_C = $(addprefix mods/,\
|
||||
pybpin.c \
|
||||
pybi2c.c \
|
||||
pybrtc.c \
|
||||
pybflash.c \
|
||||
pybsd.c \
|
||||
pybsleep.c \
|
||||
pybspi.c \
|
||||
@ -143,11 +140,12 @@ APP_MAIN_SRC_C = \
|
||||
main.c \
|
||||
mptask.c \
|
||||
mpthreadport.c \
|
||||
serverstask.c
|
||||
serverstask.c \
|
||||
fatfs_port.c \
|
||||
|
||||
APP_LIB_SRC_C = $(addprefix lib/,\
|
||||
fatfs/ff.c \
|
||||
fatfs/option/ccsbcs.c \
|
||||
oofatfs/ff.c \
|
||||
oofatfs/option/unicode.c \
|
||||
libc/string0.c \
|
||||
mp-readline/readline.c \
|
||||
netutils/netutils.c \
|
||||
|
@ -1,209 +0,0 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* If a working storage control module is available, it should be */
|
||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||
/* This is an example of glue functions to attach various exsisting */
|
||||
/* storage control modules to the FatFs module with a defined API. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "lib/fatfs/ff.h"
|
||||
#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
|
||||
#include "sflash_diskio.h" /* Serial flash disk IO API */
|
||||
#include "sd_diskio.h" /* SDCARD disk IO API */
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "pybrtc.h"
|
||||
#include "timeutils.h"
|
||||
#include "pybsd.h"
|
||||
#include "moduos.h"
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
return sflash_disk_status();
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
||||
return STA_PROTECT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return STA_NODISK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
if (RES_OK != sflash_disk_init()) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
||||
return STA_PROTECT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return STA_NODISK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector address in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
return sflash_disk_read(buff, sector, count);
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
// optimization for the built-in sd card device
|
||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||
return sd_disk_read(buff, sector, count);
|
||||
}
|
||||
mount_obj->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
||||
mount_obj->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
|
||||
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->readblocks));
|
||||
}
|
||||
// nothing mounted
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector address in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
return sflash_disk_write(buff, sector, count);
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
// optimization for the built-in sd card device
|
||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||
return sd_disk_write(buff, sector, count);
|
||||
}
|
||||
mount_obj->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
||||
mount_obj->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void *)buff);
|
||||
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->writeblocks));
|
||||
}
|
||||
// nothing mounted
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
if (pdrv == PD_FLASH) {
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
return sflash_disk_flush();
|
||||
case GET_SECTOR_COUNT:
|
||||
*((DWORD*)buff) = SFLASH_SECTOR_COUNT;
|
||||
return RES_OK;
|
||||
case GET_SECTOR_SIZE:
|
||||
*((DWORD*)buff) = SFLASH_SECTOR_SIZE;
|
||||
return RES_OK;
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
||||
return RES_OK;
|
||||
}
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
if (mount_obj->sync[0] != MP_OBJ_NULL) {
|
||||
mp_call_method_n_kw(0, 0, mount_obj->sync);
|
||||
}
|
||||
return RES_OK;
|
||||
case GET_SECTOR_COUNT:
|
||||
// optimization for the built-in sd card device
|
||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||
*((DWORD*)buff) = sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512);
|
||||
} else {
|
||||
*((DWORD*)buff) = mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count));
|
||||
}
|
||||
return RES_OK;
|
||||
case GET_SECTOR_SIZE:
|
||||
*((DWORD*)buff) = SD_SECTOR_SIZE; // Sector size is fixed to 512 bytes, as with SD cards
|
||||
return RES_OK;
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
||||
return RES_OK;
|
||||
}
|
||||
}
|
||||
// nothing mounted
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !_FS_READONLY && !_FS_NORTC
|
||||
DWORD get_fattime (
|
||||
void
|
||||
)
|
||||
{
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
|
||||
|
||||
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
||||
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
||||
((tm.tm_min) << 5) | (tm.tm_sec >> 1);
|
||||
}
|
||||
#endif
|
||||
|
@ -39,11 +39,12 @@
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "hw_types.h"
|
||||
#include "hw_memmap.h"
|
||||
#include "hw_ints.h"
|
||||
#include "rom_map.h"
|
||||
#include "diskio.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "sdhost.h"
|
||||
#include "pin.h"
|
||||
|
@ -4,8 +4,9 @@
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "simplelink.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "debug.h"
|
||||
#include "modnetwork.h"
|
||||
|
@ -1,93 +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 <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "lib/fatfs/ff.h"
|
||||
#include "lib/fatfs/ffconf.h"
|
||||
#include "lib/fatfs/diskio.h"
|
||||
#include "moduos.h"
|
||||
|
||||
#if _FS_RPATH
|
||||
extern BYTE ff_CurrVol;
|
||||
#endif
|
||||
|
||||
STATIC bool check_path(const TCHAR **path, const char *mount_point_str, mp_uint_t mount_point_len) {
|
||||
if (strncmp(*path, mount_point_str, mount_point_len) == 0) {
|
||||
if ((*path)[mount_point_len] == '/') {
|
||||
*path += mount_point_len;
|
||||
return true;
|
||||
} else if ((*path)[mount_point_len] == '\0') {
|
||||
*path = "/";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// "path" is the path to lookup; will advance this pointer beyond the volume name.
|
||||
// Returns logical drive number (-1 means invalid path).
|
||||
int ff_get_ldnumber (const TCHAR **path) {
|
||||
if (!(*path)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (**path != '/') {
|
||||
#if _FS_RPATH
|
||||
return ff_CurrVol;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (check_path(path, "/flash", 6)) {
|
||||
return PD_FLASH;
|
||||
}
|
||||
else {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (check_path(path, mount_obj->path, mount_obj->pathlen)) {
|
||||
return mount_obj->vol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ff_get_volname(BYTE vol, TCHAR **dest) {
|
||||
if (vol == PD_FLASH) {
|
||||
memcpy(*dest, "/flash", 6);
|
||||
*dest += 6;
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(vol))) {
|
||||
memcpy(*dest, mount_obj->path, mount_obj->pathlen);
|
||||
*dest += mount_obj->pathlen;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample code of OS dependent controls for FatFs */
|
||||
/* (C)ChaN, 2014 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
#if _FS_REENTRANT
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */
|
||||
BYTE vol, /* Corresponding logical drive being processed */
|
||||
_SYNC_t *sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
//
|
||||
// *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
|
||||
// ret = (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */
|
||||
// ret = 1; /* The initial value of the semaphore must be 1. */
|
||||
|
||||
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
vSemaphoreCreateBinary( (*sobj) ); /* FreeRTOS */
|
||||
ret = (int)(*sobj != NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to delete a synchronization
|
||||
/ object that created with ff_cre_syncobj function. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */
|
||||
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
// ret = CloseHandle(sobj); /* Win32 */
|
||||
|
||||
// ret = 1; /* uITRON (nothing to do) */
|
||||
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
vSemaphoreDelete(sobj); /* FreeRTOS */
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on entering file functions to lock the volume.
|
||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
||||
_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
// ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
|
||||
|
||||
// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
|
||||
|
||||
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
// ReleaseMutex(sobj); /* Win32 */
|
||||
|
||||
// sig_sem(sobj); /* uITRON */
|
||||
|
||||
// OSMutexPost(sobj); /* uC/OS-II */
|
||||
|
||||
xSemaphoreGive(sobj); /* FreeRTOS */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
||||
*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return pvPortMalloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free */
|
||||
)
|
||||
{
|
||||
vPortFree(mblock); /* Discard the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
74
cc3200/fatfs_port.c
Normal file
74
cc3200/fatfs_port.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2017 Damien P. George
|
||||
* Parts of this file are (C)ChaN, 2014, from FatFs option/syscall.c
|
||||
*
|
||||
* 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 "lib/oofatfs/ff.h"
|
||||
#include "lib/timeutils/timeutils.h"
|
||||
#include "mods/pybrtc.h"
|
||||
|
||||
#if _FS_REENTRANT
|
||||
// Create a Synchronization Object
|
||||
// This function is called in f_mount() function to create a new
|
||||
// synchronization object, such as semaphore and mutex.
|
||||
// A return of 0 indicates failure, and then f_mount() fails with FR_INT_ERR.
|
||||
int ff_cre_syncobj(FATFS *fatfs, _SYNC_t *sobj) {
|
||||
vSemaphoreCreateBinary((*sobj));
|
||||
return (int)(*sobj != NULL);
|
||||
}
|
||||
|
||||
// Delete a Synchronization Object
|
||||
// This function is called in f_mount() function to delete a synchronization
|
||||
// object that created with ff_cre_syncobj function.
|
||||
// A return of 0 indicates failure, and then f_mount() fails with FR_INT_ERR.
|
||||
int ff_del_syncobj(_SYNC_t sobj) {
|
||||
vSemaphoreDelete(sobj);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Request Grant to Access the Volume
|
||||
// This function is called on entering file functions to lock the volume.
|
||||
// When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
int ff_req_grant(_SYNC_t sobj) {
|
||||
return (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE);
|
||||
}
|
||||
|
||||
// Release Grant to Access the Volume
|
||||
// This function is called on leaving file functions to unlock the volume.
|
||||
void ff_rel_grant(_SYNC_t sobj) {
|
||||
xSemaphoreGive(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
DWORD get_fattime(void) {
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
|
||||
|
||||
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
||||
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
||||
((tm.tm_min) << 5) | (tm.tm_sec >> 1);
|
||||
}
|
135
cc3200/ftp/ftp.c
135
cc3200/ftp/ftp.c
@ -30,6 +30,9 @@
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/obj.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include "extmod/fsusermount.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
@ -43,7 +46,6 @@
|
||||
#include "modusocket.h"
|
||||
#include "debug.h"
|
||||
#include "serverstask.h"
|
||||
#include "ff.h"
|
||||
#include "fifo.h"
|
||||
#include "socketfifo.h"
|
||||
#include "updater.h"
|
||||
@ -115,7 +117,7 @@ typedef struct {
|
||||
uint8_t *dBuffer;
|
||||
uint32_t ctimeout;
|
||||
union {
|
||||
DIR dp;
|
||||
FF_DIR dp;
|
||||
FIL fp;
|
||||
};
|
||||
int16_t lc_sd;
|
||||
@ -192,6 +194,80 @@ static const ftp_month_t ftp_month[] = { { "Jan" }, { "Feb" }, { "Mar" }, { "Apr
|
||||
static SocketFifoElement_t ftp_fifoelements[FTP_SOCKETFIFO_ELEMENTS_MAX];
|
||||
static FIFO_t ftp_socketfifo;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE VFS WRAPPER FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
// These wrapper functions are used so that the FTP server can access the
|
||||
// mounted FATFS devices directly without going through the costly mp_vfs_XXX
|
||||
// functions. The latter may raise exceptions and we would then need to wrap
|
||||
// all calls in an nlr handler. The wrapper functions below assume that there
|
||||
// are only FATFS filesystems mounted.
|
||||
|
||||
STATIC FATFS *lookup_path(const TCHAR **path) {
|
||||
mp_vfs_mount_t *fs = mp_vfs_lookup_path(*path, path);
|
||||
if (fs == MP_VFS_NONE || fs == MP_VFS_ROOT) {
|
||||
return NULL;
|
||||
}
|
||||
// here we assume that the mounted device is FATFS
|
||||
return &((fs_user_mount_t*)MP_OBJ_TO_PTR(fs->obj))->fatfs;
|
||||
}
|
||||
|
||||
STATIC FRESULT f_open_helper(FIL *fp, const TCHAR *path, BYTE mode) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_open(fs, fp, path, mode);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_opendir_helper(FF_DIR *dp, const TCHAR *path) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_opendir(fs, dp, path);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_stat_helper(const TCHAR *path, FILINFO *fno) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_stat(fs, path, fno);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_mkdir_helper(const TCHAR *path) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_mkdir(fs, path);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_unlink_helper(const TCHAR *path) {
|
||||
FATFS *fs = lookup_path(&path);
|
||||
if (fs == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_unlink(fs, path);
|
||||
}
|
||||
|
||||
STATIC FRESULT f_rename_helper(const TCHAR *path_old, const TCHAR *path_new) {
|
||||
FATFS *fs_old = lookup_path(&path_old);
|
||||
if (fs_old == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
FATFS *fs_new = lookup_path(&path_new);
|
||||
if (fs_new == NULL) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
if (fs_old != fs_new) {
|
||||
return FR_NO_PATH;
|
||||
}
|
||||
return f_rename(fs_new, path_old, path_new);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
@ -210,7 +286,7 @@ static void ftp_close_cmd_data (void);
|
||||
static ftp_cmd_index_t ftp_pop_command (char **str);
|
||||
static void ftp_pop_param (char **str, char *param);
|
||||
static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno);
|
||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name);
|
||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, const char *name);
|
||||
static bool ftp_open_file (const char *path, int mode);
|
||||
static ftp_result_t ftp_read_file (char *filebuf, uint32_t desiredsize, uint32_t *actualsize);
|
||||
static ftp_result_t ftp_write_file (char *filebuf, uint32_t size);
|
||||
@ -604,10 +680,6 @@ static void ftp_process_cmd (void) {
|
||||
ftp_result_t result;
|
||||
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
|
||||
@ -634,7 +706,7 @@ static void ftp_process_cmd (void) {
|
||||
fres = FR_NO_PATH;
|
||||
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
||||
ftp_open_child (ftp_path, ftp_scratch_buffer);
|
||||
if ((ftp_path[0] == '/' && ftp_path[1] == '\0') || ((fres = f_opendir (&ftp_data.dp, ftp_path)) == FR_OK)) {
|
||||
if ((ftp_path[0] == '/' && ftp_path[1] == '\0') || ((fres = f_opendir_helper (&ftp_data.dp, ftp_path)) == FR_OK)) {
|
||||
if (fres == FR_OK) {
|
||||
f_closedir(&ftp_data.dp);
|
||||
}
|
||||
@ -653,7 +725,7 @@ static void ftp_process_cmd (void) {
|
||||
case E_FTP_CMD_SIZE:
|
||||
{
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_stat (ftp_path, &fno)) {
|
||||
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
||||
// send the size
|
||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u", (_u32)fno.fsize);
|
||||
ftp_send_reply(213, (char *)ftp_data.dBuffer);
|
||||
@ -665,7 +737,7 @@ static void ftp_process_cmd (void) {
|
||||
break;
|
||||
case E_FTP_CMD_MDTM:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_stat (ftp_path, &fno)) {
|
||||
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
||||
// send the last modified time
|
||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u%02u%02u%02u%02u%02u",
|
||||
1980 + ((fno.fdate >> 9) & 0x7f), (fno.fdate >> 5) & 0x0f,
|
||||
@ -773,7 +845,7 @@ static void ftp_process_cmd (void) {
|
||||
case E_FTP_CMD_DELE:
|
||||
case E_FTP_CMD_RMD:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_unlink(ftp_path)) {
|
||||
if (FR_OK == f_unlink_helper(ftp_path)) {
|
||||
ftp_send_reply(250, NULL);
|
||||
}
|
||||
else {
|
||||
@ -782,7 +854,7 @@ static void ftp_process_cmd (void) {
|
||||
break;
|
||||
case E_FTP_CMD_MKD:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_mkdir(ftp_path)) {
|
||||
if (FR_OK == f_mkdir_helper(ftp_path)) {
|
||||
ftp_send_reply(250, NULL);
|
||||
}
|
||||
else {
|
||||
@ -791,7 +863,7 @@ static void ftp_process_cmd (void) {
|
||||
break;
|
||||
case E_FTP_CMD_RNFR:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
if (FR_OK == f_stat (ftp_path, &fno)) {
|
||||
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
||||
ftp_send_reply(350, NULL);
|
||||
// save the current path
|
||||
strcpy ((char *)ftp_data.dBuffer, ftp_path);
|
||||
@ -803,7 +875,7 @@ static void ftp_process_cmd (void) {
|
||||
case E_FTP_CMD_RNTO:
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
// old path was saved in the data buffer
|
||||
if (FR_OK == (fres = f_rename ((char *)ftp_data.dBuffer, ftp_path))) {
|
||||
if (FR_OK == (fres = f_rename_helper((char *)ftp_data.dBuffer, ftp_path))) {
|
||||
ftp_send_reply(250, NULL);
|
||||
}
|
||||
else {
|
||||
@ -898,24 +970,16 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
|
||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, const char *name) {
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t tseconds;
|
||||
char *type = "d";
|
||||
@ -934,7 +998,7 @@ static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
|
||||
}
|
||||
|
||||
static bool ftp_open_file (const char *path, int mode) {
|
||||
FRESULT res = f_open(&ftp_data.fp, path, mode);
|
||||
FRESULT res = f_open_helper(&ftp_data.fp, path, mode);
|
||||
if (res != FR_OK) {
|
||||
return false;
|
||||
}
|
||||
@ -976,7 +1040,7 @@ static ftp_result_t ftp_open_dir_for_listing (const char *path) {
|
||||
ftp_data.listroot = true;
|
||||
} else {
|
||||
FRESULT res;
|
||||
res = f_opendir(&ftp_data.dp, path); /* Open the directory */
|
||||
res = f_opendir_helper(&ftp_data.dp, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
return E_FTP_RESULT_FAILED;
|
||||
}
|
||||
@ -993,9 +1057,6 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
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 2 directory items
|
||||
while (listcount < 2) {
|
||||
#else
|
||||
@ -1004,17 +1065,20 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
#endif
|
||||
if (ftp_data.listroot) {
|
||||
// root directory "hack"
|
||||
if (0 == ftp_data.volcount) {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
|
||||
} else if (ftp_data.volcount <= MP_STATE_PORT(mount_obj_list).len) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[(ftp_data.volcount - 1)]));
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), (char *)&mount_obj->path[1]);
|
||||
} else {
|
||||
mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);
|
||||
int i = ftp_data.volcount;
|
||||
while (vfs != NULL && i != 0) {
|
||||
vfs = vfs->next;
|
||||
i -= 1;
|
||||
}
|
||||
if (vfs == NULL) {
|
||||
if (!next) {
|
||||
// no volume found this time, we are done
|
||||
ftp_data.volcount = 0;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), vfs->str + 1);
|
||||
}
|
||||
ftp_data.volcount++;
|
||||
} else {
|
||||
@ -1036,9 +1100,6 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
ftp_close_files();
|
||||
}
|
||||
*listsize = next;
|
||||
#if _USE_LFN
|
||||
mem_Free(fno.lfname);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -113,14 +113,3 @@ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
|
||||
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
}
|
||||
|
||||
// the following is temporay, until cc3200 converts to oofatfs
|
||||
|
||||
#include "py/lexer.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
return fat_vfs_import_stat(NULL, path);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, fatfs_builtin_open);
|
||||
|
@ -33,10 +33,12 @@
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "moduos.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "random.h"
|
||||
#include "mpexception.h"
|
||||
@ -59,155 +61,20 @@
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC uint32_t os_num_mounted_devices;
|
||||
STATIC os_term_dup_obj_t os_term_dup_obj;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void unmount (os_fs_mount_t *mount_obj);
|
||||
STATIC bool path_equal(const char *path, const char *path_canonical);
|
||||
STATIC void append_dir_item (mp_obj_t dirlist, const char *item, bool string);
|
||||
STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonly);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
void moduos_init0 (void) {
|
||||
// initialize the mount objects list
|
||||
mp_obj_list_init(&MP_STATE_PORT(mount_obj_list), 0);
|
||||
os_num_mounted_devices = 0;
|
||||
}
|
||||
|
||||
os_fs_mount_t *osmount_find_by_path (const char *path) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (!strcmp(path, mount_obj->path)) {
|
||||
return mount_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (vol == mount_obj->vol) {
|
||||
return mount_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_fs_mount_t *osmount_find_by_device (mp_obj_t device) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (device == mount_obj->device) {
|
||||
return mount_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void osmount_unmount_all (void) {
|
||||
//TODO
|
||||
/*
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
unmount(mount_obj);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
// 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';
|
||||
}
|
||||
|
||||
STATIC void append_dir_item (mp_obj_t dirlist, const char *item, bool string) {
|
||||
// make a string object for this entry
|
||||
mp_obj_t entry_o;
|
||||
if (string) {
|
||||
entry_o = mp_obj_new_str(item, strlen(item), false);
|
||||
} else {
|
||||
entry_o = mp_obj_new_bytes((const byte*)item, strlen(item));
|
||||
}
|
||||
|
||||
// add the entry to the list
|
||||
mp_obj_list_append(dirlist, entry_o);
|
||||
}
|
||||
|
||||
STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonly) {
|
||||
// is the mount point already in use?
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
// cannot mount twice or on existing paths
|
||||
if (f_stat(path, &fno) == FR_OK || osmount_find_by_device(device)) {
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
|
||||
}
|
||||
|
||||
// create a new object
|
||||
os_fs_mount_t *self = m_new_obj(os_fs_mount_t);
|
||||
self->device = device;
|
||||
self->path = path;
|
||||
self->pathlen = pathlen;
|
||||
self->vol = os_num_mounted_devices + 1; // '/flash' is volume 0
|
||||
|
||||
if (device == (mp_obj_t)&pybsd_obj) {
|
||||
// need to make it different to NULL, otherwise it's read only by default
|
||||
self->writeblocks[0] = mp_const_none;
|
||||
self->sync[0] = MP_OBJ_NULL; // no need to sync the SD card
|
||||
self->count[0] = MP_OBJ_NULL;
|
||||
} else {
|
||||
// load block protocol methods
|
||||
mp_load_method(device, MP_QSTR_readblocks, self->readblocks);
|
||||
mp_load_method_maybe(device, MP_QSTR_writeblocks, self->writeblocks);
|
||||
mp_load_method_maybe(device, MP_QSTR_sync, self->sync);
|
||||
mp_load_method(device, MP_QSTR_count, self->count);
|
||||
}
|
||||
|
||||
// Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
|
||||
// User can specify read-only device by:
|
||||
// 1. readonly=True keyword argument
|
||||
// 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already)
|
||||
if (readonly) {
|
||||
self->writeblocks[0] = MP_OBJ_NULL;
|
||||
}
|
||||
|
||||
// we need to add it before doing the actual mount, so that the volume can be found
|
||||
mp_obj_list_append(&MP_STATE_PORT(mount_obj_list), self);
|
||||
|
||||
// actually mount it
|
||||
if (f_mount(&self->fatfs, self->path, 1) != FR_OK) {
|
||||
// remove it and raise
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), self);
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
||||
}
|
||||
|
||||
// mount succeeded, increment the count
|
||||
os_num_mounted_devices++;
|
||||
}
|
||||
|
||||
STATIC void unmount (os_fs_mount_t *mount_obj) {
|
||||
// remove it from the list and then call FatFs
|
||||
f_mount (NULL, mount_obj->path, 1);
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), mount_obj);
|
||||
os_num_mounted_devices--;
|
||||
*/
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -239,193 +106,6 @@ 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) {
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
bool is_str_type = true;
|
||||
const char *path;
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
|
||||
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 the root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
// add 'flash' to the list
|
||||
append_dir_item (dir_list, "flash", is_str_type);
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
append_dir_item (dir_list, &mount_obj->path[1], is_str_type);
|
||||
}
|
||||
} else {
|
||||
FRESULT res;
|
||||
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) {
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
||||
}
|
||||
|
||||
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 */
|
||||
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
|
||||
|
||||
// add the entry to the list
|
||||
append_dir_item (dir_list, fn, is_str_type);
|
||||
}
|
||||
f_closedir(&dir);
|
||||
}
|
||||
|
||||
return dir_list;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
|
||||
|
||||
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:
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
|
||||
break;
|
||||
default:
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
|
||||
|
||||
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);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
|
||||
|
||||
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
FRESULT res = f_unlink(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
|
||||
|
||||
STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
||||
const char *path = mp_obj_str_get_str(path_in);
|
||||
bool isbuilt_in = false;
|
||||
FILINFO fno;
|
||||
FRESULT res;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
// check on the user mounted devices
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (path_equal(path, mount_obj->path)) {
|
||||
isbuilt_in = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (path_equal(path, "/") || path_equal(path, "/flash") || isbuilt_in) {
|
||||
// stat built-in directory
|
||||
fno.fsize = 0;
|
||||
fno.fdate = 0;
|
||||
fno.ftime = 0;
|
||||
fno.fattrib = AM_DIR;
|
||||
} else if ((res = f_stat(path, &fno)) != 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_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_int(fno.fsize); // st_size
|
||||
t->items[7] = mp_obj_new_int(seconds); // st_atime
|
||||
t->items[8] = t->items[7]; // st_mtime
|
||||
t->items[9] = t->items[7]; // st_ctime
|
||||
return t;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
||||
|
||||
STATIC mp_obj_t os_sync(void) {
|
||||
sflash_disk_flush();
|
||||
return mp_const_none;
|
||||
@ -443,110 +123,6 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||
|
||||
STATIC mp_obj_t os_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t mount_args[] = {
|
||||
{ MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_obj_t device = pos_args[0];
|
||||
mp_obj_t mount_point = pos_args[1];
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(mount_args)];
|
||||
mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(mount_args), mount_args, args);
|
||||
|
||||
// get the mount point
|
||||
mp_uint_t pathlen;
|
||||
const char *path_in = mp_obj_str_get_data(mount_point, &pathlen);
|
||||
if (pathlen == 0) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
char *path = m_new(char, pathlen + 1);
|
||||
memcpy(path, path_in, pathlen);
|
||||
path[pathlen] = '\0';
|
||||
|
||||
// "remove" any extra slahes at the end
|
||||
while (path[(pathlen - 1)] == '/') {
|
||||
path[--pathlen] = '\0';
|
||||
}
|
||||
|
||||
// is the mount point valid?
|
||||
if (pathlen < 2 || path[0] !='/' || strchr(&path[1], '/')) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// now mount it
|
||||
mount(device, path, pathlen, args[0].u_bool);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_value_invalid_arguments);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(os_mount_obj, 2, os_mount);
|
||||
|
||||
STATIC mp_obj_t os_unmount(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
|
||||
// '/flash' cannot be unmounted, also not the current working directory
|
||||
if (path_equal(path, "/flash")) {
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
|
||||
}
|
||||
|
||||
// now unmount it
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_path(path))) {
|
||||
unmount (mount_obj);
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, mpexception_value_invalid_arguments);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_unmount_obj, os_unmount);
|
||||
|
||||
STATIC mp_obj_t os_mkfs(mp_obj_t device) {
|
||||
const char *path = "/__mkfs__mnt__";
|
||||
os_fs_mount_t *mount_obj = NULL;
|
||||
bool unmt = false;
|
||||
FRESULT res;
|
||||
|
||||
if (MP_OBJ_IS_STR_OR_BYTES(device)) {
|
||||
path = mp_obj_str_get_str(device);
|
||||
// otherwise the relative path check will pass...
|
||||
if (path[0] != '/') {
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_value_invalid_arguments);
|
||||
}
|
||||
} else {
|
||||
// mount it briefly
|
||||
mount(device, path, strlen(path), false);
|
||||
unmt = true;
|
||||
}
|
||||
|
||||
byte sfd = 0;
|
||||
if (!memcmp(path, "/flash", strlen("/flash"))) {
|
||||
sfd = 1;
|
||||
} else if ((mount_obj = osmount_find_by_path(path))) {
|
||||
if (mount_obj->device != (mp_obj_t)&pybsd_obj &&
|
||||
mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count)) < 2048) {
|
||||
sfd = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// now format the device
|
||||
res = f_mkfs(path, sfd, 0);
|
||||
|
||||
if (unmt && mount_obj) {
|
||||
unmount (mount_obj);
|
||||
}
|
||||
|
||||
if (res != FR_OK) {
|
||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkfs_obj, os_mkfs);
|
||||
|
||||
STATIC mp_obj_t os_dupterm(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
if (MP_STATE_PORT(os_term_dup_obj) == MP_OBJ_NULL) {
|
||||
@ -576,22 +152,26 @@ STATIC const mp_map_elem_t os_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
|
||||
|
||||
{ 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_rename), (mp_obj_t)&os_rename_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_remove_obj }, // rmdir aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_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_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_rename), (mp_obj_t)&mp_vfs_rename_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&mp_vfs_remove_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_unlink), (mp_obj_t)&mp_vfs_remove_obj }, // unlink aliases to remove
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||
|
||||
// MicroPython additions
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&os_mount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&os_unmount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&os_mkfs_obj },
|
||||
// removed: mkfs
|
||||
// renamed: unmount -> umount
|
||||
{ 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 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_dupterm), (mp_obj_t)&os_dupterm_obj },
|
||||
|
||||
/// \constant sep - separation character used in paths
|
||||
|
@ -28,22 +28,11 @@
|
||||
#ifndef MODUOS_H_
|
||||
#define MODUOS_H_
|
||||
|
||||
#include "ff.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC TYPES
|
||||
******************************************************************************/
|
||||
typedef struct _os_fs_mount_t {
|
||||
mp_obj_t device;
|
||||
const char *path;
|
||||
mp_uint_t pathlen;
|
||||
mp_obj_t readblocks[4];
|
||||
mp_obj_t writeblocks[4];
|
||||
mp_obj_t sync[2];
|
||||
mp_obj_t count[2];
|
||||
FATFS fatfs;
|
||||
uint8_t vol;
|
||||
} os_fs_mount_t;
|
||||
|
||||
typedef struct _os_term_dup_obj_t {
|
||||
mp_obj_t stream_o;
|
||||
@ -54,9 +43,6 @@ typedef struct _os_term_dup_obj_t {
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void moduos_init0 (void);
|
||||
os_fs_mount_t *osmount_find_by_path (const char *path);
|
||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol);
|
||||
void osmount_unmount_all (void);
|
||||
|
||||
#endif // MODUOS_H_
|
||||
|
110
cc3200/mods/pybflash.c
Normal file
110
cc3200/mods/pybflash.c
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2017 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 <stdint.h>
|
||||
//#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "extmod/fsusermount.h"
|
||||
|
||||
#include "fatfs/src/drivers/sflash_diskio.h"
|
||||
#include "mods/pybflash.h"
|
||||
|
||||
/******************************************************************************/
|
||||
// MicroPython bindings to expose the internal flash as an object with the
|
||||
// block protocol.
|
||||
|
||||
// there is a singleton Flash object
|
||||
STATIC const mp_obj_base_t pyb_flash_obj = {&pyb_flash_type};
|
||||
|
||||
STATIC mp_obj_t pyb_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
|
||||
// return singleton object
|
||||
return (mp_obj_t)&pyb_flash_obj;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_flash_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
|
||||
DRESULT res = sflash_disk_read(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SFLASH_SECTOR_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_readblocks_obj, pyb_flash_readblocks);
|
||||
|
||||
STATIC mp_obj_t pyb_flash_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||
DRESULT res = sflash_disk_write(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SFLASH_SECTOR_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_writeblocks_obj, pyb_flash_writeblocks);
|
||||
|
||||
STATIC mp_obj_t pyb_flash_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
||||
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
||||
switch (cmd) {
|
||||
case BP_IOCTL_INIT: return MP_OBJ_NEW_SMALL_INT(sflash_disk_init() != RES_OK);
|
||||
case BP_IOCTL_DEINIT: sflash_disk_flush(); return MP_OBJ_NEW_SMALL_INT(0);
|
||||
case BP_IOCTL_SYNC: sflash_disk_flush(); return MP_OBJ_NEW_SMALL_INT(0);
|
||||
case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(SFLASH_SECTOR_COUNT);
|
||||
case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(SFLASH_SECTOR_SIZE);
|
||||
default: return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_ioctl_obj, pyb_flash_ioctl);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_flash_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_flash_readblocks_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_flash_writeblocks_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_flash_ioctl_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_flash_locals_dict, pyb_flash_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_flash_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Flash,
|
||||
.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->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)sflash_disk_read; // 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)sflash_disk_write; // native version
|
||||
vfs->u.ioctl[0] = (mp_obj_t)&pyb_flash_ioctl_obj;
|
||||
vfs->u.ioctl[1] = (mp_obj_t)&pyb_flash_obj;
|
||||
}
|
35
cc3200/mods/pybflash.h
Normal file
35
cc3200/mods/pybflash.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBFLASH_H
|
||||
#define MICROPY_INCLUDED_CC3200_MODS_PYBFLASH_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
extern const mp_obj_type_t pyb_flash_type;
|
||||
|
||||
void pyb_flash_init_vfs(fs_user_mount_t *vfs);
|
||||
|
||||
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBFLASH_H
|
@ -27,6 +27,9 @@
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "extmod/fsusermount.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
#include "inc/hw_ints.h"
|
||||
@ -36,8 +39,6 @@
|
||||
#include "prcm.h"
|
||||
#include "gpio.h"
|
||||
#include "sdhost.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "pybsd.h"
|
||||
#include "mpexception.h"
|
||||
@ -163,9 +164,50 @@ STATIC mp_obj_t pyb_sd_deinit (mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sd_deinit_obj, pyb_sd_deinit);
|
||||
|
||||
STATIC mp_obj_t pyb_sd_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
|
||||
DRESULT res = sd_disk_read(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SD_SECTOR_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sd_readblocks_obj, pyb_sd_readblocks);
|
||||
|
||||
STATIC mp_obj_t pyb_sd_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||
DRESULT res = sd_disk_write(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SD_SECTOR_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sd_writeblocks_obj, pyb_sd_writeblocks);
|
||||
|
||||
STATIC mp_obj_t pyb_sd_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
||||
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
||||
switch (cmd) {
|
||||
case BP_IOCTL_INIT:
|
||||
case BP_IOCTL_DEINIT:
|
||||
case BP_IOCTL_SYNC:
|
||||
// nothing to do
|
||||
return MP_OBJ_NEW_SMALL_INT(0); // success
|
||||
|
||||
case BP_IOCTL_SEC_COUNT:
|
||||
return MP_OBJ_NEW_SMALL_INT(sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512));
|
||||
|
||||
case BP_IOCTL_SEC_SIZE:
|
||||
return MP_OBJ_NEW_SMALL_INT(SD_SECTOR_SIZE);
|
||||
|
||||
default: // unknown command
|
||||
return MP_OBJ_NEW_SMALL_INT(-1); // error
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sd_ioctl_obj, pyb_sd_ioctl);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_sd_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_sd_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_sd_deinit_obj },
|
||||
// block device protocol
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_sd_readblocks_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_sd_writeblocks_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_sd_ioctl_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_sd_locals_dict, pyb_sd_locals_dict_table);
|
||||
|
@ -55,7 +55,7 @@
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
#define MICROPY_OPT_COMPUTED_GOTO (0)
|
||||
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
|
||||
#define MICROPY_READER_FATFS (1)
|
||||
#define MICROPY_READER_VFS (1)
|
||||
#ifndef DEBUG // we need ram on the launchxl while debugging
|
||||
#define MICROPY_CPYTHON_COMPAT (1)
|
||||
#else
|
||||
@ -64,19 +64,20 @@
|
||||
#define MICROPY_QSTR_BYTES_IN_HASH (1)
|
||||
|
||||
// fatfs configuration used in ffconf.h
|
||||
#define MICROPY_FATFS_OO (1)
|
||||
#define MICROPY_FATFS_ENABLE_LFN (2)
|
||||
#define MICROPY_FATFS_MAX_LFN (MICROPY_ALLOC_PATH_MAX)
|
||||
#define MICROPY_FATFS_LFN_CODE_PAGE (437) // 1=SFN/ANSI 437=LFN/U.S.(OEM)
|
||||
#define MICROPY_FATFS_RPATH (2)
|
||||
#define MICROPY_FATFS_VOLUMES (2)
|
||||
#define MICROPY_FATFS_REENTRANT (1)
|
||||
#define MICROPY_FATFS_TIMEOUT (2500)
|
||||
#define MICROPY_FATFS_SYNC_T SemaphoreHandle_t
|
||||
#define MICROPY_FSUSERMOUNT_ADHOC (1)
|
||||
|
||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_VFS (1)
|
||||
#define MICROPY_VFS_FAT (1)
|
||||
#define MICROPY_PY_ASYNC_AWAIT (0)
|
||||
#define MICROPY_PY_BUILTINS_TIMEOUTERROR (1)
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
|
||||
@ -120,6 +121,15 @@
|
||||
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
||||
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)
|
||||
|
||||
// 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 \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
|
||||
@ -174,7 +184,6 @@ extern const struct _mp_obj_module_t mp_module_ussl;
|
||||
mp_obj_list_t pyb_sleep_obj_list; \
|
||||
mp_obj_list_t mp_irq_obj_list; \
|
||||
mp_obj_list_t pyb_timer_channel_obj_list; \
|
||||
mp_obj_list_t mount_obj_list; \
|
||||
struct _pyb_uart_obj_t *pyb_uart_objs[2]; \
|
||||
struct _os_term_dup_obj_t *os_term_dup_obj; \
|
||||
|
||||
|
@ -33,6 +33,10 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include "extmod/fsusermount.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
@ -56,13 +60,12 @@
|
||||
#include "serverstask.h"
|
||||
#include "telnet.h"
|
||||
#include "debug.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "mpexception.h"
|
||||
#include "random.h"
|
||||
#include "pybi2c.h"
|
||||
#include "pins.h"
|
||||
#include "mods/pybflash.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pybtimer.h"
|
||||
#include "cryptohash.h"
|
||||
@ -94,7 +97,8 @@ OsiTaskHandle svTaskHandle;
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
static FATFS *sflash_fatfs;
|
||||
static fs_user_mount_t *sflash_vfs_fat;
|
||||
static mp_vfs_mount_t sflash_vfs_mount;
|
||||
|
||||
static const char fresh_main_py[] = "# main.py -- put your code here!\r\n";
|
||||
static const char fresh_boot_py[] = "# boot.py -- run on boot-up\r\n"
|
||||
@ -149,7 +153,6 @@ soft_reset:
|
||||
timer_init0();
|
||||
readline_init0();
|
||||
mod_network_init0();
|
||||
moduos_init0();
|
||||
rng_init0();
|
||||
|
||||
pybsleep_reset_cause_t rstcause = pyb_sleep_get_reset_cause();
|
||||
@ -270,7 +273,7 @@ STATIC void mptask_pre_init (void) {
|
||||
ASSERT (OSI_OK == VStartSimpleLinkSpawnTask(SIMPLELINK_SPAWN_TASK_PRIORITY));
|
||||
|
||||
// Allocate memory for the flash file system
|
||||
ASSERT ((sflash_fatfs = mem_Malloc(sizeof(FATFS))) != NULL);
|
||||
ASSERT ((sflash_vfs_fat = mem_Malloc(sizeof(*sflash_vfs_fat))) != NULL);
|
||||
|
||||
// this one allocates memory for the nvic vault
|
||||
pyb_sleep_pre_init();
|
||||
@ -296,17 +299,21 @@ 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.
|
||||
// init the vfs object
|
||||
fs_user_mount_t *vfs_fat = sflash_vfs_fat;
|
||||
vfs_fat->str = NULL;
|
||||
vfs_fat->len = 0;
|
||||
vfs_fat->flags = 0;
|
||||
pyb_flash_init_vfs(vfs_fat);
|
||||
|
||||
// Create it if needed, and mount in on /flash.
|
||||
FRESULT res = f_mount(sflash_fatfs, "/flash", 1);
|
||||
FRESULT res = f_mount(&vfs_fat->fatfs);
|
||||
if (res == FR_NO_FILESYSTEM) {
|
||||
// no filesystem, so create a fresh one
|
||||
res = f_mkfs("/flash", 1, 0);
|
||||
uint8_t working_buf[_MAX_SS];
|
||||
res = f_mkfs(&vfs_fat->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf));
|
||||
if (res == FR_OK) {
|
||||
// success creating fresh LFS
|
||||
} else {
|
||||
@ -316,7 +323,7 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
mptask_create_main_py();
|
||||
} else if (res == FR_OK) {
|
||||
// mount sucessful
|
||||
if (FR_OK != f_stat("/flash/main.py", &fno)) {
|
||||
if (FR_OK != f_stat(&vfs_fat->fatfs, "/main.py", &fno)) {
|
||||
// create empty main.py
|
||||
mptask_create_main_py();
|
||||
}
|
||||
@ -324,25 +331,33 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
__fatal_error("failed to create /flash");
|
||||
}
|
||||
|
||||
// mount the flash device (there should be no other devices mounted at this point)
|
||||
mp_vfs_mount_t *vfs = &sflash_vfs_mount;
|
||||
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;
|
||||
|
||||
// create /flash/sys, /flash/lib and /flash/cert if they don't exist
|
||||
if (FR_OK != f_chdir ("/flash/sys")) {
|
||||
f_mkdir("/flash/sys");
|
||||
if (FR_OK != f_chdir(&vfs_fat->fatfs, "/sys")) {
|
||||
f_mkdir(&vfs_fat->fatfs, "/sys");
|
||||
}
|
||||
if (FR_OK != f_chdir ("/flash/lib")) {
|
||||
f_mkdir("/flash/lib");
|
||||
if (FR_OK != f_chdir(&vfs_fat->fatfs, "/lib")) {
|
||||
f_mkdir(&vfs_fat->fatfs, "/lib");
|
||||
}
|
||||
if (FR_OK != f_chdir ("/flash/cert")) {
|
||||
f_mkdir("/flash/cert");
|
||||
if (FR_OK != f_chdir(&vfs_fat->fatfs, "/cert")) {
|
||||
f_mkdir(&vfs_fat->fatfs, "/cert");
|
||||
}
|
||||
|
||||
f_chdir ("/flash");
|
||||
f_chdir(&vfs_fat->fatfs, "/");
|
||||
|
||||
// make sure we have a /flash/boot.py. Create it if needed.
|
||||
res = f_stat("/flash/boot.py", &fno);
|
||||
res = f_stat(&vfs_fat->fatfs, "/boot.py", &fno);
|
||||
if (res == FR_OK) {
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
// exists as a directory
|
||||
@ -354,7 +369,7 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
} else {
|
||||
// doesn't exist, create fresh file
|
||||
FIL fp;
|
||||
f_open(&fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_open(&vfs_fat->fatfs, &fp, "/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
|
||||
@ -374,9 +389,8 @@ STATIC void mptask_enter_ap_mode (void) {
|
||||
STATIC void mptask_create_main_py (void) {
|
||||
// create empty main.py
|
||||
FIL fp;
|
||||
f_open(&fp, "/flash/main.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_open(&sflash_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);
|
||||
f_close(&fp);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user