Added directory (mounts) listing capabilities to the default root file system when no real root file system (SD card) is mounted.

This commit is contained in:
Terje Io
2024-12-19 11:34:11 +01:00
parent 50a7507f6f
commit 2952a3eeb9
8 changed files with 134 additions and 38 deletions
+3 -3
View File
@@ -1,9 +1,9 @@
## grblHAL ##
Latest build date is 20241208, see the [changelog](changelog.md) for details.
Latest build date is 20241219, see the [changelog](changelog.md) for details.
> [!NOTE]
> A settings reset will be performed on an update of builds prior to 20241217. Backup and restore of settings is recommended.
> A settings reset will be performed on an update of builds prior to 20241208. Backup and restore of settings is recommended.
> [!NOTE]
> Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured.
@@ -93,4 +93,4 @@ G/M-codes not supported by [legacy Grbl](https://github.com/gnea/grbl/wiki) are
Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes.
---
20241217
20241219
+21
View File
@@ -1,5 +1,26 @@
## grblHAL changelog
<a name="20241219">Build 20241219
Core:
* Added directory \(mounts\) listing capabilities to the default root file system when no real root file system \(SD card\) is mounted.
Boards:
* ESP32, iMXRT1062, RP2040: added option to mount littlefs as root filesystem when SD card is not enabled.
Ref. RP2040 issue [#103](https://github.com/grblHAL/RP2040/issues/103).
* STM32F3xx: added serial port to `$pins` report.
Plugins:
* WebUI, Networking and SD card: updated to handle littlefs mounted as root filesystem.
---
## grblHAL changelog
<a name="20241217">Build 20241217
Core:
+14 -1
View File
@@ -531,7 +531,7 @@
#endif
#ifndef FTP_ENABLE
#define FTP_ENABLE 0
#elif !SDCARD_ENABLE
#elif !(SDCARD_ENABLE || LITTLEFS_ENABLE)
#undef FTP_ENABLE
#define FTP_ENABLE 0
#endif
@@ -648,6 +648,19 @@
#define SDCARD_ENABLE 0
#endif
#if LITTLEFS_ENABLE == 2 && SDCARD_ENABLE
#undef LITTLEFS_ENABLE
#define LITTLEFS_ENABLE 1
#endif
#if LITTLEFS_ENABLE
#if LITTLEFS_ENABLE == 2
#define LITTLEFS_MOUNT_DIR "/"
#else
#define LITTLEFS_MOUNT_DIR "/littlefs"
#endif
#endif
#ifndef SPI_ENABLE
#if SDCARD_ENABLE || TRINAMIC_SPI_ENABLE
#define SPI_ENABLE 1
+1 -1
View File
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20241217
#define GRBL_BUILD 20241219
#define GRBL_URL "https://github.com/grblHAL"
+1 -1
View File
@@ -669,7 +669,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
if((subname = ngc_string_param_get((ngc_string_id_t)o_label))) {
char filename[60];
vfs_file_t *file;
#if LITTLEFS_ENABLE
#if LITTLEFS_ENABLE == 1
sprintf(filename, "/littlefs/%s.macro", subname);
if((file = stream_redirect_read(filename, onNamedSubError, onNamedSubEOF)) == NULL) {
+6 -1
View File
@@ -62,7 +62,7 @@ static int16_t stream_read_file (void)
return ASCII_LF; // Return a linefeed if the last character was not a linefeed.
}
} else
c = SERIAL_NO_DATA; // TODO: close all streams?
return SERIAL_NO_DATA; // TODO: close all streams?
return (int16_t)c;
}
@@ -120,6 +120,11 @@ static void onReportHandlersInit (void)
grbl.report.status_message = trap_status_messages;
}
bool stream_is_file (void)
{
return hal.stream.type == StreamType_File;
}
vfs_file_t *stream_redirect_read (char *filename, status_message_ptr status_handler, on_file_end_ptr eof_handler)
{
static bool error_handler_ok = false;
+1
View File
@@ -24,5 +24,6 @@
#include "vfs.h"
#include "core_handlers.h"
bool stream_is_file (void);
void stream_redirect_close (vfs_file_t *file);
vfs_file_t *stream_redirect_read (char *filename, status_message_ptr status_handler, on_file_end_ptr eof_handler);
+87 -31
View File
@@ -31,6 +31,28 @@
#undef feof
#endif
static vfs_mount_t *get_rootfs (void);
static inline vfs_mount_t *path_is_mount_dir (const char *path)
{
size_t plen = strlen(path);
vfs_mount_t *mount = get_rootfs();
if(*path == '/' && plen == 1)
return mount;
size_t mlen;
if((mount = mount->next)) do {
mlen = strlen(mount->path) - 1;
if(mlen == plen && !strncmp(mount->path, path, mlen))
break;
} while((mount = mount->next));
return mount;
}
// NULL file system
static vfs_file_t *fs_open (const char *filename, const char *mode)
@@ -79,7 +101,38 @@ static int fs_dirop (const char *path)
static vfs_dir_t *fs_opendir (const char *path)
{
return NULL;
static vfs_dir_t *dir = NULL;
if(dir == NULL)
dir = calloc(sizeof(vfs_dir_t) + 3, 1);
if(dir) {
vfs_mount_t **mount = (vfs_mount_t **)&dir->handle;
*mount = get_rootfs()->next;
}
return !strcmp(path, "/") ? dir : NULL;
}
static char *fs_readdir (vfs_dir_t *dir, vfs_dirent_t *dirent)
{
vfs_mount_t **mount = (vfs_mount_t **)&dir->handle;
vfs_errno = 0;
if(*mount) {
strcpy(dirent->name, (*mount)->path);
*(strchr(dirent->name, '\0') - 1) = '\0';
dirent->st_mode = (*mount)->mode;
dirent->st_mode.directory = true;
while((*mount = (*mount)->next)) {
if(!(*mount)->mode.hidden)
break;
}
} else
*dirent->name = '\0';
return *dirent->name ? dirent->name : NULL;
}
static void fs_closedir (vfs_dir_t *dir)
@@ -88,6 +141,22 @@ static void fs_closedir (vfs_dir_t *dir)
static int fs_stat (const char *filename, vfs_stat_t *st)
{
char path[64];
vfs_mount_t *mount;
if((mount = path_is_mount_dir(strcat(strcpy(path, "/"), filename)))) {
st->st_size = 1024;
st->st_mode = mount->mode;
st->st_mode.directory = true;
#if ESP_PLATFORM
st->st_mtim = (time_t)0;
#else
st->st_mtime = (time_t)0;
#endif
return 0;
}
return -1;
}
@@ -114,6 +183,7 @@ static const vfs_t fs_null = {
.fchdir = fs_chdir,
.frmdir = fs_dirop,
.fopendir = fs_opendir,
.readdir = fs_readdir,
.fclosedir = fs_closedir,
.fstat = fs_stat,
.fgetcwd = fs_getcwd
@@ -133,6 +203,11 @@ static char cwd[100] = "/";
int vfs_errno = 0;
vfs_events_t vfs = {0};
static vfs_mount_t *get_rootfs (void)
{
return &root;
}
// Strip trailing directory separator, FatFS dont't like it (WinSCP adds it)
char *vfs_fixpath (char *path)
{
@@ -143,25 +218,6 @@ char *vfs_fixpath (char *path)
return path;
}
static inline vfs_mount_t *path_is_mount_dir (const char *path)
{
size_t plen = strlen(path);
if(*path == '/' && plen == 1)
return &root;
size_t mlen;
vfs_mount_t *mount = root.next;
if(mount) do {
mlen = strlen(mount->path) - 1;
if(mlen == plen && !strncmp(mount->path, path, mlen))
break;
} while((mount = mount->next));
return mount;
}
static vfs_mount_t *get_mount (const char *path)
{
vfs_errno = 0;
@@ -324,7 +380,7 @@ int vfs_chdir (const char *path)
vfs_errno = 0;
if(*path != '/') {
if(*path != '/' && strcmp(cwd, "/")) {
if(strcmp(path, "..")) {
if(strlen(cwd) > 1)
strcat(cwd, "/");
@@ -336,24 +392,24 @@ int vfs_chdir (const char *path)
}
} else {
strcpy(cwd, path);
if(*path == '/')
strcpy(cwd, path);
else
strcat(strcpy(cwd, "/"), path);
if((cwdmount = get_mount(path)) && strchr(path + 1, '/') == NULL && cwdmount != &root) {
vfs_fixpath(cwd);
if((cwdmount = get_mount(cwd)) && strchr(cwd + 1, '/') == NULL && cwdmount != &root) {
strcpy(cwd, cwdmount->path);
char *s;
if((s = strrchr(cwd, '/')))
*s = '\0';
vfs_fixpath(cwd);
return 0;
}
}
if((ret = cwdmount ? cwdmount->vfs->fchdir(path) : -1) != 0) { // + strlen(mount->path));))
char *s = strrchr(cwd, '/');
if(s)
*s = '\0';
}
if((ret = cwdmount ? cwdmount->vfs->fchdir(path) : -1) != 0) // + strlen(mount->path));))
vfs_fixpath(cwd);
return ret;
}