Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32-S3: How to know the device has been in light-sleep mode? (IDFGH-14254) #15048

Closed
3 tasks done
chengdujzw opened this issue Dec 18, 2024 · 5 comments
Closed
3 tasks done
Assignees
Labels
Status: Opened Issue is new Type: Bug bugs in IDF

Comments

@chengdujzw
Copy link

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v5.2

Espressif SoC revision.

ESP32-S3

Operating System used.

Linux

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

ESP32 V5.2

Power Supply used.

USB

What is the expected behavior?

I expected that the device entered the light-sleep mode.

What is the actual behavior?

Instead it could not be sure if the device was in the light-sleep mode.

Steps to reproduce.

  1. I just compiled the sample code of "wifi/power_save". For the convenience of testing, I only modified the SSID and password in the code to our own ones, without changing any other code. Then, I flashed the firmware (FW) onto the device.
    However, I didn't find any logs indicating that the device had entered the light sleep mode. Moreover, I could ping the device at any time. Since the simple code didn't include console configuration, I couldn't input anything via the console. Therefore, I'm not sure whether the device is actually in the light-sleep mode.

  2. I merged the sample codes of "wifi/power_save" and "system/console/basic".
    

    A. If the WiFi function is disabled:
    After the device boots up, it's impossible to input anything into the console, which seems to be in line with our expectations. I guess it's in the sleep mode.
    B. If the WiFi function is enabled:
    After the device boots up, it's possible to input and output via the console all the time, and I can ping the device at any time.

The sample code of "wifi/power_save" is released along with the SDK package. I think it should have been well verified. Perhaps the behavior in the sleep mode doesn't match my expectations. So, please help me by giving some suggestions on how to tell whether the device is in the sleep mode.

Debug Logs.

No response

More Information.

No response

@chengdujzw chengdujzw added the Type: Bug bugs in IDF label Dec 18, 2024
@github-actions github-actions bot changed the title ESP32-S3: How to know the device has been in light-sleep mode? ESP32-S3: How to know the device has been in light-sleep mode? (IDFGH-14254) Dec 18, 2024
@espressif-bot espressif-bot added the Status: Opened Issue is new label Dec 18, 2024
@chengdujzw
Copy link
Author

chengdujzw commented Dec 18, 2024

The below is my code in which I have merged "wifi/power_save" and "console/basic":
/* Basic console example (esp_console_repl API)

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_system.h"
#include "esp_log.h"
#include "esp_console.h"
#include "esp_vfs_dev.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"

/*

  • 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 = "example";
#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 void initialize_filesystem(void)
{
static wl_handle_t wl_handle;
const esp_vfs_fat_mount_config_t mount_config = {
.max_files = 4,
.format_if_mount_failed = true
};
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;
}
}
#endif // CONFIG_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);
}
#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_event.h"
#include "esp_pm.h"
#include "nvs_flash.h"

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s.h"
#include "driver/gpio.h"
#include "esp_system.h"
#include "esp_check.h"
#include "esp_http_client.h"
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "esp_tls.h"

#include "esp_sleep.h"
#include "driver/uart.h"

#define GPIO_WAKEUP_NUM 20
#define GPIO_WAKEUP_LEVEL 0

#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_event.h"
#include "esp_pm.h"
#include "nvs_flash.h"

#define DEFAULT_LISTEN_INTERVAL 3
#define DEFAULT_BEACON_TIMEOUT 6

#if CONFIG_EXAMPLE_POWER_SAVE_MIN_MODEM
#define DEFAULT_PS_MODE WIFI_PS_MIN_MODEM
#elif CONFIG_EXAMPLE_POWER_SAVE_MAX_MODEM
#define DEFAULT_PS_MODE WIFI_PS_MAX_MODEM
#elif CONFIG_EXAMPLE_POWER_SAVE_NONE
#define DEFAULT_PS_MODE WIFI_PS_NONE
#else
#define DEFAULT_PS_MODE WIFI_PS_NONE
#endif /CONFIG_POWER_SAVE_MODEM/

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_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
esp_wifi_connect();
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip: " IPSTR, IP2STR(&event->ip_info.ip));
}
}

/init wifi as sta and set power save mode/
static void wifi_power_save(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
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_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, NULL));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, NULL));

wifi_config_t wifi_config = {
    .sta = {
        .listen_interval = DEFAULT_LISTEN_INTERVAL,
    },
};

strcpy((char *)wifi_config.sta.ssid, "myhotspot");
strcpy((char *)wifi_config.sta.password, "1234567890");

ESP_LOGI(TAG, "Connecting AP: %s with password: %s", wifi_config.sta.ssid, 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_ERROR_CHECK(esp_wifi_start());
ESP_ERROR_CHECK(esp_wifi_set_inactive_time(WIFI_IF_STA, DEFAULT_BEACON_TIMEOUT));

ESP_LOGI(TAG, "esp_wifi_set_ps().");
esp_wifi_set_ps(DEFAULT_PS_MODE);

}

static void sleep_wait_gpio_inactive(void)
{
printf("Waiting for GPIO%d to go high...\n", GPIO_WAKEUP_NUM);
while (gpio_get_level(GPIO_WAKEUP_NUM) == GPIO_WAKEUP_LEVEL) {
vTaskDelay(pdMS_TO_TICKS(10));
}
}
esp_err_t sleep_register_gpio_wakeup(void)
{
/* Initialize GPIO */
gpio_config_t config = {
.pin_bit_mask = BIT64(GPIO_WAKEUP_NUM),
.mode = GPIO_MODE_INPUT,
.pull_down_en = false,
.pull_up_en = false,
.intr_type = GPIO_INTR_DISABLE
};

