Skip to content
Snippets Groups Projects
Commit 796e6d94 authored by q3k's avatar q3k
Browse files

st3m: implement dumb VFS for /

This allows us to os.listdir("/").
parent 08b05dab
No related branches found
No related tags found
No related merge requests found
...@@ -16,6 +16,7 @@ idf_component_register( ...@@ -16,6 +16,7 @@ idf_component_register(
st3m_captouch.c st3m_captouch.c
st3m_ringbuffer.c st3m_ringbuffer.c
st3m_tar.c st3m_tar.c
st3m_fs.c
INCLUDE_DIRS INCLUDE_DIRS
. .
REQUIRES REQUIRES
......
#include "st3m_fs.h"
#include "st3m_mode.h"
#include "st3m_sys_data.h"
#include "st3m_tar.h"
#include "esp_system.h"
#include "esp_vfs.h"
#include "esp_vfs_fat.h"
#include <errno.h>
static const char *TAG = "st3m-fs";
// Entries for root filesystem. Ideally this wouldn't be static but would
// consult the ESP-IDF VFS registry.
static struct dirent _root_dirents[4] = {
{ .d_ino = 1, .d_name = ".", .d_type = DT_DIR, },
{ .d_ino = 2, .d_name = "flash", .d_type = DT_DIR, },
{ .d_ino = 3, .d_name = "sd", .d_type = DT_DIR, },
{ .d_ino = 4, .d_name = "console", .d_type = DT_DIR, },
};
// Handle of the wear levelling library instance
static wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
static int _root_vfs_close(int fd) {
return 0;
}
static int _root_vfs_fcntl(int fd, int cmd, int arg) {
return 0;
}
static int _root_vfs_fstat(int fd, struct stat *st) {
st->st_mode = S_IFDIR;
return 0;
}
static int _root_vfs_open(const char *path, int flags, int mode) {
if (strcmp(path, "/") == 0) {
if (flags == 0) {
return 0;
}
errno = EISDIR;
} else {
errno = ENOENT;
}
return -1;
}
static ssize_t _root_vfs_read(int fd, void *data, size_t size) {
errno = EISDIR;
return -1;
}
static ssize_t _root_vfs_write(int fd, const void *data, size_t size) {
errno = EISDIR;
return -1;
}
typedef struct {
DIR _inner;
size_t ix;
} st3m_rootfs_dir_t;
static DIR *_root_vfs_opendir(const char *name) {
if (strcmp(name, "/") != 0) {
errno = ENOENT;
return NULL;
}
st3m_rootfs_dir_t *dir = calloc(1, sizeof(st3m_rootfs_dir_t));
assert(dir != NULL);
return (DIR*)dir;
}
static struct dirent *_root_vfs_readdir(DIR *pdir) {
st3m_rootfs_dir_t *dir = pdir;
if (dir->ix >= (sizeof(_root_dirents)/sizeof(struct dirent))) {
return NULL;
}
return &_root_dirents[dir->ix++];
}
static int _root_vfs_closedir(DIR *pdir) {
free(pdir);
return 0;
}
// Root filesystem implementation, because otherwise os.listdir("/") fails...
static esp_vfs_t _root_vfs = {
.flags = ESP_VFS_FLAG_DEFAULT,
.close = &_root_vfs_close,
.fcntl = &_root_vfs_fcntl,
.fstat = &_root_vfs_fstat,
.open = &_root_vfs_open,
.read = &_root_vfs_read,
.write = &_root_vfs_write,
.opendir = &_root_vfs_opendir,
.readdir = &_root_vfs_readdir,
.closedir = &_root_vfs_closedir,
};
void st3m_fs_init(void) {
esp_err_t err;
if ((err = esp_vfs_register("", &_root_vfs, NULL)) != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount root VFS: %s", esp_err_to_name(err));
return;
}
const esp_vfs_fat_mount_config_t mount_config = {
.max_files = 4,
.format_if_mount_failed = true,
.allocation_unit_size = CONFIG_WL_SECTOR_SIZE
};
err = esp_vfs_fat_spiflash_mount("/flash", "vfs", &mount_config,
&s_wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount FAT FS: %s", esp_err_to_name(err));
return;
}
ESP_LOGI(TAG, "Mounted Flash VFS Partition at /flash");
}
#pragma once
// Mount filesystem. An error will be loged if the mount failed.
//
// Filesystem layout:
// /flash - FAT from flash ('vfat' partition, wear leveled)
// /sd - FAT from SD card, if available
//
// This function must not be called more than once.
void st3m_fs_init(void);
\ No newline at end of file
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "st3m_mode.h" #include "st3m_mode.h"
#include "st3m_sys_data.h" #include "st3m_sys_data.h"
#include "st3m_tar.h" #include "st3m_tar.h"
#include "st3m_fs.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_vfs.h" #include "esp_vfs.h"
...@@ -38,24 +39,8 @@ static void _extract_sys_data(void) { ...@@ -38,24 +39,8 @@ static void _extract_sys_data(void) {
fclose(f); fclose(f);
} }
// Handle of the wear levelling library instance void flow3r_fs_init(void) {
static wl_handle_t s_wl_handle = WL_INVALID_HANDLE; st3m_fs_init();
void st3m_fs_init(void) {
const esp_vfs_fat_mount_config_t mount_config = {
.max_files = 4,
.format_if_mount_failed = true,
.allocation_unit_size = CONFIG_WL_SECTOR_SIZE
};
esp_err_t err = esp_vfs_fat_spiflash_mount("/flash", "vfs", &mount_config,
&s_wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount FAT FS: %s", esp_err_to_name(err));
return;
}
ESP_LOGI(TAG, "Mounted Flash VFS Partition at /flash");
bool have_mpy = false; bool have_mpy = false;
struct stat st; struct stat st;
......
#pragma once #pragma once
// Mount filesystem. An error will be loged if the mount failed. void flow3r_fs_init(void);
// \ No newline at end of file
// Filesystem layout:
// /flash - FAT from flash ('vfat' partition, wear leveled)
// /sd - FAT from SD card, if available
//
// This function must not be called more than once.
void st3m_fs_init(void);
\ No newline at end of file
...@@ -60,7 +60,7 @@ void flow3r_startup(void) { ...@@ -60,7 +60,7 @@ void flow3r_startup(void) {
flow3r_bsp_i2c_init(); flow3r_bsp_i2c_init();
st3m_mode_set(st3m_mode_kind_starting, "fs"); st3m_mode_set(st3m_mode_kind_starting, "fs");
st3m_mode_update_display(NULL); st3m_mode_update_display(NULL);
st3m_fs_init(); flow3r_fs_init();
st3m_mode_set(st3m_mode_kind_starting, "audio"); st3m_mode_set(st3m_mode_kind_starting, "audio");
st3m_mode_update_display(NULL); st3m_mode_update_display(NULL);
st3m_scope_init(); st3m_scope_init();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment