适配新版本idf。

This commit is contained in:
amass 2025-04-19 11:27:47 +08:00
parent 42420bbd6b
commit 3e43587034
18 changed files with 629 additions and 240 deletions

View File

@ -8,14 +8,14 @@
"ESP_ROM_ELF_DIR": "E:\\Projects\\esp\\.espressif\\tools\\esp-rom-elfs\\20230320/",
"IDF_TARGET": "esp32"
},
"idf.espIdfPathWin": "e:\\Projects\\esp\\v5.4.1\\esp-idf",
"idf.espIdfPathWin": "d:\\Espressif\\esp\\v5.4.1\\esp-idf",
"idf.openOcdConfigs": [
"interface/ftdi/esp32_devkitj_v1.cfg",
"target/esp32.cfg"
],
"idf.portWin": "COM5",
"idf.pythonBinPathWin": "E:\\Projects\\esp\\.espressif\\python_env\\idf5.2_py3.11_env\\Scripts\\python.exe",
"idf.toolsPathWin": "e:\\Projects\\.espressif",
"idf.pythonInstallPath": "e:\\Projects\\.espressif\\tools\\idf-python\\3.11.2\\python.exe",
"idf.toolsPathWin": "d:\\Espressif\\.espressif",
"idf.pythonInstallPath": "d:\\Espressif\\.espressif\\tools\\idf-python\\3.11.2\\python.exe",
"idf.flashType": "UART"
}

View File

@ -1,12 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
DShanMCU-Yat_ESP32
# _Sample project_
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This is the simplest buildable example. The example is used by command `idf.py create-project`
that copies the project to user specified path and set it's name. For more information follow the [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project)

View File