esp_err_t err = gpio_config(&config);
if  (err != ESP_OK) {
	printf("Initialize GPIO%d failed.\n", GPIO_WAKEUP_NUM);
	return err;
}

err = gpio_wakeup_enable(GPIO_WAKEUP_NUM, GPIO_WAKEUP_LEVEL == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL);
if (err != ESP_OK) {
	printf("Enable gpio wakeup failed.\n");
	return err;
}

err = esp_sleep_enable_gpio_wakeup();
if (err != ESP_OK) {
	printf("Configure gpio as wakeup source failed.\n");
	return err;
}

sleep_wait_gpio_inactive();
printf("Gpio wakeup source is ready.\n");

return ESP_OK;

}

static void test_thread(void *param)
{
while(1) {
esp_pm_dump_locks(stdout);
vTaskDelay(5000/portTICK_PERIOD_MS);
}

vTaskDelete(NULL);

}

void app_main(void)
{
esp_console_repl_t repl = NULL;
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
/
Prompt to be printed before each line.
* This can be customized, made dynamic, etc.
*/
repl_config.prompt = PROMPT_STR ">";
repl_config.max_cmdline_length = CONFIG_CONSOLE_MAX_COMMAND_LINE_LENGTH;

initialize_nvs();

#if CONFIG_CONSOLE_STORE_HISTORY
initialize_filesystem();
repl_config.history_save_path = HISTORY_PATH;
ESP_LOGI(TAG, "Command history enabled");
#else
ESP_LOGI(TAG, "Command history disabled");
#endif

/* Register commands */
esp_console_register_help_command();
register_system_common();

#if SOC_LIGHT_SLEEP_SUPPORTED
register_system_light_sleep();
#endif
#if SOC_DEEP_SLEEP_SUPPORTED
register_system_deep_sleep();
#endif
#if SOC_WIFI_SUPPORTED
register_wifi();
#endif
register_nvs();

#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));

#if CONFIG_PM_ENABLE
// Configure dynamic frequency scaling:
// maximum and minimum frequencies are set in sdkconfig,
// automatic light sleep is enabled if tickless idle support is enabled.
esp_pm_config_t pm_config = {
.max_freq_mhz = 160,
.min_freq_mhz = 40,
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
.light_sleep_enable = true
#endif
};
ESP_ERROR_CHECK( esp_pm_configure(&pm_config) );
#endif // CONFIG_PM_ENABLE
//sleep_register_gpio_wakeup();
//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) );

wifi_power_save();

// xTaskCreate(test_thread, ((const char *)"test_thread"), 4096, NULL, tskIDLE_PRIORITY + 1, NULL);
//while(1) {
//vTaskDelay(5000/portTICK_PERIOD_MS);
//printf("sdfdsfdsf\n");
//}
}

