Fix 2x SPIFFS mounting/formatting related issues.

- If the initial filesystem mounting fails, then a subsequent file.format()
  does not mount it afterwards, necessitating a node.restart(). In the normal
  case, after file.format() the filesystem is mounted and ready for use.
  We now explicitly remount after a format to gain consistent behaviour.

- If using USB CDC, the auto-format on first boot interferes with USB
  enumeration, resulting in a failed startup. We now avoid doing an
  auto-format if the USB CDC console is enabled. The behaviour is
  configurable/overrideable via Kconfig.
This commit is contained in:
Jade Mattsson 2024-10-17 15:24:02 +11:00
parent 717617593a
commit b78477f2b0
7 changed files with 67 additions and 31 deletions

View File

@ -2,6 +2,6 @@ idf_component_register(
SRCS "ip_fmt.c" "user_main.c" SRCS "ip_fmt.c" "user_main.c"
INCLUDE_DIRS "include" INCLUDE_DIRS "include"
REQUIRES "lua" REQUIRES "lua"
PRIV_REQUIRES "nvs_flash" "spiffs" "esp_netif" "driver" "vfs" "esp_vfs_console" PRIV_REQUIRES "driver" "esp_netif" "esp_vfs_console" "nvs_flash" "vfs"
LDFRAGMENTS "nodemcu.lf" LDFRAGMENTS "nodemcu.lf"
) )

View File

@ -17,7 +17,6 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_event.h" #include "esp_event.h"
#include "esp_spiffs.h"
#include "esp_netif.h" #include "esp_netif.h"
#include "esp_vfs_dev.h" #include "esp_vfs_dev.h"
#include "esp_vfs_cdcacm.h" #include "esp_vfs_cdcacm.h"
@ -55,6 +54,10 @@
# define TX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_LF # define TX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_LF
#endif #endif
#ifndef CONFIG_NODEMCU_AUTO_FORMAT_ON_BOOT
# define CONFIG_NODEMCU_AUTO_FORMAT_ON_BOOT 0
#endif
// We don't get argument size data from the esp_event dispatch, so it's // We don't get argument size data from the esp_event dispatch, so it's
// not possible to copy and forward events from the default event queue // not possible to copy and forward events from the default event queue
@ -127,7 +130,6 @@ static void start_lua ()
static void nodemcu_init(void) static void nodemcu_init(void)
{ {
NODE_ERR("\n");
// Initialize platform first for lua modules. // Initialize platform first for lua modules.
if( platform_init() != PLATFORM_OK ) if( platform_init() != PLATFORM_OK )
{ {
@ -135,34 +137,8 @@ static void nodemcu_init(void)
NODE_DBG("Can not init platform for modules.\n"); NODE_DBG("Can not init platform for modules.\n");
return; return;
} }
const char *label = CONFIG_NODEMCU_DEFAULT_SPIFFS_LABEL; const char *reason =
platform_remount_default_fs(CONFIG_NODEMCU_AUTO_FORMAT_ON_BOOT);
esp_vfs_spiffs_conf_t spiffs_cfg = {
.base_path = "",
.partition_label = (label && label[0]) ? label : NULL,
.max_files = CONFIG_NODEMCU_MAX_OPEN_FILES,
.format_if_mount_failed = true,
};
const char *reason = NULL;
switch(esp_vfs_spiffs_register(&spiffs_cfg))
{
case ESP_OK: break;
case ESP_ERR_NO_MEM:
reason = "out of memory";
break;
case ESP_ERR_INVALID_STATE:
reason = "already mounted, or encrypted";
break;
case ESP_ERR_NOT_FOUND:
reason = "no SPIFFS partition found";
break;
case ESP_FAIL:
reason = "failed to mount or format partition";
break;
default:
reason = "unknown";
break;
}
if (reason) if (reason)
printf("Failed to mount SPIFFS partition: %s\n", reason); printf("Failed to mount SPIFFS partition: %s\n", reason);
} }

View File

@ -31,6 +31,11 @@ static int file_format( lua_State* L )
else{ else{
NODE_ERR( "format done.\n" ); NODE_ERR( "format done.\n" );
} }
const char *err = platform_remount_default_fs(false);
if (err)
return luaL_error(L, err);
return 0; return 0;
} }

View File

@ -24,4 +24,5 @@ idf_component_register(
"esp_rom" "esp_rom"
"lua" "lua"
"soc" "soc"
"spiffs"
) )

View File

@ -37,6 +37,18 @@ menu "NodeMCU platform config"
opened. Raising this limit will incur some extra memory opened. Raising this limit will incur some extra memory
overhead. overhead.
config NODEMCU_AUTO_FORMAT_ON_BOOT
bool "Auto-format SPIFFS on first boot"
default "y" if !ESP_CONSOLE_USB_CDC
default "n" if ESP_CONSOLE_USB_CDC
help
The traditional behavior of NodeMCU is to automatically format
the SPIFFS partition on first boot (or any other time the
filesystem is unmountable). When using USB CDC however, the
formatting can interfere with USB device enumeration, leading
to a failed boot. In that case, disable the auto-format and
use file.format() after startup instead.
config NODEMCU_EMBED_LFS config NODEMCU_EMBED_LFS
bool "Embed LFS as part of the NodeMCU firmware" bool "Embed LFS as part of the NodeMCU firmware"
default "n" default "n"

View File

@ -272,4 +272,10 @@ bool platform_partition_info (uint8_t idx, platform_partition_t *info);
void platform_print_deprecation_note( const char *msg, const char *time_frame); void platform_print_deprecation_note( const char *msg, const char *time_frame);
/**
* Mount or remount the default SPIFFS filesystem.
* @returns An error message string if the operation failed.
*/
const char *platform_remount_default_fs(bool autoformat);
#endif #endif

View File

@ -11,6 +11,7 @@
#include "lua.h" #include "lua.h"
#include "rom/uart.h" #include "rom/uart.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_spiffs.h"
#include "task/task.h" #include "task/task.h"
#include "linput.h" #include "linput.h"
@ -670,3 +671,38 @@ void platform_print_deprecation_note( const char *msg, const char *time_frame)
printf( "Warning, deprecated API! %s. It will be removed %s. See documentation for details.\n", msg, time_frame ); printf( "Warning, deprecated API! %s. It will be removed %s. See documentation for details.\n", msg, time_frame );
} }
const char *platform_remount_default_fs(bool autoformat)
{
const char *label = CONFIG_NODEMCU_DEFAULT_SPIFFS_LABEL;
if (esp_spiffs_mounted(label))
esp_vfs_spiffs_unregister(label);
esp_vfs_spiffs_conf_t spiffs_cfg = {
.base_path = "",
.partition_label = (label && label[0]) ? label : NULL,
.max_files = CONFIG_NODEMCU_MAX_OPEN_FILES,
.format_if_mount_failed = autoformat,
};
const char *reason = NULL;
switch(esp_vfs_spiffs_register(&spiffs_cfg))
{
case ESP_OK:
case ESP_ERR_INVALID_STATE: // already mounted (or encrypted)
break;
case ESP_ERR_NO_MEM:
reason = "out of memory";
break;
case ESP_ERR_NOT_FOUND:
reason = "no SPIFFS partition found";
break;
case ESP_FAIL:
reason = "failed to mount partition, use file.format() to reformat";
break;
default:
reason = "unknown";
break;
}
return reason;
}