@ -1,10 +1,11 @@
idf_component_register(SRCS
cmd_nvs.h cmd_nvs.c
cmd_system.c
cmd_system_common.c
CustomCommand.cpp
idf_component_register(
SRCS
cmd_nvs.h cmd_nvs.c
cmd_system.c
cmd_system_common.c
cmd_system_sleep.c
cmd_wifi.h cmd_wifi.c
Command.h Command.cpp
INCLUDE_DIRS .
REQUIRES console spi_flash nvs_flash driver esp_wifi LedController Communication
)
target_sources(${COMPONENT_LIB} PRIVATE cmd_system_sleep.c)

View File

@ -0,0 +1,67 @@
#include "Command.h"
#include "Application.h"
#include "LedController.h"
#include "MqttClient.h"
#include "esp_console.h"
#include <argtable3/argtable3.h>
#include <esp_log.h>
#include <iostream>
static int custom_command(int argc, char **argv) {
printf("i am amass.\n");
return 0;
}
static int led_command(int argc, char **argv) {
for (int i = 0; i < argc; i++) {
std::cout << i << " " << argv[i] << std::endl;
}
LedController::instance()->setDuty(static_cast<LedController::Channel>(atoi(argv[1])), atoi(argv[2]));
return 0;
}
static int mqtt_command(int argc, char **argv) {
MqttClient::instance()->initialize(argv[1], argv[2]);
Application::instance()->setField("mqtt_username", std::string(argv[1]));
Application::instance()->setField("mqtt_password", std::string(argv[2]));
return 0;
}
void register_custom() {
const esp_console_cmd_t heap_cmd = {
.command = "amass",
.help = "test command.",
.hint = NULL,
.func = &custom_command,
.argtable = nullptr,
};
ESP_ERROR_CHECK(esp_console_cmd_register(&heap_cmd));
const esp_console_cmd_t led_cmd = {
.command = "led",
.help = "led pwm duty.",
.hint = NULL,
.func = &led_command,
.argtable = nullptr,
};
ESP_ERROR_CHECK(esp_console_cmd_register(&led_cmd));
const esp_console_cmd_t mqtt_cmd = {
.command = "mqtt",
.help = "mqtt client.",
.hint = NULL,
.func = &mqtt_command,
.argtable = nullptr,
};
ESP_ERROR_CHECK(esp_console_cmd_register(&mqtt_cmd));
}
Command::Command()
{
}
Command::~Command()
{
}

View File

@ -0,0 +1,18 @@
#ifndef __COMMAND_H__
#define __COMMAND_H__
#include <list>
#include <string>
class Command {
public:
Command();
~Command();
private:
std::list<std::string> m_commands;
};
void register_custom();
#endif // __COMMAND_H__

View File

@ -1,104 +0,0 @@
#include "CustomCommand.h"
#include "Application.h"
#include "LedController.h"
#include "MqttClient.h"
#include "esp_console.h"
#include <argtable3/argtable3.h>
#include <esp_log.h>
#include <iostream>
static int custom_command(int argc, char **argv) {
printf("i am amass.\n");
return 0;
}
static int led_command(int argc, char **argv) {
for (int i = 0; i < argc; i++) {
std::cout << i << " " << argv[i] << std::endl;
}
LedController::instance()->setDuty(static_cast<LedController::Channel>(atoi(argv[1])), atoi(argv[2]));
return 0;
}
static int mqtt_command(int argc, char **argv) {
MqttClient::instance()->initialize(argv[1], argv[2]);
Application::instance()->setField("mqtt_username", std::string(argv[1]));
Application::instance()->setField("mqtt_password", std::string(argv[2]));
return 0;
}
static struct {
struct arg_int *timeout;
struct arg_str *ssid;
struct arg_str *password;
struct arg_end *end;
} join_args;
static int wifi_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] = Application::WifiJoinTimeoutMillisecond;
}
bool connected = Application::instance()->wifiConnect(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;
}
Application::instance()->setField("ssid", std::string(join_args.ssid->sval[0]));
Application::instance()->setField("psk", std::string(join_args.password->sval[0]));
ESP_LOGI(__func__, "Connected");
return 0;
}
void register_custom() {
const esp_console_cmd_t heap_cmd = {
.command = "amass",
.help = "test command.",
.hint = NULL,
.func = &custom_command,
.argtable = nullptr,
};
ESP_ERROR_CHECK(esp_console_cmd_register(&heap_cmd));
join_args.timeout = arg_int0(NULL, "timeout", "<t>", "Connection timeout, ms");
join_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
join_args.password = arg_str0(NULL, NULL, "<pass>", "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 = &wifi_connect,
.argtable = &join_args,
};
ESP_ERROR_CHECK(esp_console_cmd_register(&join_cmd));
const esp_console_cmd_t led_cmd = {
.command = "led",
.help = "led pwm duty.",
.hint = NULL,
.func = &led_command,
.argtable = nullptr,
};
ESP_ERROR_CHECK(esp_console_cmd_register(&led_cmd));
const esp_console_cmd_t mqtt_cmd = {
.command = "mqtt",
.help = "mqtt client.",
.hint = NULL,
.func = &mqtt_command,
.argtable = nullptr,
};
ESP_ERROR_CHECK(esp_console_cmd_register(&mqtt_cmd));
}

View File

@ -1,11 +0,0 @@
#ifndef __CUSTOMCOMMAND_H__
#define __CUSTOMCOMMAND_H__
void register_custom();
#endif // __CUSTOMCOMMAND_H__

View File

@ -14,5 +14,12 @@
void register_system(void)
{
register_system_common();
register_system_sleep();
#if SOC_LIGHT_SLEEP_SUPPORTED
register_system_light_sleep();
#endif
#if SOC_DEEP_SLEEP_SUPPORTED
register_system_deep_sleep();
#endif
}

View File

@ -19,7 +19,8 @@ void register_system(void);
void register_system_common(void);
// Register deep and light sleep functions
void register_system_sleep(void);
void register_system_deep_sleep(void);
void register_system_light_sleep(void);
#ifdef __cplusplus
}

View File