@chengdujzw
Copy link
Author

The logs as below:
[2024-12-18 11:23:05.528] I (580) wifi:Init dynamic rx buffer num: 32
[2024-12-18 11:23:05.532] I (583) wifi_init: rx ba win: 6
[2024-12-18 11:23:05.536] I (586) wifi_init: accept mbox: 6
[2024-12-18 11:23:05.540] I (588) wifi_init: tcpip mbox: 32
[2024-12-18 11:23:05.544] I (590) wifi_init: udp mbox: 6
[2024-12-18 11:23:05.548] I (593) wifi_init: tcp mbox: 6
[2024-12-18 11:23:05.552] I (595) wifi_init: tcp tx win: 5760
[2024-12-18 11:23:05.556] I (608) wifi_init: tcp rx win: 5760
[2024-12-18 11:23:05.560] I (610) wifi_init: tcp mss: 1440
[2024-12-18 11:23:05.564] I (613) wifi_init: WiFi IRAM OP enabled
[2024-12-18 11:23:05.568] I (615) wifi_init: WiFi RX IRAM OP enabled
[2024-12-18 11:23:05.573] I (618) wifi_init: WiFi SLP IRAM OP enabled
[2024-12-18 11:23:05.578] I (621) example: Connecting AP: myhotspot with password: 1234567890
[2024-12-18 11:23:05.585] W (637) wifi:Password length matches WPA2 standards, authmode threshold changes from OPEN to WPA2
[2024-12-18 11:23:05.594] I (644) phy_init: phy_version 680,a6008b2,Jun 4 2024,16:41:10
[2024-12-18 11:23:05.649] I (702) wifi:mode : sta (34:85:18:99:4e:c8)
[2024-12-18 11:23:05.653] I (705) wifi:enable tsf
[2024-12-18 11:23:05.657] I (711) example: esp_wifi_set_ps().
[2024-12-18 11:23:05.661] I (714) wifi:Set ps type: 0, coexist: 0
[2024-12-18 11:23:05.665]
[2024-12-18 11:23:05.665] I (716) main_task: Returned from app_main()
[2024-12-18 11:23:05.670] I (719) wifi:new:<6,2>, old:<1,0>, ap:<255,255>, sta:<6,2>, prof:1, snd_ch_cfg:0x0
[2024-12-18 11:23:05.677] I (727) wifi:state: init -> auth (0xb0)
[2024-12-18 11:23:05.682] I (736) wifi:state: auth -> assoc (0x0)
[2024-12-18 11:23:05.695] I (748) wifi:state: assoc -> run (0x10)
[2024-12-18 11:23:05.833] I (886) wifi:connected with myhotsport, aid = 1, channel 6, 40D, bssid = 38:83:45:a6:f9:ea
[2024-12-18 11:23:05.841] I (891) wifi:security: WPA2-PSK, phy: bgn, rssi: -47
[2024-12-18 11:23:05.845] I (898) wifi:pm start, type: 0
[2024-12-18 11:23:05.848]
[2024-12-18 11:23:05.848] I (900) wifi:dp: 1, bi: 102400, li: 3, scale listen interval from 307200 us to 307200 us
[2024-12-18 11:23:05.856] I (904) wifi:set rx beacon pti, rx_bcn_pti: 0, bcn_timeout: 25000, mt_pti: 0, mt_time: 10000
[2024-12-18 11:23:05.864] I (916) wifi:AP's beacon interval = 102400 us, DTIM period = 1
[2024-12-18 11:23:05.870] I (923) wifi:idx:0 (ifx:0, 38:83:45:a6:f9:ea), tid:6, ssn:0, winSize:64
[2024-12-18 11:23:05.877] I (931) wifi:idx:1 (ifx:0, 38:83:45:a6:f9:ea), tid:0, ssn:0, winSize:64
[2024-12-18 11:23:06.858] I (1911) esp_netif_handlers: sta ip: 110.1.1.150, mask: 255.255.255.0, gw: 110.1.1.212
[2024-12-18 11:23:06.867] I (1916) example: got ip: 110.1.1.150
[0Kesp32s3>
esp32s3>
[2024-12-18 11:23:09.784] esp32s3>

@chengdujzw
Copy link
Author

chengdujzw commented Dec 18, 2024

Even if it is set to WIFI_PS_MAX_MODEM, it can not know if the device is in the light-sleep mode. Is it because the device enters the light-sleep mode and goes out of the light-sleep mode too fast? only we can know it by capturing them with a power consumption measuring device?

But even I enlarge the listening interval and beacon timeout, it doesn't enter light-sleep yet.

#define DEFAULT_LISTEN_INTERVAL 2000
#define DEFAULT_BEACON_TIMEOUT 4000
#define CONFIG_EXAMPLE_POWER_SAVE_MAX_MODEM 1
#if CONFIG_EXAMPLE_POWER_SAVE_MIN_MODEM
#define DEFAULT_PS_MODE WIFI_PS_MIN_MODEM
#elif CONFIG_EXAMPLE_POWER_SAVE_MAX_MODEM
#define DEFAULT_PS_MODE WIFI_PS_MAX_MODEM
#elif CONFIG_EXAMPLE_POWER_SAVE_NONE
#define DEFAULT_PS_MODE WIFI_PS_NONE
#else
#define DEFAULT_PS_MODE WIFI_PS_NONE
#endif /CONFIG_POWER_SAVE_MODEM/

@chengdujzw
Copy link
Author

  1. I changed the AP's parameters: Beacon interval:1000, DTIM: 5, it does not enter sleep yet.
  2. And I dumped the task status, it seems no task is busy, the system is in idle.

The source codes:
static int dump_task(void)
{
esp_pm_dump_locks(stdout);
return 0;
}
void app_main(void)
{
.....
wifi_power_save();
const esp_console_cmd_t cmd = {
.command = "dump",
.help = "dump task status",
.hint = NULL,
.func = &dump_task,
};
ESP_ERROR_CHECK_WITHOUT_ABORT( esp_console_cmd_register(&cmd) );
}

The dumping log:
[2024-12-19 09:16:13.564] Time since bootup: 15236107 us
[2024-12-19 09:16:13.567] Lock stats:
[2024-12-19 09:16:13.568] Name Type Arg Active Total_count Time(us) Time(%)
[2024-12-19 09:16:13.576] wifi APB_FREQ_MAX 0 0 13 2939899 20 %
[2024-12-19 09:16:13.583] uart_driver APB_FREQ_MAX 0 0 3507 124638 1 %
[2024-12-19 09:16:13.590] rtos1 CPU_FREQ_MAX 0 0 14602 2442637 17 %
[2024-12-19 09:16:13.598] rtos0 CPU_FREQ_MAX 0 1 12942 2863373 19 %
[2024-12-19 09:16:13.605]
[2024-12-19 09:16:13.606] Mode stats:
[2024-12-19 09:16:13.607] Mode CPU_freq Time(us) Time(%)
[2024-12-19 09:16:13.611] APB_MIN 80 M 9609090 62%
[2024-12-19 09:16:13.614] APB_MAX 80 M 2283930 14%
[2024-12-19 09:16:13.618] CPU_MAX 80 M 3332292 21%

@chengdujzw
Copy link
Author

Now I can observe the light-sleep mode by changing AP's parameters, therefore close this ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Opened Issue is new Type: Bug bugs in IDF
Projects
None yet
Development

No branches or pull requests

3 participants