mirror of
https://github.com/grblHAL/core.git
synced 2026-09-22 19:43:43 +08:00
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:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user