Procházet zdrojové kódy

examples: re-enable console examples for C2, C6, H2

- Split the sleep-related system commands into a separate file
- Don't compile that file and don't register sleep commands for H2 yet
- Exclude Wi-Fi commands if the chip doesn't have Wi-Fi
Ivan Grokhotkov před 2 roky
rodič
revize
bb3f1fd261

+ 4 - 14
examples/system/.build-test-rules.yml

@@ -13,14 +13,9 @@ examples/system/base_mac_address:
       reason: cannot pass, IDF-6809
 
 examples/system/console/advanced:
-  disable:
-    - if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2"]
-      temporary: true
-      reason: target(s) not supported yet
   disable_test:
-    - if: IDF_TARGET in ["esp32s2", "esp32s3"]
-      temporary: true
-      reason: lack of runners
+    - if: IDF_TARGET not in ["esp32", "esp32c3"]
+      reason: Sufficient to run this app on one chip with each architecture
 
 examples/system/console/advanced_usb_cdc:
   enable:
@@ -29,14 +24,9 @@ examples/system/console/advanced_usb_cdc:
       reason: the other targets are not tested yet
 
 examples/system/console/basic:
-  disable:
-    - if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2"]
-      temporary: true
-      reason: target(s) not supported yet
   disable_test:
-    - if: IDF_TARGET in ["esp32s2", "esp32s3"]
-      temporary: true
-      reason: lack of runners
+    - if: IDF_TARGET not in ["esp32", "esp32c3"]
+      reason: Sufficient to run this app on one chip with each architecture
 
 examples/system/deep_sleep:
   disable:

+ 2 - 2
examples/system/console/advanced/README.md

@@ -1,5 +1,5 @@
-| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
-| ----------------- | ----- | -------- | -------- | -------- |
+| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
+| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
 
 # Console Example
 

+ 5 - 1
examples/system/console/advanced/components/cmd_system/CMakeLists.txt