@ -81,6 +81,12 @@ static int get_version(int argc, char **argv)
case CHIP_ESP32C2:
model = "ESP32-C2";
break;
case CHIP_ESP32P4:
model = "ESP32-P4";
break;
case CHIP_ESP32C5:
model = "ESP32-C5";
break;
default:
model = "Unknown";
break;
@ -153,7 +159,7 @@ static void register_free(void)
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
}
/* 'heap' command prints minumum heap size */
/* 'heap' command prints minimum heap size */
static int heap_size(int argc, char **argv)
{
uint32_t heap_size = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -29,18 +29,8 @@
static const char *TAG = "cmd_system_sleep";
static void register_deep_sleep(void);
static void register_light_sleep(void);
void register_system_sleep(void)
{
register_deep_sleep();
register_light_sleep();
}
#if SOC_DEEP_SLEEP_SUPPORTED
/** 'deep_sleep' command puts the chip into deep sleep mode */
static struct {
struct arg_int *wakeup_time;
#if SOC_PM_SUPPORT_EXT0_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
@ -82,7 +72,7 @@ static int deep_sleep(int argc, char **argv)
ESP_LOGI(TAG, "Enabling wakeup on GPIO%d, wakeup on %s level",
io_num, level ? "HIGH" : "LOW");
ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup(1ULL << io_num, level) );
ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup_io(1ULL << io_num, level) );
ESP_LOGE(TAG, "GPIO wakeup from deep sleep currently unsupported on ESP32-C3");
}
#endif // SOC_PM_SUPPORT_EXT1_WAKEUP
@ -90,12 +80,11 @@ static int deep_sleep(int argc, char **argv)
#if CONFIG_IDF_TARGET_ESP32
rtc_gpio_isolate(GPIO_NUM_12);
#endif //CONFIG_IDF_TARGET_ESP32
esp_deep_sleep_start();
return 1;
}
static void register_deep_sleep(void)
void register_system_deep_sleep(void)
{
int num_args = 1;
deep_sleep_args.wakeup_time =
@ -125,9 +114,10 @@ static void register_deep_sleep(void)
};
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
}
#endif // SOC_DEEP_SLEEP_SUPPORTED
#if SOC_LIGHT_SLEEP_SUPPORTED
/** 'light_sleep' command puts the chip into light sleep mode */
static struct {
struct arg_int *wakeup_time;
struct arg_int *wakeup_gpio_num;
@ -177,6 +167,7 @@ static int light_sleep(int argc, char **argv)
fsync(fileno(stdout));
esp_light_sleep_start();
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
const char *cause_str;
switch (cause) {
case ESP_SLEEP_WAKEUP_GPIO:
@ -196,7 +187,7 @@ static int light_sleep(int argc, char **argv)
return 0;
}
static void register_light_sleep(void)
void register_system_light_sleep(void)
{
light_sleep_args.wakeup_time =
arg_int0("t", "time", "<t>", "Wake up time, ms");
@ -220,3 +211,4 @@ static void register_light_sleep(void)
};
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
}
#endif // SOC_LIGHT_SLEEP_SUPPORTED

View File

