From fc26095d4d963b75161673409618c04efc04938a Mon Sep 17 00:00:00 2001 From: Jade Mattsson Date: Tue, 27 Feb 2024 18:25:11 +1100 Subject: [PATCH] Proof-of-concept multi-type console support via stdio --- components/base_nodemcu/CMakeLists.txt | 2 +- components/base_nodemcu/user_main.c | 95 ++++++++++++++++++++++++-- components/platform/platform.c | 28 +++++--- 3 files changed, 111 insertions(+), 14 deletions(-) diff --git a/components/base_nodemcu/CMakeLists.txt b/components/base_nodemcu/CMakeLists.txt index 50114b1ff..fdb2c3808 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" + PRIV_REQUIRES "nvs_flash" "spiffs" "esp_netif" "driver" "vfs" LDFRAGMENTS "nodemcu.lf" ) diff --git a/components/base_nodemcu/user_main.c b/components/base_nodemcu/user_main.c index 2e8bca562..8c3288eb5 100644 --- a/components/base_nodemcu/user_main.c +++ b/components/base_nodemcu/user_main.c @@ -13,11 +13,16 @@ #include "platform.h" #include #include +#include #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" +#include "esp_vfs_usb_serial_jtag.h" +#include "driver/usb_serial_jtag.h" #include "nvs_flash.h" #include "task/task.h" @@ -98,7 +103,7 @@ static void start_lua () lua_main(); } -void nodemcu_init(void) +static void nodemcu_init(void) { NODE_ERR("\n"); // Initialize platform first for lua modules. @@ -141,6 +146,89 @@ void nodemcu_init(void) } +static void console_task(void *) +{ + char linebuf[64]; + for (;;) + { + ssize_t n = read(fileno(stdin), linebuf, sizeof(linebuf)); + if (n > 0) + { + // If we want to honor run_input, we'd need to check the return val + feed_lua_input(linebuf, n); + } + } +} + + +static void console_init(void) +{ + fflush(stdout); + fsync(fileno(stdout)); + + /* Disable buffering */ + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + + /* Enable non-blocking mode */ + fcntl(fileno(stdin), F_SETFL, 0); + fcntl(fileno(stdout), F_SETFL, 0); + +#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( + CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR); + esp_vfs_dev_uart_port_set_tx_line_endings( + CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF); + + /* Configure UART. Note that REF_TICK is used so that the baud rate remains + * correct while APB frequency is changing in light sleep mode. + */ + const uart_config_t uart_config = { + .baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, +#if SOC_UART_SUPPORT_REF_TICK + .source_clk = UART_SCLK_REF_TICK, +#elif SOC_UART_SUPPORT_XTAL_CLK + .source_clk = UART_SCLK_XTAL, +#endif + }; + /* Install UART driver for interrupt-driven reads and writes */ + uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, 256, 0, 0, NULL, 0); + 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); + +#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + /* Based on @pjsg's work */ + + esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR); + esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); + + 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(); +#elif CONFIG_ESP_CONSOLE_USB_CDC + /* Based on console/advanced_usb_cdc */ + + esp_vfs_dev_cdcacm_set_rx_line_endings(ESP_LINE_ENDINGS_CR); + esp_vfs_dev_cdcacm_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); +#else +# error "Unsupported console type" +#endif + + xTaskCreate( + console_task, "console", 1024, NULL, ESP_TASK_MAIN_PRIO+1, NULL); +} + + void __attribute__((noreturn)) app_main(void) { task_init(); @@ -155,14 +243,13 @@ void __attribute__((noreturn)) app_main(void) relay_default_loop_events, NULL); - platform_uart_start(CONFIG_ESP_CONSOLE_UART_NUM); - setvbuf(stdout, NULL, _IONBF, 0); - nodemcu_init (); nvs_flash_init (); esp_netif_init (); + console_init(); + start_lua (); task_pump_messages (); __builtin_unreachable (); diff --git a/components/platform/platform.c b/components/platform/platform.c index ea759c34e..2d8141bdb 100644 --- a/components/platform/platform.c +++ b/components/platform/platform.c @@ -284,6 +284,11 @@ uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int pari void platform_uart_setmode(unsigned id, unsigned mode) { +#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM + if (id == CONFIG_ESP_CONSOLE_UART_NUM) + return; +#endif + uart_mode_t uartMode; switch(mode) @@ -334,6 +339,11 @@ void platform_uart_flush( unsigned id ) int platform_uart_start( unsigned id ) { +#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM + if (id == CONFIG_ESP_CONSOLE_UART_NUM) + return -1; +#endif + if(uart_event_task_id == 0) uart_event_task_id = task_get_id( uart_event_task ); @@ -365,16 +375,16 @@ int platform_uart_start( unsigned id ) void platform_uart_stop( unsigned id ) { +#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM if (id == CONFIG_ESP_CONSOLE_UART_NUM) - ; - else { - uart_status_t *us = & uart_status[id]; - uart_driver_delete(id); - if(us->line_buffer) free(us->line_buffer); - us->line_buffer = NULL; - if(us->taskHandle) vTaskDelete(us->taskHandle); - us->taskHandle = NULL; - } + return; +#endif + uart_status_t *us = & uart_status[id]; + uart_driver_delete(id); + if(us->line_buffer) free(us->line_buffer); + us->line_buffer = NULL; + if(us->taskHandle) vTaskDelete(us->taskHandle); + us->taskHandle = NULL; } int platform_uart_get_config(unsigned id, uint32_t *baudp, uint32_t *databitsp, uint32_t *parityp, uint32_t *stopbitsp) {