@@ -1,3 +1,7 @@
-idf_component_register(SRCS "cmd_system.c"
+idf_component_register(SRCS "cmd_system.c" "cmd_system_common.c"
                     INCLUDE_DIRS .
                     REQUIRES console spi_flash driver)
+
+if(NOT CONFIG_IDF_TARGET_ESP32H2)  # IDF-6268
+    target_sources(${COMPONENT_LIB} PRIVATE cmd_system_sleep.c)
+endif()

+ 2 - 449
examples/system/console/advanced/components/cmd_system/cmd_system.c

@@ -7,461 +7,14 @@
    CONDITIONS OF ANY KIND, either express or implied.
 */
 
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include "esp_log.h"
-#include "esp_console.h"
-#include "esp_chip_info.h"
-#include "esp_sleep.h"
-#include "esp_flash.h"
-#include "driver/rtc_io.h"
-#include "driver/uart.h"
-#include "argtable3/argtable3.h"
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
+
 #include "cmd_system.h"
 #include "sdkconfig.h"
 
-#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
-#define WITH_TASKS_INFO 1
-#endif
-
-static const char *TAG = "cmd_system";
-
-static void register_free(void);
-static void register_heap(void);
-static void register_version(void);
-static void register_restart(void);
-static void register_deep_sleep(void);
-static void register_light_sleep(void);
-#if WITH_TASKS_INFO
-static void register_tasks(void);
-#endif
-static void register_log_level(void);
-
-void register_system_common(void)
-{
-    register_free();
-    register_heap();
-    register_version();
-    register_restart();
-#if WITH_TASKS_INFO
-    register_tasks();
-#endif
-    register_log_level();
-}
-
-void register_system_sleep(void)
-{
-    register_deep_sleep();
-    register_light_sleep();
-}
-
 void register_system(void)
 {
     register_system_common();
+#ifndef CONFIG_IDF_TARGET_ESP32H2  // IDF-6268
     register_system_sleep();
-}
-
-/* 'version' command */
-static int get_version(int argc, char **argv)
-{
-    const char *model;
-    esp_chip_info_t info;
-    uint32_t flash_size;
-    esp_chip_info(&info);
-
-    switch(info.model) {
-        case CHIP_ESP32:
-            model = "ESP32";
-            break;
-        case CHIP_ESP32S2:
-            model = "ESP32-S2";
-            break;
-        case CHIP_ESP32S3:
-            model = "ESP32-S3";
-            break;
-        case CHIP_ESP32C3:
-            model = "ESP32-C3";
-            break;
-        case CHIP_ESP32H4:
-            model = "ESP32-H4";
-            break;
-        case CHIP_ESP32C2:
-            model = "ESP32-C2";
-            break;
-        default:
-            model = "Unknown";
-            break;
-    }
-
-    if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
-        printf("Get flash size failed");
-        return 1;
-    }
-    printf("IDF Version:%s\r\n", esp_get_idf_version());
-    printf("Chip info:\r\n");
-    printf("\tmodel:%s\r\n", model);
-    printf("\tcores:%d\r\n", info.cores);
-    printf("\tfeature:%s%s%s%s%"PRIu32"%s\r\n",
-           info.features & CHIP_FEATURE_WIFI_BGN ? "/802.11bgn" : "",
-           info.features & CHIP_FEATURE_BLE ? "/BLE" : "",
-           info.features & CHIP_FEATURE_BT ? "/BT" : "",
-           info.features & CHIP_FEATURE_EMB_FLASH ? "/Embedded-Flash:" : "/External-Flash:",
-           flash_size / (1024 * 1024), " MB");
-    printf("\trevision number:%d\r\n", info.revision);
-    return 0;
-}
-
-static void register_version(void)
-{
-    const esp_console_cmd_t cmd = {
-        .command = "version",
-        .help = "Get version of chip and SDK",
-        .hint = NULL,
-        .func = &get_version,
-    };
-    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
-}
-
-/** 'restart' command restarts the program */
-
-static int restart(int argc, char **argv)
-{
-    ESP_LOGI(TAG, "Restarting");
-    esp_restart();
-}
-
-static void register_restart(void)
-{
-    const esp_console_cmd_t cmd = {
-        .command = "restart",
-        .help = "Software reset of the chip",
-        .hint = NULL,
-        .func = &restart,
-    };
-    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
-}
-
-/** 'free' command prints available heap memory */
-
-static int free_mem(int argc, char **argv)
-{
-    printf("%"PRIu32"\n", esp_get_free_heap_size());
-    return 0;
-}
-
-static void register_free(void)
-{
-    const esp_console_cmd_t cmd = {
-        .command = "free",
-        .help = "Get the current size of free heap memory",
-        .hint = NULL,
-        .func = &free_mem,
-    };
-    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
-}
-
-/* 'heap' command prints minumum heap size */
-static int heap_size(int argc, char **argv)
-{
-    uint32_t heap_size = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);
-    printf("min heap size: %"PRIu32"\n", heap_size);
-    return 0;
-}
-
-static void register_heap(void)
-{
-    const esp_console_cmd_t heap_cmd = {
-        .command = "heap",
-        .help = "Get minimum size of free heap memory that was available during program execution",
-        .hint = NULL,
-        .func = &heap_size,
-    };
-    ESP_ERROR_CHECK( esp_console_cmd_register(&heap_cmd) );
-
-}
-
-/** 'tasks' command prints the list of tasks and related information */
-#if WITH_TASKS_INFO
-
-static int tasks_info(int argc, char **argv)
-{
-    const size_t bytes_per_task = 40; /* see vTaskList description */
-    char *task_list_buffer = malloc(uxTaskGetNumberOfTasks() * bytes_per_task);
-    if (task_list_buffer == NULL) {
-        ESP_LOGE(TAG, "failed to allocate buffer for vTaskList output");
-        return 1;
-    }
-    fputs("Task Name\tStatus\tPrio\tHWM\tTask#", stdout);
-#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
-    fputs("\tAffinity", stdout);
-#endif
-    fputs("\n", stdout);
-    vTaskList(task_list_buffer);
-    fputs(task_list_buffer, stdout);
-    free(task_list_buffer);
-    return 0;
-}
-
-static void register_tasks(void)
-{
-    const esp_console_cmd_t cmd = {
-        .command = "tasks",
-        .help = "Get information about running tasks",
-        .hint = NULL,
-        .func = &tasks_info,
-    };
-    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
-}
-
-#endif // WITH_TASKS_INFO
-
-/** '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
-    struct arg_int *wakeup_gpio_num;
-    struct arg_int *wakeup_gpio_level;
-#endif
-    struct arg_end *end;
-} deep_sleep_args;
-
-
-static int deep_sleep(int argc, char **argv)
-{
-    int nerrors = arg_parse(argc, argv, (void **) &deep_sleep_args);
-    if (nerrors != 0) {
-        arg_print_errors(stderr, deep_sleep_args.end, argv[0]);
-        return 1;
-    }
-    if (deep_sleep_args.wakeup_time->count) {
-        uint64_t timeout = 1000ULL * deep_sleep_args.wakeup_time->ival[0];
-        ESP_LOGI(TAG, "Enabling timer wakeup, timeout=%lluus", timeout);
-        ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) );
-    }
-
-#if SOC_PM_SUPPORT_EXT1_WAKEUP
-    if (deep_sleep_args.wakeup_gpio_num->count) {
-        int io_num = deep_sleep_args.wakeup_gpio_num->ival[0];
-        if (!esp_sleep_is_valid_wakeup_gpio(io_num)) {
-            ESP_LOGE(TAG, "GPIO %d is not an RTC IO", io_num);
-            return 1;
-        }
-        int level = 0;
-        if (deep_sleep_args.wakeup_gpio_level->count) {
-            level = deep_sleep_args.wakeup_gpio_level->ival[0];
-            if (level != 0 && level != 1) {
-                ESP_LOGE(TAG, "Invalid wakeup level: %d", level);
-                return 1;
-            }
-        }
-        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_LOGE(TAG, "GPIO wakeup from deep sleep currently unsupported on ESP32-C3");
-    }
-#endif // SOC_PM_SUPPORT_EXT1_WAKEUP
-
-#if CONFIG_IDF_TARGET_ESP32
-    rtc_gpio_isolate(GPIO_NUM_12);
-#endif //CONFIG_IDF_TARGET_ESP32
-
-    esp_deep_sleep_start();
-}
-
-static void register_deep_sleep(void)
-{
-    int num_args = 1;
-    deep_sleep_args.wakeup_time =
-        arg_int0("t", "time", "<t>", "Wake up time, ms");
-#if SOC_PM_SUPPORT_EXT0_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
-    deep_sleep_args.wakeup_gpio_num =
-        arg_int0(NULL, "io", "<n>",
-                 "If specified, wakeup using GPIO with given number");
-    deep_sleep_args.wakeup_gpio_level =
-        arg_int0(NULL, "io_level", "<0|1>", "GPIO level to trigger wakeup");
-    num_args += 2;
 #endif
-    deep_sleep_args.end = arg_end(num_args);
-
-    const esp_console_cmd_t cmd = {
-        .command = "deep_sleep",
-        .help = "Enter deep sleep mode. "
-#if SOC_PM_SUPPORT_EXT0_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
-        "Two wakeup modes are supported: timer and GPIO. "
-#else
-        "Timer wakeup mode is supported. "
-#endif
-        "If no wakeup option is specified, will sleep indefinitely.",
-        .hint = NULL,
-        .func = &deep_sleep,
-        .argtable = &deep_sleep_args
-    };
-    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
-}
-
-/** 'light_sleep' command puts the chip into light sleep mode */
-
-static struct {
-    struct arg_int *wakeup_time;
-    struct arg_int *wakeup_gpio_num;
-    struct arg_int *wakeup_gpio_level;
-    struct arg_end *end;
-} light_sleep_args;
-
-static int light_sleep(int argc, char **argv)
-{
-    int nerrors = arg_parse(argc, argv, (void **) &light_sleep_args);
-    if (nerrors != 0) {
-        arg_print_errors(stderr, light_sleep_args.end, argv[0]);
-        return 1;
-    }
-    esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
-    if (light_sleep_args.wakeup_time->count) {
-        uint64_t timeout = 1000ULL * light_sleep_args.wakeup_time->ival[0];
-        ESP_LOGI(TAG, "Enabling timer wakeup, timeout=%lluus", timeout);
-        ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) );
-    }
-    int io_count = light_sleep_args.wakeup_gpio_num->count;
-    if (io_count != light_sleep_args.wakeup_gpio_level->count) {
-        ESP_LOGE(TAG, "Should have same number of 'io' and 'io_level' arguments");
-        return 1;
-    }
-    for (int i = 0; i < io_count; ++i) {
-        int io_num = light_sleep_args.wakeup_gpio_num->ival[i];
-        int level = light_sleep_args.wakeup_gpio_level->ival[i];
-        if (level != 0 && level != 1) {
-            ESP_LOGE(TAG, "Invalid wakeup level: %d", level);
-            return 1;
-        }
-        ESP_LOGI(TAG, "Enabling wakeup on GPIO%d, wakeup on %s level",
-                 io_num, level ? "HIGH" : "LOW");
-
-        ESP_ERROR_CHECK( gpio_wakeup_enable(io_num, level ? GPIO_INTR_HIGH_LEVEL : GPIO_INTR_LOW_LEVEL) );
-    }
-    if (io_count > 0) {
-        ESP_ERROR_CHECK( esp_sleep_enable_gpio_wakeup() );
-    }
-    if (CONFIG_ESP_CONSOLE_UART_NUM >= 0 && CONFIG_ESP_CONSOLE_UART_NUM <= UART_NUM_1) {
-        ESP_LOGI(TAG, "Enabling UART wakeup (press ENTER to exit light sleep)");
-        ESP_ERROR_CHECK( uart_set_wakeup_threshold(CONFIG_ESP_CONSOLE_UART_NUM, 3) );
-        ESP_ERROR_CHECK( esp_sleep_enable_uart_wakeup(CONFIG_ESP_CONSOLE_UART_NUM) );
-    }
-    fflush(stdout);
-    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:
-        cause_str = "GPIO";
-        break;
-    case ESP_SLEEP_WAKEUP_UART:
-        cause_str = "UART";
-        break;
-    case ESP_SLEEP_WAKEUP_TIMER:
-        cause_str = "timer";
-        break;
-    default:
-        cause_str = "unknown";
-        printf("%d\n", cause);
-    }
-    ESP_LOGI(TAG, "Woke up from: %s", cause_str);
-    return 0;
-}
-
-static void register_light_sleep(void)
-{
-    light_sleep_args.wakeup_time =
-        arg_int0("t", "time", "<t>", "Wake up time, ms");
-    light_sleep_args.wakeup_gpio_num =
-        arg_intn(NULL, "io", "<n>", 0, 8,
-                 "If specified, wakeup using GPIO with given number");
-    light_sleep_args.wakeup_gpio_level =
-        arg_intn(NULL, "io_level", "<0|1>", 0, 8, "GPIO level to trigger wakeup");
-    light_sleep_args.end = arg_end(3);
-
-    const esp_console_cmd_t cmd = {
-        .command = "light_sleep",
-        .help = "Enter light sleep mode. "
-        "Two wakeup modes are supported: timer and GPIO. "
-        "Multiple GPIO pins can be specified using pairs of "
-        "'io' and 'io_level' arguments. "
-        "Will also wake up on UART input.",
-        .hint = NULL,
-        .func = &light_sleep,
-        .argtable = &light_sleep_args
-    };
-    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
-}
-
-/** log_level command changes log level via esp_log_level_set */
-
-static struct {
-    struct arg_str *tag;
-    struct arg_str *level;
-    struct arg_end *end;
-} log_level_args;
-
-static const char* s_log_level_names[] = {
-    "none",
-    "error",
-    "warn",
-    "info",
-    "debug",
-    "verbose"
-};
-
-static int log_level(int argc, char **argv)
-{
-    int nerrors = arg_parse(argc, argv, (void **) &log_level_args);
-    if (nerrors != 0) {
-        arg_print_errors(stderr, log_level_args.end, argv[0]);
-        return 1;
-    }
-    assert(log_level_args.tag->count == 1);
-    assert(log_level_args.level->count == 1);
-    const char* tag = log_level_args.tag->sval[0];
-    const char* level_str = log_level_args.level->sval[0];
-    esp_log_level_t level;
-    size_t level_len = strlen(level_str);
-    for (level = ESP_LOG_NONE; level <= ESP_LOG_VERBOSE; level++) {
-        if (memcmp(level_str, s_log_level_names[level], level_len) == 0) {
-            break;
-        }
-    }
-    if (level > ESP_LOG_VERBOSE) {
-        printf("Invalid log level '%s', choose from none|error|warn|info|debug|verbose\n", level_str);
-        return 1;
-    }
-    if (level > CONFIG_LOG_MAXIMUM_LEVEL) {
-        printf("Can't set log level to %s, max level limited in menuconfig to %s. "
-               "Please increase CONFIG_LOG_MAXIMUM_LEVEL in menuconfig.\n",
-               s_log_level_names[level], s_log_level_names[CONFIG_LOG_MAXIMUM_LEVEL]);
-        return 1;
-    }
-    esp_log_level_set(tag, level);
-    return 0;
-}
-
-static void register_log_level(void)
-{
-    log_level_args.tag = arg_str1(NULL, NULL, "<tag|*>", "Log tag to set the level for, or * to set for all tags");
-    log_level_args.level = arg_str1(NULL, NULL, "<none|error|warn|debug|verbose>", "Log level to set. Abbreviated words are accepted.");
-    log_level_args.end = arg_end(2);
-
-    const esp_console_cmd_t cmd = {
-        .command = "log_level",
-        .help = "Set log level for all tags or a specific tag.",
-        .hint = NULL,
-        .func = &log_level,
-        .argtable = &log_level_args
-    };
-    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
 }