@ -0,0 +1,136 @@
/*
* SPDX-FileCopyrightText: 2022-2024 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.)
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 <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "esp_console.h"
#include "argtable3/argtable3.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", "<t>", "Connection timeout, ms");
join_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
join_args.password = arg_str0(NULL, NULL, "<pass>", "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) );
}

View File

@ -0,0 +1,25 @@
/*
* 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.)
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

View File

@ -1,2 +1,6 @@
idf_component_register(SRCS "main.cpp"
INCLUDE_DIRS ".")
idf_component_register(
SRCS
main.cpp
console_settings.h console_settings.c
INCLUDE_DIRS "."
)

19
main/Kconfig.projbuild Normal file
View File

@ -0,0 +1,19 @@
menu "Dual Led Controller Configuration"
config CONSOLE_STORE_HISTORY
bool "Store command history in flash"
default y
help
Linenoise line editing library provides functions to save and load
command history. If this option is enabled, initializes a FAT filesystem
and uses it to store command history.
config CONSOLE_IGNORE_EMPTY_LINES
bool "Ignore empty lines inserted into the console"
default y
help
If an empty line is inserted to the console, the Console can either
ignore empty lines (the example would continue), or break on empty lines
(the example would stop after an empty line).
endmenu

163
main/console_settings.c Normal file
View File

@ -0,0 +1,163 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_console.h"
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#include "driver/uart_vfs.h"
#include "driver/uart.h"
#include "driver/usb_serial_jtag.h"
#include "driver/usb_serial_jtag_vfs.h"
#include "esp_vfs_cdcacm.h"
#include "linenoise/linenoise.h"
#include "argtable3/argtable3.h"
#define CONSOLE_MAX_CMDLINE_ARGS 8
#define CONSOLE_MAX_CMDLINE_LENGTH 256
#define CONSOLE_PROMPT_MAX_LEN (32)
char prompt[CONSOLE_PROMPT_MAX_LEN]; // Prompt to be printed before each line
void initialize_console_peripheral(void)
{
/* Drain stdout before reconfiguring it */
fflush(stdout);
fsync(fileno(stdout));
#if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) || defined(CONFIG_ESP_CONSOLE_UART_CUSTOM)
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */
uart_vfs_dev_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 */
ESP_ERROR_CHECK( uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, 256, 0, 0, NULL, 0) );
ESP_ERROR_CHECK( uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config) );
/* Tell VFS to use UART driver */
uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
#elif defined(CONFIG_ESP_CONSOLE_USB_CDC)
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
esp_vfs_dev_cdcacm_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_cdcacm_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
/* Enable blocking mode on stdin and stdout */
fcntl(fileno(stdout), F_SETFL, 0);
fcntl(fileno(stdin), F_SETFL, 0);
#elif defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG)
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
usb_serial_jtag_vfs_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */
usb_serial_jtag_vfs_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
/* Enable blocking mode on stdin and stdout */
fcntl(fileno(stdout), F_SETFL, 0);
fcntl(fileno(stdin), F_SETFL, 0);
usb_serial_jtag_driver_config_t jtag_config = {
.tx_buffer_size = 256,
.rx_buffer_size = 256,
};
/* Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes */
ESP_ERROR_CHECK( usb_serial_jtag_driver_install(&jtag_config));
/* Tell vfs to use usb-serial-jtag driver */
usb_serial_jtag_vfs_use_driver();
#else
#error Unsupported console type
#endif
/* Disable buffering on stdin */
setvbuf(stdin, NULL, _IONBF, 0);
}
void initialize_console_library(const char *history_path)
{
/* Initialize the console */
esp_console_config_t console_config = {
.max_cmdline_args = CONSOLE_MAX_CMDLINE_ARGS,
.max_cmdline_length = CONSOLE_MAX_CMDLINE_LENGTH,
#if CONFIG_LOG_COLORS
.hint_color = atoi(LOG_COLOR_CYAN)
#endif
};
ESP_ERROR_CHECK( esp_console_init(&console_config) );
/* Configure linenoise line completion library */
/* Enable multiline editing. If not set, long commands will scroll within
* single line.
*/
linenoiseSetMultiLine(1);
/* Tell linenoise where to get command completions and hints */
linenoiseSetCompletionCallback(&esp_console_get_completion);
linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
/* Set command history size */
linenoiseHistorySetMaxLen(100);
/* Set command maximum length */
linenoiseSetMaxLineLen(console_config.max_cmdline_length);
/* Don't return empty lines */
linenoiseAllowEmpty(false);
#if CONFIG_CONSOLE_STORE_HISTORY
/* Load command history from filesystem */
linenoiseHistoryLoad(history_path);
#endif // CONFIG_CONSOLE_STORE_HISTORY
/* Figure out if the terminal supports escape sequences */
const int probe_status = linenoiseProbe();
if (probe_status) { /* zero indicates success */
linenoiseSetDumbMode(1);
}
}
char *setup_prompt(const char *prompt_str)
{
/* set command line prompt */
const char *prompt_temp = "esp>";
if (prompt_str) {
prompt_temp = prompt_str;
}
snprintf(prompt, CONSOLE_PROMPT_MAX_LEN - 1, LOG_COLOR_I "%s " LOG_RESET_COLOR, prompt_temp);
if (linenoiseIsDumbMode()) {
#if CONFIG_LOG_COLORS
/* Since the terminal doesn't support escape sequences,
* don't use color codes in the s_prompt.
*/
snprintf(prompt, CONSOLE_PROMPT_MAX_LEN - 1, "%s ", prompt_temp);
#endif //CONFIG_LOG_COLORS
}
return prompt;
}

