summaryrefslogtreecommitdiff
path: root/supervisor/shared/filesystem.c
diff options
context:
space:
mode:
Diffstat (limited to 'supervisor/shared/filesystem.c')
-rw-r--r--supervisor/shared/filesystem.c84
1 files changed, 82 insertions, 2 deletions
diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c
index d968f4798..f6b94e38b 100644
--- a/supervisor/shared/filesystem.c
+++ b/supervisor/shared/filesystem.c
@@ -24,6 +24,8 @@
* THE SOFTWARE.
*/
+#include "supervisor/filesystem.h"
+
#include "extmod/vfs_fat.h"
#include "lib/oofatfs/ff.h"
#include "lib/oofatfs/diskio.h"
@@ -35,12 +37,51 @@
static mp_vfs_mount_t _mp_vfs;
static fs_user_mount_t _internal_vfs;
+static volatile uint32_t filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS;
+volatile bool filesystem_flush_requested = false;
+
+void filesystem_background(void) {
+ if (filesystem_flush_requested) {
+ filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS;
+ // Flush but keep caches
+ supervisor_flash_flush();
+ filesystem_flush_requested = false;
+ }
+}
+
+inline void filesystem_tick(void) {
+ if (filesystem_flush_interval_ms == 0) {
+ // 0 means not turned on.
+ return;
+ }
+ if (filesystem_flush_interval_ms == 1) {
+ filesystem_flush_requested = true;
+ filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS;
+ } else {
+ filesystem_flush_interval_ms--;
+ }
+}
+
+
static void make_empty_file(FATFS *fatfs, const char *path) {
FIL fp;
f_open(fatfs, &fp, path, FA_WRITE | FA_CREATE_ALWAYS);
f_close(&fp);
}
+
+static void make_sample_code_file(FATFS *fatfs) {
+ #if CIRCUITPY_FULL_BUILD
+ FIL fs;
+ UINT char_written = 0;
+ const byte buffer[] = "print('Hello World!')\n";
+ //Create or modify existing code.py file
+ f_open(fatfs, &fs, "/code.py", FA_WRITE | FA_CREATE_ALWAYS);
+ f_write(&fs, buffer, sizeof(buffer) - 1, &char_written);
+ f_close(&fs);
+ #endif
+}
+
// we don't make this function static because it needs a lot of stack and we
// want it to be executed without using stack within main() function
void filesystem_init(bool create_allowed, bool force_create) {
@@ -63,13 +104,22 @@ void filesystem_init(bool create_allowed, bool force_create) {
}
// set label
+#ifdef CIRCUITPY_DRIVE_LABEL
+ f_setlabel(&vfs_fat->fatfs, CIRCUITPY_DRIVE_LABEL);
+#else
f_setlabel(&vfs_fat->fatfs, "CIRCUITPY");
+#endif
// inhibit file indexing on MacOS
f_mkdir(&vfs_fat->fatfs, "/.fseventsd");
make_empty_file(&vfs_fat->fatfs, "/.metadata_never_index");
make_empty_file(&vfs_fat->fatfs, "/.Trashes");
make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log");
+ // make a sample code.py file
+ make_sample_code_file(&vfs_fat->fatfs);
+
+ // create empty lib directory
+ f_mkdir(&vfs_fat->fatfs, "/lib");
// and ensure everything is flushed
supervisor_flash_flush();
@@ -89,19 +139,49 @@ void filesystem_init(bool create_allowed, bool force_create) {
}
void filesystem_flush(void) {
+ // Reset interval before next flush.
+ filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS;
supervisor_flash_flush();
+ // Don't keep caches because this is called when starting or stopping the VM.
+ supervisor_flash_release_cache();
}
-void filesystem_writable_by_python(bool writable) {
+void filesystem_set_internal_writable_by_usb(bool writable) {
fs_user_mount_t *vfs = &_internal_vfs;
- if (writable) {
+ filesystem_set_writable_by_usb(vfs, writable);
+}
+
+void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable) {
+ if (usb_writable) {
vfs->flags |= FSUSER_USB_WRITABLE;
} else {
vfs->flags &= ~FSUSER_USB_WRITABLE;
}
}
+bool filesystem_is_writable_by_python(fs_user_mount_t *vfs) {
+ return (vfs->flags & FSUSER_CONCURRENT_WRITE_PROTECTED) == 0 ||
+ (vfs->flags & FSUSER_USB_WRITABLE) == 0;
+}
+
+bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs) {
+ return (vfs->flags & FSUSER_CONCURRENT_WRITE_PROTECTED) == 0 ||
+ (vfs->flags & FSUSER_USB_WRITABLE) != 0;
+}
+
+void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection) {
+ filesystem_set_concurrent_write_protection(&_internal_vfs, concurrent_write_protection);
+}
+
+void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection) {
+ if (concurrent_write_protection) {
+ vfs->flags |= FSUSER_CONCURRENT_WRITE_PROTECTED;
+ } else {
+ vfs->flags &= ~FSUSER_CONCURRENT_WRITE_PROTECTED;
+ }
+}
+
bool filesystem_present(void) {
return true;
}