summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott.shawcroft@gmail.com>2017-06-26 14:04:22 -0700
committerScott Shawcroft <scott.shawcroft@gmail.com>2017-06-26 14:04:22 -0700
commite87a61ffb4ad089b7eb5eb4512cb57c085fd9136 (patch)
treea464a1d4f4627015450ba4d1285c476bc76f6a45
parent8251d8cb2a408a4493395b8a2ee87cc11fcdfc3e (diff)
atmel-samd: Fix running off of the new VFS filesystem including
an issue at startup leading to safe mode and mass storage support not working.
-rw-r--r--atmel-samd/access_vfs.c65
-rw-r--r--atmel-samd/access_vfs.h1
-rw-r--r--atmel-samd/main.c20
-rw-r--r--atmel-samd/spi_flash.c3
-rw-r--r--py/runtime.c17
5 files changed, 56 insertions, 50 deletions
diff --git a/atmel-samd/access_vfs.c b/atmel-samd/access_vfs.c
index 72b56526b..5dc47a7a1 100644
--- a/atmel-samd/access_vfs.c
+++ b/atmel-samd/access_vfs.c
@@ -42,6 +42,17 @@
#define VFS_INDEX 0
+static fs_user_mount_t* get_vfs(int index) {
+ mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
+ for (uint8_t i = 0; current_mount != NULL; i++) {
+ if (i == VFS_INDEX) {
+ return (fs_user_mount_t *) current_mount->obj;
+ }
+ current_mount = current_mount->next;
+ }
+ return NULL;
+}
+
//! This function tests memory state, and starts memory initialization
//! @return Ctrl_status
//! It is ready -> CTRL_GOOD
@@ -50,12 +61,9 @@
//! An error occurred -> CTRL_FAIL
Ctrl_status vfs_test_unit_ready(void)
{
- mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
- for (uint8_t i = 0; current_mount != NULL; i++) {
- if (i == VFS_INDEX) {
- return CTRL_GOOD;
- }
- current_mount = current_mount->next;
+ fs_user_mount_t* current_mount = get_vfs(VFS_INDEX);
+ if (current_mount != NULL) {
+ return CTRL_GOOD;
}
return CTRL_NO_PRESENT;
}
@@ -69,7 +77,9 @@ Ctrl_status vfs_test_unit_ready(void)
//! An error occurred -> CTRL_FAIL
Ctrl_status vfs_read_capacity(uint32_t *last_valid_sector)
{
- if (disk_ioctl(VFS_INDEX, GET_SECTOR_COUNT, last_valid_sector) != RES_OK) {
+ fs_user_mount_t * vfs = get_vfs(VFS_INDEX);
+ if (vfs == NULL ||
+ disk_ioctl(vfs, GET_SECTOR_COUNT, last_valid_sector) != RES_OK) {
return CTRL_FAIL;
}
// Subtract one from the sector count to get the last valid sector.
@@ -83,20 +93,9 @@ Ctrl_status vfs_read_capacity(uint32_t *last_valid_sector)
//!
bool vfs_wr_protect(void)
{
- mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
- for (uint8_t i = 0; current_mount != NULL; i++) {
- if (i == VFS_INDEX) {
- break;
- }
- current_mount = current_mount->next;
- }
- if (current_mount == NULL) {
- return true;
- }
- fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj;
-
+ fs_user_mount_t * vfs = get_vfs(VFS_INDEX);
// This is used to determine the writeability of the disk from USB.
- if (vfs->writeblocks[0] == MP_OBJ_NULL ||
+ if (vfs == NULL || vfs->writeblocks[0] == MP_OBJ_NULL ||
(vfs->flags & FSUSER_USB_WRITEABLE) == 0) {
return true;
}
@@ -112,11 +111,6 @@ bool vfs_removal(void)
return true;
}
-bool vfs_unload(bool unload)
-{
- return unload;
-}
-
// TODO(tannewt): Transfer more than a single sector at a time if we need more
// speed.
//! This function transfers the memory data to the USB MSC interface
@@ -132,9 +126,10 @@ bool vfs_unload(bool unload)
//!
Ctrl_status vfs_usb_read_10(uint32_t addr, volatile uint16_t nb_sector)
{
+ fs_user_mount_t * vfs = get_vfs(VFS_INDEX);
uint8_t sector_buffer[FILESYSTEM_BLOCK_SIZE];
for (uint16_t sector = 0; sector < nb_sector; sector++) {
- DRESULT result = disk_read(VFS_INDEX, sector_buffer, addr + sector, 1);
+ DRESULT result = disk_read(vfs, sector_buffer, addr + sector, 1);
if (result == RES_PARERR) {
return CTRL_NO_PRESENT;
}
@@ -161,13 +156,17 @@ Ctrl_status vfs_usb_read_10(uint32_t addr, volatile uint16_t nb_sector)
//!
Ctrl_status vfs_usb_write_10(uint32_t addr, volatile uint16_t nb_sector)
{
+ if (vfs_wr_protect()) {
+ return CTRL_FAIL;
+ }
+ fs_user_mount_t * vfs = get_vfs(VFS_INDEX);
uint8_t sector_buffer[FILESYSTEM_BLOCK_SIZE];
for (uint16_t sector = 0; sector < nb_sector; sector++) {
if (!udi_msc_trans_block(false, sector_buffer, FILESYSTEM_BLOCK_SIZE, NULL)) {
return CTRL_FAIL; // transfer aborted
}
uint32_t sector_address = addr + sector;
- DRESULT result = disk_write(VFS_INDEX, sector_buffer, sector_address, 1);
+ DRESULT result = disk_write(vfs, sector_buffer, sector_address, 1);
if (result == RES_PARERR) {
return CTRL_NO_PRESENT;
}
@@ -176,18 +175,6 @@ Ctrl_status vfs_usb_write_10(uint32_t addr, volatile uint16_t nb_sector)
}
// Since by getting here we assume the mount is read-only to MicroPython
// lets update the cached FatFs sector if its the one we just wrote.
- mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
- for (uint8_t i = 0; current_mount != NULL; i++) {
- if (i == VFS_INDEX) {
- break;
- }
- current_mount = current_mount->next;
- }
- if (current_mount == NULL) {
- return CTRL_NO_PRESENT;
- }
- fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj;
-
#if _MAX_SS != _MIN_SS
if (vfs->ssize == FILESYSTEM_BLOCK_SIZE) {
#else
diff --git a/atmel-samd/access_vfs.h b/atmel-samd/access_vfs.h
index 07af89e22..c1cd635fc 100644
--- a/atmel-samd/access_vfs.h
+++ b/atmel-samd/access_vfs.h
@@ -36,7 +36,6 @@ Ctrl_status vfs_test_unit_ready(void);
Ctrl_status vfs_read_capacity(uint32_t *u32_nb_sector);
bool vfs_wr_protect(void);
bool vfs_removal(void);
-bool vfs_unload(bool);
Ctrl_status vfs_usb_read_10(uint32_t addr, uint16_t nb_sector);
Ctrl_status vfs_usb_write_10(uint32_t addr, uint16_t nb_sector);
diff --git a/atmel-samd/main.c b/atmel-samd/main.c
index 1f3c3405c..1a0ee9dca 100644
--- a/atmel-samd/main.c
+++ b/atmel-samd/main.c
@@ -104,10 +104,7 @@ void init_flash_fs(void) {
} else if (res != FR_OK) {
return;
}
- mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
- if (vfs == NULL) {
- return;
- }
+ mp_vfs_mount_t *vfs = &mp_vfs_mount_flash;
vfs->str = "/";
vfs->len = 1;
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
@@ -584,9 +581,6 @@ int main(void) {
mp_stack_ctrl_init();
mp_stack_set_limit((char*)&_estack - (char*)&_ebss - 1024);
- // Initialise the local flash filesystem after the gc in case we need to
- // grab memory from it. Create it if needed, mount in on /flash, and set it
- // as current dir.
init_flash_fs();
// Reset everything and prep MicroPython to run boot.py.
@@ -599,7 +593,7 @@ int main(void) {
// If not in safe mode, run boot before initing USB and capture output in a
// file.
- if (safe_mode == NO_SAFE_MODE) {
+ if (safe_mode == NO_SAFE_MODE && MP_STATE_VM(vfs_mount_table) != NULL) {
new_status_color(BOOT_RUNNING);
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
FIL file_pointer;
@@ -680,6 +674,10 @@ void gc_collect(void) {
// pointers from CPU registers, and thus may function incorrectly.
void *dummy;
gc_collect_start();
+ // This collects root pointers from the first VFS entry which is statically
+ // allocated. This way we can do VFS operations prior to setting up the heap.
+ // This also means it can be done once on boot and not repeatedly.
+ gc_collect_root((void**)&mp_vfs_mount_flash, sizeof(mp_vfs_mount_t) / sizeof(mp_uint_t));
// This naively collects all object references from an approximate stack
// range.
gc_collect_root(&dummy, ((mp_uint_t)&_estack - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
@@ -687,11 +685,13 @@ void gc_collect(void) {
}
void NORETURN nlr_jump_fail(void *val) {
- while (1);
+ HardFault_Handler();
+ while (true) {}
}
void NORETURN __fatal_error(const char *msg) {
- while (1);
+ HardFault_Handler();
+ while (true) {}
}
#ifndef NDEBUG
diff --git a/atmel-samd/spi_flash.c b/atmel-samd/spi_flash.c
index 7f3c8984c..bf1f190c8 100644
--- a/atmel-samd/spi_flash.c
+++ b/atmel-samd/spi_flash.c
@@ -662,7 +662,10 @@ const mp_obj_type_t spi_flash_type = {
};
void 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->fatfs.part = 1; // flash filesystem lives on first partition
vfs->readblocks[0] = (mp_obj_t)&spi_flash_obj_readblocks_obj;
vfs->readblocks[1] = (mp_obj_t)&spi_flash_obj;
vfs->readblocks[2] = (mp_obj_t)spi_flash_read_blocks; // native version
diff --git a/py/runtime.c b/py/runtime.c
index 5fe132ae7..504c17c15 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -29,6 +29,8 @@
#include <string.h>
#include <assert.h>
+#include "extmod/vfs.h"
+
#include "py/mpstate.h"
#include "py/nlr.h"
#include "py/parsenum.h"
@@ -114,10 +116,25 @@ void mp_init(void) {
#endif
#if MICROPY_VFS
+ #if MICROPY_FATFS_NUM_PERSISTENT > 0
+ mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);
+ if (vfs != NULL) {
+ MP_STATE_VM(vfs_cur) = vfs;
+ }
+ // Skip forward until the vfs->next pointer is the first vfs that shouldn't
+ // persist.
+ uint8_t i = 1;
+ while (vfs != NULL && i < MICROPY_FATFS_NUM_PERSISTENT) {
+ vfs = vfs->next;
+ i++;
+ }
+ vfs->next = NULL;
+ #else
// initialise the VFS sub-system
MP_STATE_VM(vfs_cur) = NULL;
MP_STATE_VM(vfs_mount_table) = NULL;
#endif
+ #endif
#if MICROPY_PY_THREAD_GIL
mp_thread_mutex_init(&MP_STATE_VM(gil_mutex));