46
main/console_settings.h Normal file
View File

@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize console peripheral type
*
* Console peripheral is based on sdkconfig settings
*
* UART CONFIG_ESP_CONSOLE_UART_DEFAULT
* USB_OTG CONFIG_ESP_CONSOLE_USB_CDC
* USB_SERIAL_JTAG CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
*/
void initialize_console_peripheral(void);
/**
* @brief Initialize linenoise and esp console
*
* This function initialize linenoise library and esp_console component,
* also checks if the terminal supports escape sequences
*
* @param history_path Path to store command history
*/
void initialize_console_library(const char *history_path);
/**
* @brief Initialize console prompt
*
* This function adds color code to the prompt (if the console supports escape sequences)
*
* @param prompt_str Prompt in form of string eg esp32s3>
*
* @return
* - pointer to initialized prompt
*/
char *setup_prompt(const char *prompt_str);
#ifdef __cplusplus
}
#endif

View File

@ -1,45 +1,106 @@
#include "Application.h"
#include "CustomCommand.h"
#include "Command.h"
#include "LedController.h"
#include "MqttClient.h"
#include "cmd_nvs.h"
#include "cmd_system.h"
#include "driver/uart.h"
#include "esp_console.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_vfs_fat.h"
#include "linenoise/linenoise.h"
#include "nvs.h"
#include "nvs_flash.h"
#include <driver/uart_vfs.h>
#include <stdio.h>
#include <unistd.h>
#include "cmd_wifi.h"
#include "console_settings.h"
#include <cstring>
#include <esp_console.h>
#include <esp_err.h>
#include <esp_log.h>
#include <esp_vfs_fat.h>
#include <linenoise/linenoise.h>
#include <nvs_flash.h>
/*
* We warn if a secondary serial console is enabled. A secondary serial console is always output-only and
* hence not very useful for interactive console applications. If you encounter this warning, consider disabling
* the secondary serial console in menuconfig unless you know what you are doing.
*/
#if SOC_USB_SERIAL_JTAG_SUPPORTED
#if !CONFIG_ESP_CONSOLE_SECONDARY_NONE
#warning "A secondary serial console is not useful when using the console component. Please disable it in menuconfig."
#endif
#endif
static const char *TAG = "main";
#define PROMPT_STR CONFIG_IDF_TARGET
/* Console command history can be stored to and loaded from a file.
* The easiest way to do this is to use FATFS filesystem on top of
* wear_levelling library.
*/
#if CONFIG_CONSOLE_STORE_HISTORY
#define MOUNT_PATH "/data"
#define HISTORY_PATH MOUNT_PATH "/history.txt"
static const char *TAG = "main";
static void initialize_filesystem(void) {
static wl_handle_t wl_handle;
const esp_vfs_fat_mount_config_t mount_config = {
.format_if_mount_failed = true,
.max_files = 4,
static void initialize_nvs();
static void initialize_filesystem();
static void initialize_console();
};
esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(MOUNT_PATH, "storage", &mount_config, &wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
return;
}
}
#else
#define HISTORY_PATH NULL
#endif // CONFIG_CONSOLE_STORE_HISTORY
static void initialize_nvs(void) {
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
}
extern "C" void app_main() {
const char *prompt = LOG_COLOR_I PROMPT_STR "> " LOG_RESET_COLOR;
initialize_nvs();
#if CONFIG_CONSOLE_STORE_HISTORY
initialize_filesystem();
initialize_console();
ESP_LOGI(TAG, "Command history enabled");
#else
ESP_LOGI(TAG, "Command history disabled");
#endif
/* Initialize console output periheral (UART, USB_OTG, USB_JTAG) */
initialize_console_peripheral();
/* Initialize linenoise library and esp_console*/
initialize_console_library(HISTORY_PATH);
/* Prompt to be printed before each line.
* This can be customized, made dynamic, etc.
*/
const char *prompt = setup_prompt(PROMPT_STR ">");
Application::instance()->initialize();
/* Register commands */
esp_console_register_help_command();
register_system_common();
register_system_sleep();
register_custom();
#if SOC_LIGHT_SLEEP_SUPPORTED
register_system_light_sleep();
#endif
#if SOC_DEEP_SLEEP_SUPPORTED
register_system_deep_sleep();
#endif
#if (CONFIG_ESP_WIFI_ENABLED || CONFIG_ESP_HOST_WIFI_ENABLED)
register_wifi();
#endif
register_nvs();
register_custom();
LedController::instance()->initialize();
if (Application::instance()->contains("brightness")) {
int brightness = Application::instance()->field<int>("brightness");
@ -70,17 +131,41 @@ extern "C" void app_main() {
}
}
if (linenoiseIsDumbMode()) {
printf("\n"
"Your terminal application does not support escape sequences.\n"
"Line editing and history features are disabled.\n"
"On Windows, try using Putty instead.\n");
}
/* Main loop */
while (true) {
/* Get a line using linenoise.
* The line is returned when ENTER is pressed.
*/
char *line = linenoise(prompt);
if (line == NULL) { /* Break on EOF or error */
// break;
#if CONFIG_CONSOLE_IGNORE_EMPTY_LINES
if (line == NULL) { /* Ignore empty lines */
continue;
;
}
#else
if (line == NULL) { /* Break on EOF or error */
break;
}
#endif // CONFIG_CONSOLE_IGNORE_EMPTY_LINES
/* Add the command to the history if not empty*/
if (strlen(line) > 0) {
linenoiseHistoryAdd(line);
#if CONFIG_CONSOLE_STORE_HISTORY
/* Save command history to filesystem */
linenoiseHistorySave(HISTORY_PATH);
#endif // CONFIG_CONSOLE_STORE_HISTORY
}
/* Try to run the command */
int ret;
esp_err_t err = esp_console_run(line, &ret);
if (err == ESP_ERR_NOT_FOUND) {
@ -95,66 +180,7 @@ extern "C" void app_main() {
/* linenoise allocates line buffer on the heap, so need to free it */
linenoiseFree(line);
}
ESP_LOGE(TAG, "Error or end-of-input, terminating console");
esp_console_deinit();
}
static void initialize_console() {
fflush(stdout);
fsync(fileno(stdout));
setvbuf(stdin, NULL, _IONBF, 0);
uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
uart_config_t uart_config = {};
uart_config.baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
uart_config.data_bits = UART_DATA_8_BITS;
uart_config.parity = UART_PARITY_DISABLE;
uart_config.stop_bits = UART_STOP_BITS_1;
uart_config.source_clk = UART_SCLK_REF_TICK;
ESP_ERROR_CHECK(uart_driver_install(static_cast<uart_port_t>(CONFIG_ESP_CONSOLE_UART_NUM), 256, 0, 0, NULL, 0));
ESP_ERROR_CHECK(uart_param_config(static_cast<uart_port_t>(CONFIG_ESP_CONSOLE_UART_NUM), &uart_config));
uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
esp_console_config_t console_config = {};
console_config.max_cmdline_args = 8;
console_config.max_cmdline_length = 256;
console_config.hint_color = atoi(LOG_COLOR_CYAN);
ESP_ERROR_CHECK(esp_console_init(&console_config));
linenoiseSetMultiLine(1);
linenoiseSetCompletionCallback(&esp_console_get_completion);
linenoiseSetHintsCallback((linenoiseHintsCallback *)&esp_console_get_hint);
linenoiseHistorySetMaxLen(100);
linenoiseSetMaxLineLen(console_config.max_cmdline_length);
linenoiseAllowEmpty(false);
linenoiseHistoryLoad(HISTORY_PATH);
}
static void initialize_nvs() {
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
}
static void initialize_filesystem(void) {
static wl_handle_t wl_handle;
esp_vfs_fat_mount_config_t config;
memset(&config, 0, sizeof(esp_vfs_fat_mount_config_t));
config.max_files = 4;
config.format_if_mount_failed = true;
esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(MOUNT_PATH, "storage", &config, &wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
return;
}
}