console_example_main.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /* Console example
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "esp_system.h"
  10. #include "esp_log.h"
  11. #include "esp_console.h"
  12. #include "esp_vfs_dev.h"
  13. #include "driver/uart.h"
  14. #include "linenoise/linenoise.h"
  15. #include "argtable3/argtable3.h"
  16. #include "esp_vfs_fat.h"
  17. #include "nvs.h"
  18. #include "nvs_flash.h"
  19. #include "soc/soc_caps.h"
  20. #include "cmd_system.h"
  21. #include "cmd_wifi.h"
  22. #include "cmd_nvs.h"
  23. /*
  24. * We warn if a secondary serial console is enabled. A secondary serial console is always output-only and
  25. * hence not very useful for interactive console applications. If you encounter this warning, consider disabling
  26. * the secondary serial console in menuconfig unless you know what you are doing.
  27. */
  28. #if SOC_USB_SERIAL_JTAG_SUPPORTED
  29. #if !CONFIG_ESP_CONSOLE_SECONDARY_NONE
  30. #warning "A secondary serial console is not useful when using the console component. Please disable it in menuconfig."
  31. #endif
  32. #endif
  33. #ifdef CONFIG_ESP_CONSOLE_USB_CDC
  34. #error This example is incompatible with USB CDC console. Please try "console_usb" example instead.
  35. #endif // CONFIG_ESP_CONSOLE_USB_CDC
  36. #ifdef CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
  37. #error This example is incompatible with USB serial JTAG console.
  38. #endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
  39. static const char* TAG = "example";
  40. #define PROMPT_STR CONFIG_IDF_TARGET
  41. /* Console command history can be stored to and loaded from a file.
  42. * The easiest way to do this is to use FATFS filesystem on top of
  43. * wear_levelling library.
  44. */
  45. #if CONFIG_STORE_HISTORY
  46. #define MOUNT_PATH "/data"
  47. #define HISTORY_PATH MOUNT_PATH "/history.txt"
  48. static void initialize_filesystem(void)
  49. {
  50. static wl_handle_t wl_handle;
  51. const esp_vfs_fat_mount_config_t mount_config = {
  52. .max_files = 4,
  53. .format_if_mount_failed = true
  54. };
  55. esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(MOUNT_PATH, "storage", &mount_config, &wl_handle);
  56. if (err != ESP_OK) {
  57. ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
  58. return;
  59. }
  60. }
  61. #endif // CONFIG_STORE_HISTORY
  62. static void initialize_nvs(void)
  63. {
  64. esp_err_t err = nvs_flash_init();
  65. if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  66. ESP_ERROR_CHECK( nvs_flash_erase() );
  67. err = nvs_flash_init();
  68. }
  69. ESP_ERROR_CHECK(err);
  70. }
  71. static void initialize_console(void)
  72. {
  73. /* Drain stdout before reconfiguring it */
  74. fflush(stdout);
  75. fsync(fileno(stdout));
  76. /* Disable buffering on stdin */
  77. setvbuf(stdin, NULL, _IONBF, 0);
  78. /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
  79. esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
  80. /* Move the caret to the beginning of the next line on '\n' */
  81. esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
  82. /* Configure UART. Note that REF_TICK is used so that the baud rate remains
  83. * correct while APB frequency is changing in light sleep mode.
  84. */
  85. const uart_config_t uart_config = {
  86. .baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE,
  87. .data_bits = UART_DATA_8_BITS,
  88. .parity = UART_PARITY_DISABLE,
  89. .stop_bits = UART_STOP_BITS_1,
  90. #if SOC_UART_SUPPORT_REF_TICK
  91. .source_clk = UART_SCLK_REF_TICK,
  92. #elif SOC_UART_SUPPORT_XTAL_CLK
  93. .source_clk = UART_SCLK_XTAL,
  94. #endif
  95. };
  96. /* Install UART driver for interrupt-driven reads and writes */
  97. ESP_ERROR_CHECK( uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM,
  98. 256, 0, 0, NULL, 0) );
  99. ESP_ERROR_CHECK( uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config) );
  100. /* Tell VFS to use UART driver */
  101. esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
  102. /* Initialize the console */
  103. esp_console_config_t console_config = {
  104. .max_cmdline_args = 8,
  105. .max_cmdline_length = 256,
  106. #if CONFIG_LOG_COLORS
  107. .hint_color = atoi(LOG_COLOR_CYAN)
  108. #endif
  109. };
  110. ESP_ERROR_CHECK( esp_console_init(&console_config) );
  111. /* Configure linenoise line completion library */
  112. /* Enable multiline editing. If not set, long commands will scroll within
  113. * single line.
  114. */
  115. linenoiseSetMultiLine(1);
  116. /* Tell linenoise where to get command completions and hints */
  117. linenoiseSetCompletionCallback(&esp_console_get_completion);
  118. linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
  119. /* Set command history size */
  120. linenoiseHistorySetMaxLen(100);
  121. /* Set command maximum length */
  122. linenoiseSetMaxLineLen(console_config.max_cmdline_length);
  123. /* Don't return empty lines */
  124. linenoiseAllowEmpty(false);
  125. #if CONFIG_STORE_HISTORY
  126. /* Load command history from filesystem */
  127. linenoiseHistoryLoad(HISTORY_PATH);
  128. #endif
  129. }
  130. void app_main(void)
  131. {
  132. initialize_nvs();
  133. #if CONFIG_STORE_HISTORY
  134. initialize_filesystem();
  135. ESP_LOGI(TAG, "Command history enabled");
  136. #else
  137. ESP_LOGI(TAG, "Command history disabled");
  138. #endif
  139. initialize_console();
  140. /* Register commands */
  141. esp_console_register_help_command();
  142. register_system_common();
  143. register_system_sleep();
  144. #if SOC_WIFI_SUPPORTED
  145. register_wifi();
  146. #endif
  147. register_nvs();
  148. /* Prompt to be printed before each line.
  149. * This can be customized, made dynamic, etc.
  150. */
  151. const char* prompt = LOG_COLOR_I PROMPT_STR "> " LOG_RESET_COLOR;
  152. printf("\n"
  153. "This is an example of ESP-IDF console component.\n"
  154. "Type 'help' to get the list of commands.\n"
  155. "Use UP/DOWN arrows to navigate through command history.\n"
  156. "Press TAB when typing command name to auto-complete.\n"
  157. "Press Enter or Ctrl+C will terminate the console environment.\n");
  158. /* Figure out if the terminal supports escape sequences */
  159. int probe_status = linenoiseProbe();
  160. if (probe_status) { /* zero indicates success */
  161. printf("\n"
  162. "Your terminal application does not support escape sequences.\n"
  163. "Line editing and history features are disabled.\n"
  164. "On Windows, try using Putty instead.\n");
  165. linenoiseSetDumbMode(1);
  166. #if CONFIG_LOG_COLORS
  167. /* Since the terminal doesn't support escape sequences,
  168. * don't use color codes in the prompt.
  169. */
  170. prompt = PROMPT_STR "> ";
  171. #endif //CONFIG_LOG_COLORS
  172. }
  173. /* Main loop */
  174. while(true) {
  175. /* Get a line using linenoise.
  176. * The line is returned when ENTER is pressed.
  177. */
  178. char* line = linenoise(prompt);
  179. if (line == NULL) { /* Break on EOF or error */
  180. break;
  181. }
  182. /* Add the command to the history if not empty*/
  183. if (strlen(line) > 0) {
  184. linenoiseHistoryAdd(line);
  185. #if CONFIG_STORE_HISTORY
  186. /* Save command history to filesystem */
  187. linenoiseHistorySave(HISTORY_PATH);
  188. #endif
  189. }
  190. /* Try to run the command */
  191. int ret;
  192. esp_err_t err = esp_console_run(line, &ret);
  193. if (err == ESP_ERR_NOT_FOUND) {
  194. printf("Unrecognized command\n");
  195. } else if (err == ESP_ERR_INVALID_ARG) {
  196. // command was empty
  197. } else if (err == ESP_OK && ret != ESP_OK) {
  198. printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret));
  199. } else if (err != ESP_OK) {
  200. printf("Internal error: %s\n", esp_err_to_name(err));
  201. }
  202. /* linenoise allocates line buffer on the heap, so need to free it */
  203. linenoiseFree(line);
  204. }
  205. ESP_LOGE(TAG, "Error or end-of-input, terminating console");
  206. esp_console_deinit();
  207. }