+ 274 - 0
examples/system/console/advanced/components/cmd_system/cmd_system_common.c

@@ -0,0 +1,274 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
+ */
+/* Console example — various system 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 <ctype.h>
+#include <inttypes.h>
+#include "esp_log.h"
+#include "esp_console.h"
+#include "esp_chip_info.h"
+#include "esp_flash.h"
+#include "argtable3/argtable3.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "cmd_system.h"
+#include "sdkconfig.h"
+
+#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
+#define WITH_TASKS_INFO 1
+#endif
+
+static const char *TAG = "cmd_system_common";
+
+static void register_free(void);
+static void register_heap(void);
+static void register_version(void);
+static void register_restart(void);
+#if WITH_TASKS_INFO
+static void register_tasks(void);
+#endif
+static void register_log_level(void);
+
+void register_system_common(void)
+{
+    register_free();
+    register_heap();
+    register_version();
+    register_restart();
+#if WITH_TASKS_INFO
+    register_tasks();
+#endif
+    register_log_level();
+}
+
+
+/* 'version' command */
+static int get_version(int argc, char **argv)
+{
+    const char *model;
+    esp_chip_info_t info;
+    uint32_t flash_size;
+    esp_chip_info(&info);
+
+    switch(info.model) {
+        case CHIP_ESP32:
+            model = "ESP32";
+            break;
+        case CHIP_ESP32S2:
+            model = "ESP32-S2";
+            break;
+        case CHIP_ESP32S3:
+            model = "ESP32-S3";
+            break;
+        case CHIP_ESP32C3:
+            model = "ESP32-C3";
+            break;
+        case CHIP_ESP32H4:
+            model = "ESP32-H4";
+            break;
+        case CHIP_ESP32C2:
+            model = "ESP32-C2";
+            break;
+        default:
+            model = "Unknown";
+            break;
+    }
+
+    if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
+        printf("Get flash size failed");
+        return 1;
+    }
+    printf("IDF Version:%s\r\n", esp_get_idf_version());
+    printf("Chip info:\r\n");
+    printf("\tmodel:%s\r\n", model);
+    printf("\tcores:%d\r\n", info.cores);
+    printf("\tfeature:%s%s%s%s%"PRIu32"%s\r\n",
+           info.features & CHIP_FEATURE_WIFI_BGN ? "/802.11bgn" : "",
+           info.features & CHIP_FEATURE_BLE ? "/BLE" : "",
+           info.features & CHIP_FEATURE_BT ? "/BT" : "",
+           info.features & CHIP_FEATURE_EMB_FLASH ? "/Embedded-Flash:" : "/External-Flash:",
+           flash_size / (1024 * 1024), " MB");
+    printf("\trevision number:%d\r\n", info.revision);
+    return 0;
+}
+
+static void register_version(void)
+{
+    const esp_console_cmd_t cmd = {
+        .command = "version",
+        .help = "Get version of chip and SDK",
+        .hint = NULL,
+        .func = &get_version,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+/** 'restart' command restarts the program */
+
+static int restart(int argc, char **argv)
+{
+    ESP_LOGI(TAG, "Restarting");
+    esp_restart();
+}
+
+static void register_restart(void)
+{
+    const esp_console_cmd_t cmd = {
+        .command = "restart",
+        .help = "Software reset of the chip",
+        .hint = NULL,
+        .func = &restart,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+/** 'free' command prints available heap memory */
+
+static int free_mem(int argc, char **argv)
+{
+    printf("%"PRIu32"\n", esp_get_free_heap_size());
+    return 0;
+}
+
+static void register_free(void)
+{
+    const esp_console_cmd_t cmd = {
+        .command = "free",
+        .help = "Get the current size of free heap memory",
+        .hint = NULL,
+        .func = &free_mem,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+/* 'heap' command prints minumum heap size */
+static int heap_size(int argc, char **argv)
+{
+    uint32_t heap_size = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);
+    printf("min heap size: %"PRIu32"\n", heap_size);
+    return 0;
+}
+
+static void register_heap(void)
+{
+    const esp_console_cmd_t heap_cmd = {
+        .command = "heap",
+        .help = "Get minimum size of free heap memory that was available during program execution",
+        .hint = NULL,
+        .func = &heap_size,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&heap_cmd) );
+
+}
+
+/** 'tasks' command prints the list of tasks and related information */
+#if WITH_TASKS_INFO
+
+static int tasks_info(int argc, char **argv)
+{
+    const size_t bytes_per_task = 40; /* see vTaskList description */
+    char *task_list_buffer = malloc(uxTaskGetNumberOfTasks() * bytes_per_task);
+    if (task_list_buffer == NULL) {
+        ESP_LOGE(TAG, "failed to allocate buffer for vTaskList output");
+        return 1;
+    }
+    fputs("Task Name\tStatus\tPrio\tHWM\tTask#", stdout);
+#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
+    fputs("\tAffinity", stdout);
+#endif
+    fputs("\n", stdout);
+    vTaskList(task_list_buffer);
+    fputs(task_list_buffer, stdout);
+    free(task_list_buffer);
+    return 0;
+}
+
+static void register_tasks(void)
+{
+    const esp_console_cmd_t cmd = {
+        .command = "tasks",
+        .help = "Get information about running tasks",
+        .hint = NULL,
+        .func = &tasks_info,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+#endif // WITH_TASKS_INFO
+
+/** log_level command changes log level via esp_log_level_set */
+
+static struct {
+    struct arg_str *tag;
+    struct arg_str *level;
+    struct arg_end *end;
+} log_level_args;
+
+static const char* s_log_level_names[] = {
+    "none",
+    "error",
+    "warn",
+    "info",
+    "debug",
+    "verbose"
+};
+
+static int log_level(int argc, char **argv)
+{
+    int nerrors = arg_parse(argc, argv, (void **) &log_level_args);
+    if (nerrors != 0) {
+        arg_print_errors(stderr, log_level_args.end, argv[0]);
+        return 1;
+    }
+    assert(log_level_args.tag->count == 1);
+    assert(log_level_args.level->count == 1);
+    const char* tag = log_level_args.tag->sval[0];
+    const char* level_str = log_level_args.level->sval[0];
+    esp_log_level_t level;
+    size_t level_len = strlen(level_str);
+    for (level = ESP_LOG_NONE; level <= ESP_LOG_VERBOSE; level++) {
+        if (memcmp(level_str, s_log_level_names[level], level_len) == 0) {
+            break;
+        }
+    }
+    if (level > ESP_LOG_VERBOSE) {
+        printf("Invalid log level '%s', choose from none|error|warn|info|debug|verbose\n", level_str);
+        return 1;
+    }
+    if (level > CONFIG_LOG_MAXIMUM_LEVEL) {
+        printf("Can't set log level to %s, max level limited in menuconfig to %s. "
+               "Please increase CONFIG_LOG_MAXIMUM_LEVEL in menuconfig.\n",
+               s_log_level_names[level], s_log_level_names[CONFIG_LOG_MAXIMUM_LEVEL]);
+        return 1;
+    }
+    esp_log_level_set(tag, level);
+    return 0;
+}
+
+static void register_log_level(void)
+{
+    log_level_args.tag = arg_str1(NULL, NULL, "<tag|*>", "Log tag to set the level for, or * to set for all tags");
+    log_level_args.level = arg_str1(NULL, NULL, "<none|error|warn|debug|verbose>", "Log level to set. Abbreviated words are accepted.");
+    log_level_args.end = arg_end(2);
+
+    const esp_console_cmd_t cmd = {
+        .command = "log_level",
+        .help = "Set log level for all tags or a specific tag.",
+        .hint = NULL,
+        .func = &log_level,
+        .argtable = &log_level_args
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}

+ 221 - 0
examples/system/console/advanced/components/cmd_system/cmd_system_sleep.c

@@ -0,0 +1,221 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
+ */
+/* Console example — various sleep-related 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 <ctype.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include "esp_log.h"
+#include "esp_console.h"
+#include "esp_chip_info.h"
+#include "esp_sleep.h"
+#include "driver/rtc_io.h"
+#include "driver/uart.h"
+#include "argtable3/argtable3.h"
+#include "cmd_system.h"
+#include "sdkconfig.h"
+
+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();
+}
+
+
+/** '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
+    struct arg_int *wakeup_gpio_num;
+    struct arg_int *wakeup_gpio_level;
+#endif
+    struct arg_end *end;
+} deep_sleep_args;
+
+
+static int deep_sleep(int argc, char **argv)
+{
+    int nerrors = arg_parse(argc, argv, (void **) &deep_sleep_args);
+    if (nerrors != 0) {
+        arg_print_errors(stderr, deep_sleep_args.end, argv[0]);
+        return 1;
+    }
+    if (deep_sleep_args.wakeup_time->count) {
+        uint64_t timeout = 1000ULL * deep_sleep_args.wakeup_time->ival[0];
+        ESP_LOGI(TAG, "Enabling timer wakeup, timeout=%lluus", timeout);
+        ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) );
+    }
+
+#if SOC_PM_SUPPORT_EXT1_WAKEUP
+    if (deep_sleep_args.wakeup_gpio_num->count) {
+        int io_num = deep_sleep_args.wakeup_gpio_num->ival[0];
+        if (!esp_sleep_is_valid_wakeup_gpio(io_num)) {
+            ESP_LOGE(TAG, "GPIO %d is not an RTC IO", io_num);
+            return 1;
+        }
+        int level = 0;
+        if (deep_sleep_args.wakeup_gpio_level->count) {
+            level = deep_sleep_args.wakeup_gpio_level->ival[0];
+            if (level != 0 && level != 1) {
+                ESP_LOGE(TAG, "Invalid wakeup level: %d", level);
+                return 1;
+            }
+        }
+        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_LOGE(TAG, "GPIO wakeup from deep sleep currently unsupported on ESP32-C3");
+    }
+#endif // SOC_PM_SUPPORT_EXT1_WAKEUP
+
+#if CONFIG_IDF_TARGET_ESP32
+    rtc_gpio_isolate(GPIO_NUM_12);
+#endif //CONFIG_IDF_TARGET_ESP32
+
+    esp_deep_sleep_start();
+}
+
+static void register_deep_sleep(void)
+{
+    int num_args = 1;
+    deep_sleep_args.wakeup_time =
+        arg_int0("t", "time", "<t>", "Wake up time, ms");
+#if SOC_PM_SUPPORT_EXT0_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
+    deep_sleep_args.wakeup_gpio_num =
+        arg_int0(NULL, "io", "<n>",
+                 "If specified, wakeup using GPIO with given number");
+    deep_sleep_args.wakeup_gpio_level =
+        arg_int0(NULL, "io_level", "<0|1>", "GPIO level to trigger wakeup");
+    num_args += 2;
+#endif
+    deep_sleep_args.end = arg_end(num_args);
+
+    const esp_console_cmd_t cmd = {
+        .command = "deep_sleep",
+        .help = "Enter deep sleep mode. "
+#if SOC_PM_SUPPORT_EXT0_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
+        "Two wakeup modes are supported: timer and GPIO. "
+#else
+        "Timer wakeup mode is supported. "
+#endif
+        "If no wakeup option is specified, will sleep indefinitely.",
+        .hint = NULL,
+        .func = &deep_sleep,
+        .argtable = &deep_sleep_args
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+/** 'light_sleep' command puts the chip into light sleep mode */
+
+static struct {
+    struct arg_int *wakeup_time;
+    struct arg_int *wakeup_gpio_num;
+    struct arg_int *wakeup_gpio_level;
+    struct arg_end *end;
+} light_sleep_args;
+
+static int light_sleep(int argc, char **argv)
+{
+    int nerrors = arg_parse(argc, argv, (void **) &light_sleep_args);
+    if (nerrors != 0) {
+        arg_print_errors(stderr, light_sleep_args.end, argv[0]);
+        return 1;
+    }
+    esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
+    if (light_sleep_args.wakeup_time->count) {
+        uint64_t timeout = 1000ULL * light_sleep_args.wakeup_time->ival[0];
+        ESP_LOGI(TAG, "Enabling timer wakeup, timeout=%lluus", timeout);
+        ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) );
+    }
+    int io_count = light_sleep_args.wakeup_gpio_num->count;
+    if (io_count != light_sleep_args.wakeup_gpio_level->count) {
+        ESP_LOGE(TAG, "Should have same number of 'io' and 'io_level' arguments");
+        return 1;
+    }
+    for (int i = 0; i < io_count; ++i) {
+        int io_num = light_sleep_args.wakeup_gpio_num->ival[i];
+        int level = light_sleep_args.wakeup_gpio_level->ival[i];
+        if (level != 0 && level != 1) {
+            ESP_LOGE(TAG, "Invalid wakeup level: %d", level);
+            return 1;
+        }
+        ESP_LOGI(TAG, "Enabling wakeup on GPIO%d, wakeup on %s level",
+                 io_num, level ? "HIGH" : "LOW");
+
+        ESP_ERROR_CHECK( gpio_wakeup_enable(io_num, level ? GPIO_INTR_HIGH_LEVEL : GPIO_INTR_LOW_LEVEL) );
+    }
+    if (io_count > 0) {
+        ESP_ERROR_CHECK( esp_sleep_enable_gpio_wakeup() );
+    }
+    if (CONFIG_ESP_CONSOLE_UART_NUM >= 0 && CONFIG_ESP_CONSOLE_UART_NUM <= UART_NUM_1) {
+        ESP_LOGI(TAG, "Enabling UART wakeup (press ENTER to exit light sleep)");
+        ESP_ERROR_CHECK( uart_set_wakeup_threshold(CONFIG_ESP_CONSOLE_UART_NUM, 3) );
+        ESP_ERROR_CHECK( esp_sleep_enable_uart_wakeup(CONFIG_ESP_CONSOLE_UART_NUM) );
+    }
+    fflush(stdout);
+    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:
+        cause_str = "GPIO";
+        break;
+    case ESP_SLEEP_WAKEUP_UART:
+        cause_str = "UART";
+        break;
+    case ESP_SLEEP_WAKEUP_TIMER:
+        cause_str = "timer";
+        break;
+    default:
+        cause_str = "unknown";
+        printf("%d\n", cause);
+    }
+    ESP_LOGI(TAG, "Woke up from: %s", cause_str);
+    return 0;
+}
+
+static void register_light_sleep(void)
+{
+    light_sleep_args.wakeup_time =
+        arg_int0("t", "time", "<t>", "Wake up time, ms");
+    light_sleep_args.wakeup_gpio_num =
+        arg_intn(NULL, "io", "<n>", 0, 8,
+                 "If specified, wakeup using GPIO with given number");
+    light_sleep_args.wakeup_gpio_level =
+        arg_intn(NULL, "io_level", "<0|1>", 0, 8, "GPIO level to trigger wakeup");
+    light_sleep_args.end = arg_end(3);
+
+    const esp_console_cmd_t cmd = {
+        .command = "light_sleep",
+        .help = "Enter light sleep mode. "
+        "Two wakeup modes are supported: timer and GPIO. "
+        "Multiple GPIO pins can be specified using pairs of "
+        "'io' and 'io_level' arguments. "
+        "Will also wake up on UART input.",
+        .hint = NULL,
+        .func = &light_sleep,
+        .argtable = &light_sleep_args
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}

+ 7 - 1
examples/system/console/advanced/main/console_example_main.c

@@ -19,6 +19,7 @@
 #include "esp_vfs_fat.h"
 #include "nvs.h"
 #include "nvs_flash.h"
+#include "soc/soc_caps.h"
 #include "cmd_system.h"
 #include "cmd_wifi.h"
 #include "cmd_nvs.h"
@@ -150,8 +151,13 @@ void app_main(void)
 
     /* Register commands */
     esp_console_register_help_command();
-    register_system();
+    register_system_common();
+#ifndef CONFIG_IDF_TARGET_ESP32H2  // needs deep sleep support, IDF-6268
+    register_system_sleep();
+#endif
+#if SOC_WIFI_SUPPORTED
     register_wifi();
+#endif
     register_nvs();
 
     /* Prompt to be printed before each line.

+ 2 - 2
examples/system/console/basic/README.md

@@ -1,5 +1,5 @@
-| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
-| ----------------- | ----- | -------- | -------- | -------- |
+| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
+| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
 
 # Basic Console Example (`esp_console_repl`)
 

+ 6 - 1
examples/system/console/basic/main/console_example_main.c

@@ -79,8 +79,13 @@ void app_main(void)
 
     /* Register commands */
     esp_console_register_help_command();
-    register_system();
+    register_system_common();
+#ifndef CONFIG_IDF_TARGET_ESP32H2  // needs deep sleep support, IDF-6268
+    register_system_sleep();
+#endif
+#if SOC_WIFI_SUPPORTED
     register_wifi();
+#endif
     register_nvs();
 
 #if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) || defined(CONFIG_ESP_CONSOLE_UART_CUSTOM)