From d483fd94d8887e8403289003fb23360f63d79a01 Mon Sep 17 00:00:00 2001 From: Jade Mattsson Date: Mon, 14 Oct 2024 11:57:23 +1100 Subject: [PATCH 1/6] Upgrade IDF to 5.3.1 --- components/base_nodemcu/CMakeLists.txt | 2 +- components/base_nodemcu/user_main.c | 7 ++++--- components/modules/eth.c | 4 ++-- components/modules/node.c | 7 +++++-- components/platform/Kconfig | 1 + components/platform/platform.c | 2 +- sdk/esp32-esp-idf | 2 +- 7 files changed, 15 insertions(+), 10 deletions(-) diff --git a/components/base_nodemcu/CMakeLists.txt b/components/base_nodemcu/CMakeLists.txt index fdb2c3808..9c891dad5 100644 --- a/components/base_nodemcu/CMakeLists.txt +++ b/components/base_nodemcu/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register( SRCS "ip_fmt.c" "user_main.c" INCLUDE_DIRS "include" REQUIRES "lua" - PRIV_REQUIRES "nvs_flash" "spiffs" "esp_netif" "driver" "vfs" + PRIV_REQUIRES "nvs_flash" "spiffs" "esp_netif" "driver" "vfs" "esp_vfs_console" LDFRAGMENTS "nodemcu.lf" ) diff --git a/components/base_nodemcu/user_main.c b/components/base_nodemcu/user_main.c index 0a70e58b6..6528d98c4 100644 --- a/components/base_nodemcu/user_main.c +++ b/components/base_nodemcu/user_main.c @@ -22,6 +22,7 @@ #include "esp_vfs_dev.h" #include "esp_vfs_cdcacm.h" #include "esp_vfs_usb_serial_jtag.h" +#include "driver/uart_vfs.h" #include "driver/usb_serial_jtag.h" #include "nvs_flash.h" @@ -231,9 +232,9 @@ static void console_init(void) #if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM /* Based on console/advanced example */ - esp_vfs_dev_uart_port_set_rx_line_endings( + uart_vfs_dev_port_set_rx_line_endings( CONFIG_ESP_CONSOLE_UART_NUM, RX_LINE_ENDINGS_CFG); - esp_vfs_dev_uart_port_set_tx_line_endings( + uart_vfs_dev_port_set_tx_line_endings( CONFIG_ESP_CONSOLE_UART_NUM, TX_LINE_ENDINGS_CFG); /* Configure UART. Note that REF_TICK is used so that the baud rate remains @@ -255,7 +256,7 @@ static void console_init(void) uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config); /* Tell VFS to use UART driver */ - esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); + uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); #elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG /* Based on @pjsg's work */ diff --git a/components/modules/eth.c b/components/modules/eth.c index 253935b1b..7ab7d8ffa 100644 --- a/components/modules/eth.c +++ b/components/modules/eth.c @@ -274,9 +274,9 @@ static int leth_init( lua_State *L ) eth_esp32_emac_config_t emac_cfg = ETH_ESP32_EMAC_DEFAULT_CONFIG(); - emac_cfg.smi_mdc_gpio_num = + emac_cfg.smi_gpio.mdc_num = opt_checkint_range( L, "mdc", -1, GPIO_NUM_0, GPIO_NUM_MAX-1 ); - emac_cfg.smi_mdio_gpio_num = + emac_cfg.smi_gpio.mdio_num = opt_checkint_range( L, "mdio", -1, GPIO_NUM_0, GPIO_NUM_MAX-1 ); eth_mac_config_t mac_cfg = ETH_MAC_DEFAULT_CONFIG(); diff --git a/components/modules/node.c b/components/modules/node.c index 9979a3990..931492ceb 100644 --- a/components/modules/node.c +++ b/components/modules/node.c @@ -113,7 +113,7 @@ static int node_bootreason( lua_State *L) #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32C6) case SDIO_RESET: #endif -#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32H2) +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) case GLITCH_RTC_RESET: #endif #if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) @@ -122,6 +122,9 @@ static int node_bootreason( lua_State *L) #if defined(CONFIG_IDF_TARGET_ESP32C6) case JTAG_RESET: #endif +#if defined(CONFIG_IDF_TARGET_ESP32H2) + case JTAG_CPU_RESET: +#endif #if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) case USB_UART_CHIP_RESET: case USB_JTAG_CHIP_RESET: @@ -131,7 +134,7 @@ static int node_bootreason( lua_State *L) #endif case TG0WDT_SYS_RESET: case TG1WDT_SYS_RESET: -#if !defined(CONFIG_IDF_TARGET_ESP32C6) +#if !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2) case INTRUSION_RESET: #endif case RTCWDT_BROWN_OUT_RESET: diff --git a/components/platform/Kconfig b/components/platform/Kconfig index a2b21f7ab..0c9ee65bc 100644 --- a/components/platform/Kconfig +++ b/components/platform/Kconfig @@ -79,6 +79,7 @@ menu "NodeMCU platform config" bool default y if IDF_TARGET_ESP32 default y if IDF_TARGET_ESP32S3 + default y if IDF_TARGET_ESP32C6 config NODEMCU_UART_DRIVER_BUF_SIZE_RX0 int "RX buffer size for UART0" diff --git a/components/platform/platform.c b/components/platform/platform.c index 86606df8c..01b00f750 100644 --- a/components/platform/platform.c +++ b/components/platform/platform.c @@ -215,7 +215,7 @@ uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int pari uart_config_t cfg = { .baud_rate = baud, .flow_ctrl = flow_control, - .rx_flow_ctrl_thresh = UART_FIFO_LEN - 16, + .rx_flow_ctrl_thresh = UART_HW_FIFO_LEN(id) - 16, .source_clk = UART_SCLK_DEFAULT, }; diff --git a/sdk/esp32-esp-idf b/sdk/esp32-esp-idf index e7771c75b..c8fc5f643 160000 --- a/sdk/esp32-esp-idf +++ b/sdk/esp32-esp-idf @@ -1 +1 @@ -Subproject commit e7771c75bd1dbbfb7b3c5381be7e063b197c9734 +Subproject commit c8fc5f643b7a7b0d3b182d3df610844e3dc9bd74 From 2814b8c624523c3bef2f0387dcd734be7caa34c8 Mon Sep 17 00:00:00 2001 From: Jade Mattsson Date: Mon, 14 Oct 2024 18:59:31 +1100 Subject: [PATCH 2/6] Fixes to make 5.3.1 run without crashing. --- components/base_nodemcu/user_main.c | 3 +++ components/modules/Kconfig | 11 +++++++++++ components/modules/wifi.c | 29 +++++++++-------------------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/components/base_nodemcu/user_main.c b/components/base_nodemcu/user_main.c index 6528d98c4..33a1b780e 100644 --- a/components/base_nodemcu/user_main.c +++ b/components/base_nodemcu/user_main.c @@ -21,6 +21,7 @@ #include "esp_netif.h" #include "esp_vfs_dev.h" #include "esp_vfs_cdcacm.h" +#include "esp_vfs_console.h" #include "esp_vfs_usb_serial_jtag.h" #include "driver/uart_vfs.h" #include "driver/usb_serial_jtag.h" @@ -218,6 +219,8 @@ static void console_task(void *) static void console_init(void) { + esp_vfs_console_register(); + fflush(stdout); fsync(fileno(stdout)); diff --git a/components/modules/Kconfig b/components/modules/Kconfig index ce13f848d..0ca93e763 100644 --- a/components/modules/Kconfig +++ b/components/modules/Kconfig @@ -323,6 +323,17 @@ menu "NodeMCU modules" help Includes the WiFi module (recommended). + config NODEMCU_CMODULE_WIFI_STARTUP_DELAY + depends on ESP_CONSOLE_USB_CDC + int "WiFi start-up delay (ms)" + default 500 + help + For some unknown reason there is an issue with allowing the + WiFi stack to initialise immediately when using a USB CDC + console (at least on the ESP32-S2). The workaround is to + delay the initialisation sequence by enough that whatever + else is needing to run gets to run first. + config NODEMCU_CMODULE_WS2812 bool "WS2812 module" default "n" diff --git a/components/modules/wifi.c b/components/modules/wifi.c index f16b98331..81b86a0e8 100644 --- a/components/modules/wifi.c +++ b/components/modules/wifi.c @@ -93,22 +93,6 @@ static int wifi_stop (lua_State *L) 0 : luaL_error (L, "failed to stop wifi, code %d", err); } -#if defined(CONFIG_ESP_CONSOLE_USB_CDC) -// For some unknown reason, on an S2 with USB CDC console enabled, if we allow -// the esp_wifi_init() to run during initial startup, something Bad(tm) -// happens and the S2 fails to enumerate on the USB bus. However, if we defer -// the wifi initialisation, it starts up fine. This is an ugly workaround, but -// I'm out of ideas at this point. If I use a UART console, I see no errors -// even with the immediate init. -static task_handle_t th; -#endif - -static void do_esp_wifi_init(task_param_t p, task_prio_t) -{ - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init (&cfg)); -} - extern void wifi_ap_init (void); extern void wifi_sta_init (void); static int wifi_init (lua_State *L) @@ -117,11 +101,16 @@ static int wifi_init (lua_State *L) wifi_sta_init (); #if defined(CONFIG_ESP_CONSOLE_USB_CDC) - th = task_get_id(do_esp_wifi_init); - task_post_low(th, 0); -#else - do_esp_wifi_init(0, 0); +// For some unknown reason, on an S2 with USB CDC console enabled, if we allow +// the esp_wifi_init() to run during initial startup, something Bad(tm) +// happens and the S2 fails to enumerate on the USB bus. However, if we defer +// it by half a second or so, everything works. This is an ugly workaround, +// but I'm out of ideas at this point. + vTaskDelay(CONFIG_NODEMCU_CMODULE_WIFI_STARTUP_DELAY / portTICK_PERIOD_MS); #endif + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init (&cfg)); + return 0; } From 717617593a67db8ee6042240648b4ff0afc1ac14 Mon Sep 17 00:00:00 2001 From: Jade Mattsson Date: Thu, 17 Oct 2024 11:41:14 +1100 Subject: [PATCH 3/6] Only show startup delay setting if wifi module enabled --- components/modules/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/components/modules/Kconfig b/components/modules/Kconfig index 0ca93e763..19c869755 100644 --- a/components/modules/Kconfig +++ b/components/modules/Kconfig @@ -324,6 +324,7 @@ menu "NodeMCU modules" Includes the WiFi module (recommended). config NODEMCU_CMODULE_WIFI_STARTUP_DELAY + depends on NODEMCU_CMODULE_WIFI depends on ESP_CONSOLE_USB_CDC int "WiFi start-up delay (ms)" default 500 From b78477f2b0ac4740ac19e92515b9bc23d3843d2a Mon Sep 17 00:00:00 2001 From: Jade Mattsson Date: Thu, 17 Oct 2024 15:24:02 +1100 Subject: [PATCH 4/6] 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. --- components/base_nodemcu/CMakeLists.txt | 2 +- components/base_nodemcu/user_main.c | 36 +++++--------------------- components/modules/file.c | 5 ++++ components/platform/CMakeLists.txt | 1 + components/platform/Kconfig | 12 +++++++++ components/platform/include/platform.h | 6 +++++ components/platform/platform.c | 36 ++++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 31 deletions(-) diff --git a/components/base_nodemcu/CMakeLists.txt b/components/base_nodemcu/CMakeLists.txt index 9c891dad5..4df26aee8 100644 --- a/components/base_nodemcu/CMakeLists.txt +++ b/components/base_nodemcu/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register( SRCS "ip_fmt.c" "user_main.c" INCLUDE_DIRS "include" 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" ) diff --git a/components/base_nodemcu/user_main.c b/components/base_nodemcu/user_main.c index 33a1b780e..82453afd1 100644 --- a/components/base_nodemcu/user_main.c +++ b/components/base_nodemcu/user_main.c @@ -17,7 +17,6 @@ #include "sdkconfig.h" #include "esp_system.h" #include "esp_event.h" -#include "esp_spiffs.h" #include "esp_netif.h" #include "esp_vfs_dev.h" #include "esp_vfs_cdcacm.h" @@ -55,6 +54,10 @@ # define TX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_LF #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 // 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) { - NODE_ERR("\n"); // Initialize platform first for lua modules. if( platform_init() != PLATFORM_OK ) { @@ -135,34 +137,8 @@ static void nodemcu_init(void) NODE_DBG("Can not init platform for modules.\n"); return; } - const char *label = CONFIG_NODEMCU_DEFAULT_SPIFFS_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 = 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; - } + const char *reason = + platform_remount_default_fs(CONFIG_NODEMCU_AUTO_FORMAT_ON_BOOT); if (reason) printf("Failed to mount SPIFFS partition: %s\n", reason); } diff --git a/components/modules/file.c b/components/modules/file.c index fae1c0bc6..73cf8584b 100644 --- a/components/modules/file.c +++ b/components/modules/file.c @@ -31,6 +31,11 @@ static int file_format( lua_State* L ) else{ NODE_ERR( "format done.\n" ); } + + const char *err = platform_remount_default_fs(false); + if (err) + return luaL_error(L, err); + return 0; } diff --git a/components/platform/CMakeLists.txt b/components/platform/CMakeLists.txt index 955f8dbb4..3166c3296 100644 --- a/components/platform/CMakeLists.txt +++ b/components/platform/CMakeLists.txt @@ -24,4 +24,5 @@ idf_component_register( "esp_rom" "lua" "soc" + "spiffs" ) diff --git a/components/platform/Kconfig b/components/platform/Kconfig index 0c9ee65bc..f3711d3ac 100644 --- a/components/platform/Kconfig +++ b/components/platform/Kconfig @@ -37,6 +37,18 @@ menu "NodeMCU platform config" opened. Raising this limit will incur some extra memory 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 bool "Embed LFS as part of the NodeMCU firmware" default "n" diff --git a/components/platform/include/platform.h b/components/platform/include/platform.h index 42ec933a6..f3e4e2dd8 100644 --- a/components/platform/include/platform.h +++ b/components/platform/include/platform.h @@ -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); +/** + * 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 diff --git a/components/platform/platform.c b/components/platform/platform.c index 01b00f750..cb1f79354 100644 --- a/components/platform/platform.c +++ b/components/platform/platform.c @@ -11,6 +11,7 @@ #include "lua.h" #include "rom/uart.h" #include "esp_log.h" +#include "esp_spiffs.h" #include "task/task.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 ); } + +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; +} From bee12d0a15901ea65275e8aefb705a4a5d672c7a Mon Sep 17 00:00:00 2001 From: Jade Mattsson Date: Fri, 18 Oct 2024 13:11:37 +1100 Subject: [PATCH 5/6] Address additional deprecation warnings --- components/base_nodemcu/user_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/components/base_nodemcu/user_main.c b/components/base_nodemcu/user_main.c index 82453afd1..f2391b22a 100644 --- a/components/base_nodemcu/user_main.c +++ b/components/base_nodemcu/user_main.c @@ -24,6 +24,7 @@ #include "esp_vfs_usb_serial_jtag.h" #include "driver/uart_vfs.h" #include "driver/usb_serial_jtag.h" +#include "driver/usb_serial_jtag_vfs.h" #include "nvs_flash.h" #include "task/task.h" @@ -240,15 +241,15 @@ static void console_init(void) #elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG /* Based on @pjsg's work */ - esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(RX_LINE_ENDINGS_CFG); - esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(TX_LINE_ENDINGS_CFG); + usb_serial_jtag_vfs_set_rx_line_endings(RX_LINE_ENDINGS_CFG); + usb_serial_jtag_vfs_set_tx_line_endings(TX_LINE_ENDINGS_CFG); usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT(); /* Install USB-SERIAL-JTAG driver for interrupt-driven reads and write */ usb_serial_jtag_driver_install(&usb_serial_jtag_config); - esp_vfs_usb_serial_jtag_use_driver(); + usb_serial_jtag_vfs_use_driver(); #elif CONFIG_ESP_CONSOLE_USB_CDC /* Based on console/advanced_usb_cdc */ From 4931b375c02bb7e1fd44d4c3e317ab08405ba2b6 Mon Sep 17 00:00:00 2001 From: Jade Mattsson Date: Fri, 18 Oct 2024 18:09:22 +1100 Subject: [PATCH 6/6] Increase console task stack size. This allegedly resolves the reboot crashes seen on ESP32-S3 Zero. It also removes the peculiar need to explicitly call esp_vfs_console_register(), the absence of which previously would trigger an assertion failure in xQueueGenericSend on input. --- components/base_nodemcu/user_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/base_nodemcu/user_main.c b/components/base_nodemcu/user_main.c index f2391b22a..0b86dbaf2 100644 --- a/components/base_nodemcu/user_main.c +++ b/components/base_nodemcu/user_main.c @@ -196,8 +196,6 @@ static void console_task(void *) static void console_init(void) { - esp_vfs_console_register(); - fflush(stdout); fsync(fileno(stdout)); @@ -260,7 +258,8 @@ static void console_init(void) #endif xTaskCreate( - console_task, "console", 1024, NULL, ESP_TASK_MAIN_PRIO+1, NULL); + console_task, "console", configMINIMAL_STACK_SIZE, + NULL, ESP_TASK_MAIN_PRIO+1, NULL); }