diff --git a/examples/system/console/README.md b/examples/system/console/README.md new file mode 100644 index 0000000000..851ae7e276 --- /dev/null +++ b/examples/system/console/README.md @@ -0,0 +1,27 @@ +# Console examples + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +Examples in this directory illustrate the usage of the [Console Component](https://docs.espressif.com/projects/esp-idf/en/stable/api-guides/console.html#console) to create an interactive shell on the ESP chip. + +## basic example + +This example illustrates high-level Read-Eval-Print Loop API (`esp_console_repl`). + +This example can be used with UART, USB_OTG or USB_SERIAL_JTAG peripherals. It works on all ESP chips. + +It is the recommended starting point when getting familiar with console component. + +## advanced example + +This example illustrates lower-level APIs for line editing and autocompletion (`linenoise`), argument parsing (`argparse3`) and command registration (`esp_console`). + +These APIs allow for a lot of flexibility when building a console application, but require more code to be written. + +While these APIs allow for a console to be implemented over various interfaces (UART, USB, TCP), this example works with UART only. + +## advanced_usb_cdc example + +This example is similar to the one above, except it works over USB CDC provided by USB_OTG peripheral. + +Currently it can be used on ESP32-S2. diff --git a/examples/system/console/advanced/components/cmd_wifi/CMakeLists.txt b/examples/system/console/advanced/components/cmd_wifi/CMakeLists.txt new file mode 100644 index 0000000000..ca51905567 --- /dev/null +++ b/examples/system/console/advanced/components/cmd_wifi/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "cmd_wifi.c" + INCLUDE_DIRS . + REQUIRES console esp_wifi) diff --git a/examples/system/console/basic/main/cmd_wifi.c b/examples/system/console/advanced/components/cmd_wifi/cmd_wifi.c similarity index 97% rename from examples/system/console/basic/main/cmd_wifi.c rename to examples/system/console/advanced/components/cmd_wifi/cmd_wifi.c index 0daf53677c..b8dbaea2c8 100644 --- a/examples/system/console/basic/main/cmd_wifi.c +++ b/examples/system/console/advanced/components/cmd_wifi/cmd_wifi.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ /* Console example — WiFi commands This example code is in the Public Domain (or CC0 licensed, at your option.) @@ -12,7 +17,6 @@ #include "esp_log.h" #include "esp_console.h" #include "argtable3/argtable3.h" -#include "cmd_decl.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" #include "esp_wifi.h" diff --git a/examples/system/console/basic/main/cmd_wifi.h b/examples/system/console/advanced/components/cmd_wifi/cmd_wifi.h similarity index 79% rename from examples/system/console/basic/main/cmd_wifi.h rename to examples/system/console/advanced/components/cmd_wifi/cmd_wifi.h index 67f3d9d3ad..f25d6304b1 100644 --- a/examples/system/console/basic/main/cmd_wifi.h +++ b/examples/system/console/advanced/components/cmd_wifi/cmd_wifi.h @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ /* Console example — declarations of command registration functions. This example code is in the Public Domain (or CC0 licensed, at your option.) diff --git a/examples/system/console/advanced/main/CMakeLists.txt b/examples/system/console/advanced/main/CMakeLists.txt index 588654505d..6833bf8b62 100644 --- a/examples/system/console/advanced/main/CMakeLists.txt +++ b/examples/system/console/advanced/main/CMakeLists.txt @@ -1,3 +1,2 @@ -idf_component_register(SRCS "cmd_wifi.c" - "console_example_main.c" +idf_component_register(SRCS "console_example_main.c" INCLUDE_DIRS ".") diff --git a/examples/system/console/advanced/main/cmd_decl.h b/examples/system/console/advanced/main/cmd_decl.h deleted file mode 100644 index 983b6e974c..0000000000 --- a/examples/system/console/advanced/main/cmd_decl.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Console example — declarations of command registration functions. - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "cmd_system.h" -#include "cmd_wifi.h" -#include "cmd_nvs.h" - -#ifdef __cplusplus -} -#endif diff --git a/examples/system/console/advanced/main/cmd_wifi.c b/examples/system/console/advanced/main/cmd_wifi.c deleted file mode 100644 index 0daf53677c..0000000000 --- a/examples/system/console/advanced/main/cmd_wifi.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Console example — WiFi commands - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include -#include -#include "esp_log.h" -#include "esp_console.h" -#include "argtable3/argtable3.h" -#include "cmd_decl.h" -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_netif.h" -#include "esp_event.h" -#include "cmd_wifi.h" - -#define JOIN_TIMEOUT_MS (10000) - -static EventGroupHandle_t wifi_event_group; -const int CONNECTED_BIT = BIT0; - - -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - } -} - -static void initialise_wifi(void) -{ - esp_log_level_set("wifi", ESP_LOG_WARN); - static bool initialized = false; - if (initialized) { - return; - } - ESP_ERROR_CHECK(esp_netif_init()); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap(); - assert(ap_netif); - esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta(); - assert(sta_netif); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &event_handler, NULL) ); - ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) ); - ESP_ERROR_CHECK( esp_wifi_start() ); - initialized = true; -} - -static bool wifi_join(const char *ssid, const char *pass, int timeout_ms) -{ - initialise_wifi(); - wifi_config_t wifi_config = { 0 }; - strlcpy((char *) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid)); - if (pass) { - strlcpy((char *) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password)); - } - - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); - esp_wifi_connect(); - - int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, - pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS); - return (bits & CONNECTED_BIT) != 0; -} - -/** Arguments used by 'join' function */ -static struct { - struct arg_int *timeout; - struct arg_str *ssid; - struct arg_str *password; - struct arg_end *end; -} join_args; - -static int connect(int argc, char **argv) -{ - int nerrors = arg_parse(argc, argv, (void **) &join_args); - if (nerrors != 0) { - arg_print_errors(stderr, join_args.end, argv[0]); - return 1; - } - ESP_LOGI(__func__, "Connecting to '%s'", - join_args.ssid->sval[0]); - - /* set default value*/ - if (join_args.timeout->count == 0) { - join_args.timeout->ival[0] = JOIN_TIMEOUT_MS; - } - - bool connected = wifi_join(join_args.ssid->sval[0], - join_args.password->sval[0], - join_args.timeout->ival[0]); - if (!connected) { - ESP_LOGW(__func__, "Connection timed out"); - return 1; - } - ESP_LOGI(__func__, "Connected"); - return 0; -} - -void register_wifi(void) -{ - join_args.timeout = arg_int0(NULL, "timeout", "", "Connection timeout, ms"); - join_args.ssid = arg_str1(NULL, NULL, "", "SSID of AP"); - join_args.password = arg_str0(NULL, NULL, "", "PSK of AP"); - join_args.end = arg_end(2); - - const esp_console_cmd_t join_cmd = { - .command = "join", - .help = "Join WiFi AP as a station", - .hint = NULL, - .func = &connect, - .argtable = &join_args - }; - - ESP_ERROR_CHECK( esp_console_cmd_register(&join_cmd) ); -} diff --git a/examples/system/console/advanced/main/cmd_wifi.h b/examples/system/console/advanced/main/cmd_wifi.h deleted file mode 100644 index 67f3d9d3ad..0000000000 --- a/examples/system/console/advanced/main/cmd_wifi.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Console example — declarations of command registration functions. - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -// Register WiFi functions -void register_wifi(void); - -#ifdef __cplusplus -} -#endif diff --git a/examples/system/console/advanced/main/console_example_main.c b/examples/system/console/advanced/main/console_example_main.c index 82e5431cd4..6812a29ff7 100644 --- a/examples/system/console/advanced/main/console_example_main.c +++ b/examples/system/console/advanced/main/console_example_main.c @@ -16,10 +16,12 @@ #include "driver/uart.h" #include "linenoise/linenoise.h" #include "argtable3/argtable3.h" -#include "cmd_decl.h" #include "esp_vfs_fat.h" #include "nvs.h" #include "nvs_flash.h" +#include "cmd_system.h" +#include "cmd_wifi.h" +#include "cmd_nvs.h" #ifdef CONFIG_ESP_CONSOLE_USB_CDC #error This example is incompatible with USB CDC console. Please try "console_usb" example instead. diff --git a/examples/system/console_usb/CMakeLists.txt b/examples/system/console/advanced_usb_cdc/CMakeLists.txt similarity index 100% rename from examples/system/console_usb/CMakeLists.txt rename to examples/system/console/advanced_usb_cdc/CMakeLists.txt diff --git a/examples/system/console_usb/README.md b/examples/system/console/advanced_usb_cdc/README.md similarity index 95% rename from examples/system/console_usb/README.md rename to examples/system/console/advanced_usb_cdc/README.md index 921793950e..809ec282e0 100644 --- a/examples/system/console_usb/README.md +++ b/examples/system/console/advanced_usb_cdc/README.md @@ -1,11 +1,11 @@ | Supported Targets | ESP32-S2 | | ----------------- | -------- | -# USB Console Example +# USB_OTG CDC Console Example (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example is similar to the [console example](../console/advanced/README.md), but instead of the UART it uses USB CDC for console output. +This example is similar to the [advanced console example](../advanced/README.md), but instead of the UART it uses the USB CDC port provided by USB_OTG peripheral for console output. The example uses the [Console Component](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/console.html#console) to create an interactive shell. The interactive shell implemented in this example contains a wide variety of commands, and can act as a basis for applications that require a command-line interface (CLI). diff --git a/examples/system/console_usb/main/CMakeLists.txt b/examples/system/console/advanced_usb_cdc/main/CMakeLists.txt similarity index 100% rename from examples/system/console_usb/main/CMakeLists.txt rename to examples/system/console/advanced_usb_cdc/main/CMakeLists.txt diff --git a/examples/system/console_usb/main/console_usb_example_main.c b/examples/system/console/advanced_usb_cdc/main/console_usb_example_main.c similarity index 96% rename from examples/system/console_usb/main/console_usb_example_main.c rename to examples/system/console/advanced_usb_cdc/main/console_usb_example_main.c index a4e2168ee0..25f1c6beec 100644 --- a/examples/system/console_usb/main/console_usb_example_main.c +++ b/examples/system/console/advanced_usb_cdc/main/console_usb_example_main.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ /* USB console example This example code is in the Public Domain (or CC0 licensed, at your option.) @@ -15,11 +20,12 @@ #include "esp_console.h" #include "linenoise/linenoise.h" #include "argtable3/argtable3.h" -#include "cmd_nvs.h" -#include "cmd_system.h" #include "esp_vfs_cdcacm.h" #include "nvs.h" #include "nvs_flash.h" +#include "cmd_nvs.h" +#include "cmd_system.h" +#include "cmd_wifi.h" static void initialize_nvs(void) { @@ -80,6 +86,7 @@ void app_main(void) register_system_common(); register_system_sleep(); register_nvs(); + register_wifi(); /* Prompt to be printed before each line. * This can be customized, made dynamic, etc. diff --git a/examples/system/console_usb/sdkconfig.defaults b/examples/system/console/advanced_usb_cdc/sdkconfig.defaults similarity index 100% rename from examples/system/console_usb/sdkconfig.defaults rename to examples/system/console/advanced_usb_cdc/sdkconfig.defaults diff --git a/examples/system/console/basic/README.md b/examples/system/console/basic/README.md index feb2417cee..67a67be03b 100644 --- a/examples/system/console/basic/README.md +++ b/examples/system/console/basic/README.md @@ -1,24 +1,48 @@ -# Console Example +# Basic Console Example (`esp_console_repl`) (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example illustrates the usage of the [Console Component](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/console.html#console) to create an interactive shell on the ESP chip. The interactive shell running on the ESP chip can then be controlled/interacted with over a serial port (UART). +This example illustrates the usage of the REPL (Read-Eval-Print Loop) APIs of the [Console Component](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/console.html#console) to create an interactive shell on the ESP chip. The interactive shell running on the ESP chip can then be controlled/interacted with over a serial interface. This example supports UART and USB interfaces. The interactive shell implemented in this example contains a wide variety of commands, and can act as a basis for applications that require a command-line interface (CLI). +Compared to the [advanced console example](../advanced), this example requires less code to initialize and run the console. `esp_console_repl` API handles most of the details. If you'd like to customize the way console works (for example, process console commands in an existing task), please check the advanced console example. + ## How to use example -### Hardware Required +This example can be used on boards with UART and USB interfaces. The sections below explain how to set up the board and configure the example. -This example should be able to run on any commonly available Espressif development board. +### Using with UART -### Configure the project +When UART interface is used, this example should run on any commonly available Espressif development board. UART interface is enabled by default (`CONFIG_ESP_CONSOLE_UART_DEFAULT` option in menuconfig). No extra configuration is required. -``` -idf.py menuconfig -``` +### Using with USB_SERIAL_JTAG -* Enable/disable `Example Configuration > Store command history in flash` as necessary +On chips with USB_SERIAL_JTAG peripheral, console example can be used over the USB serial port. + +* First, connect the USB cable to the USB_SERIAL_JTAG interface. +* Second, run `idf.py menuconfig` and enable `CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG` option. + +For more details about connecting and configuring USB_SERIAL_JTAG (including pin numbers), see the IDF Programming Guide: +* [ESP32-C3 USB_SERIAL_JTAG](https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/api-guides/usb-serial-jtag-console.html) +* [ESP32-S3 USB_SERIAL_JTAG](https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-guides/usb-serial-jtag-console.html) + +### Using with USB CDC (USB_OTG peripheral) + +USB_OTG peripheral can also provide a USB serial port which works with this example. + +* First, connect the USB cable to the USB_OTG peripheral interface. +* Second, run `idf.py menuconfig` and enable `CONFIG_ESP_CONSOLE_USB_CDC` option. + +For more details about connecting and configuring USB_OTG (including pin numbers), see the IDF Programming Guide: +* [ESP32-S2 USB_OTG](https://docs.espressif.com/projects/esp-idf/en/stable/esp32s2/api-guides/usb-otg-console.html) +* [ESP32-S3 USB_OTG](https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-guides/usb-otg-console.html) + +### Other configuration options + +This example has an option to store the command history in Flash. This option is enabled by default. + +To disable this, run `idf.py menuconfig` and disable `CONFIG_CONSOLE_STORE_HISTORY` option. ### Build and Flash @@ -36,7 +60,9 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ## Example Output -Enter the `help` command get a full list of all available commands. The following is a sample session of the Console Example where a variety of commands provided by the Console Example are used. Note that GPIO15 is connected to GND to remove the boot log output. +Enter the `help` command get a full list of all available commands. The following is a sample session of the Console Example where a variety of commands provided by the Console Example are used. + +On ESP32, GPIO15 may be connected to GND to remove the boot log output. ``` This is an example of ESP-IDF console component. @@ -119,33 +145,3 @@ Line editing and history features are disabled. On Windows, try using Putty instead. esp32> ``` - -## Example Breakdown - -### Configuring UART - -The ``initialize_console()`` function in the example configures some aspects of UART relevant to the operation of the console. - -- **Line Endings**: The default line endings are configured to match those expected/generated by common serial monitor programs, such as `screen`, `minicom`, and the `idf_monitor.py` included in the SDK. The default behavior for these commands are: - - When 'enter' key is pressed on the keyboard, `CR` (0x13) code is sent to the serial device. - - To move the cursor to the beginning of the next line, serial device needs to send `CR LF` (0x13 0x10) sequence. - -### Line editing - -The main source file of the example illustrates how to use `linenoise` library, including line completion, hints, and history. - -### Commands - -Several commands are registered using `esp_console_cmd_register()` function. See the `register_wifi()` and `register_system()` functions in `cmd_wifi.c` and `cmd_system.c` files. - -### Command handling - -Main loop inside `app_main()` function illustrates how to use `linenoise` and `esp_console_run()` to implement read/eval loop. - -### Argument parsing - -Several commands implemented in `cmd_wifi.c` and `cmd_system.c` use the Argtable3 library to parse and check the arguments. - -### Command history - -Each time a new command line is obtained from `linenoise`, it is written into history and the history is saved into a file in flash memory. On reset, history is initialized from that file. diff --git a/examples/system/console/basic/main/CMakeLists.txt b/examples/system/console/basic/main/CMakeLists.txt index 588654505d..6833bf8b62 100644 --- a/examples/system/console/basic/main/CMakeLists.txt +++ b/examples/system/console/basic/main/CMakeLists.txt @@ -1,3 +1,2 @@ -idf_component_register(SRCS "cmd_wifi.c" - "console_example_main.c" +idf_component_register(SRCS "console_example_main.c" INCLUDE_DIRS ".") diff --git a/examples/system/console/basic/main/cmd_decl.h b/examples/system/console/basic/main/cmd_decl.h deleted file mode 100644 index 983b6e974c..0000000000 --- a/examples/system/console/basic/main/cmd_decl.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Console example — declarations of command registration functions. - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "cmd_system.h" -#include "cmd_wifi.h" -#include "cmd_nvs.h" - -#ifdef __cplusplus -} -#endif diff --git a/examples/system/console/basic/main/console_example_main.c b/examples/system/console/basic/main/console_example_main.c index a67fb06314..26fc3d4d5b 100644 --- a/examples/system/console/basic/main/console_example_main.c +++ b/examples/system/console/basic/main/console_example_main.c @@ -1,4 +1,4 @@ -/* Console example +/* Basic console example (esp_console_repl API) This example code is in the Public Domain (or CC0 licensed, at your option.) @@ -13,17 +13,12 @@ #include "esp_log.h" #include "esp_console.h" #include "esp_vfs_dev.h" -#include "driver/uart.h" -#include "linenoise/linenoise.h" -#include "argtable3/argtable3.h" -#include "cmd_decl.h" #include "esp_vfs_fat.h" #include "nvs.h" #include "nvs_flash.h" - -#ifdef CONFIG_ESP_CONSOLE_USB_CDC -#error This example is incompatible with USB CDC console. Please try "console_usb" example instead. -#endif // CONFIG_ESP_CONSOLE_USB_CDC +#include "cmd_system.h" +#include "cmd_wifi.h" +#include "cmd_nvs.h" static const char* TAG = "example"; #define PROMPT_STR CONFIG_IDF_TARGET @@ -66,7 +61,6 @@ void app_main(void) { esp_console_repl_t *repl = NULL; esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); - esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); /* Prompt to be printed before each line. * This can be customized, made dynamic, etc. */ @@ -89,7 +83,21 @@ void app_main(void) register_wifi(); register_nvs(); - ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); +#if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) || defined(CONFIG_ESP_CONSOLE_UART_CUSTOM) + esp_console_dev_uart_config_t hw_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_uart(&hw_config, &repl_config, &repl)); + +#elif defined(CONFIG_ESP_CONSOLE_USB_CDC) + esp_console_dev_usb_cdc_config_t hw_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&hw_config, &repl_config, &repl)); + +#elif defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG) + esp_console_dev_usb_serial_jtag_config_t hw_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&hw_config, &repl_config, &repl)); + +#else +#error Unsupported console type +#endif ESP_ERROR_CHECK(esp_console_start_repl(repl)); }