Explorar o código

Merge branch 'feature/esp32c6_itwt_support_light_sleep' into 'master'

esp_wifi: itwt support light sleep

See merge request espressif/esp-idf!22772
Xu Xiao %!s(int64=2) %!d(string=hai) anos
pai
achega
033f737205

+ 1 - 1
components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld

@@ -71,7 +71,7 @@ pm_is_waked = 0x40000c9c;
 //pm_keep_alive = 0x40000ca0;
 /* pm_on_beacon_rx = 0x40000ca4; */
 pm_on_data_rx = 0x40000ca8;
-pm_on_tbtt = 0x40000cac;
+//pm_on_tbtt = 0x40000cac;
 pm_parse_beacon = 0x40000cb0;
 //pm_process_tim = 0x40000cb4;
 //pm_rx_beacon_process = 0x40000cb8;

+ 1 - 1
components/esp_wifi/lib

@@ -1 +1 @@
-Subproject commit e61fec6b57f6a16ae6747ce3b52d7fc6286425bb
+Subproject commit 515b89441b26f0c76daedb10ac0f411a4c67cccb

+ 45 - 16
examples/common_components/iperf/iperf.c

@@ -124,7 +124,11 @@ static void socket_recv(int recv_socket, struct sockaddr_storage listen_addr, ui
     uint8_t *buffer;
     int want_recv = 0;
     int actual_recv = 0;
+#ifdef CONFIG_LWIP_IPV6
     socklen_t socklen = (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+#else
+    socklen_t socklen = sizeof(struct sockaddr_in);
+#endif
     const char *error_log = (type == IPERF_TRANS_TYPE_TCP) ? "tcp server recv" : "udp server recv";
 
     buffer = s_iperf_ctrl.buffer;
@@ -157,7 +161,11 @@ static void socket_send(int send_socket, struct sockaddr_storage dest_addr, uint
     int64_t prev_time = 0;
     int64_t send_time = 0;
     int err = 0;
+#ifdef CONFIG_LWIP_IPV6
     const socklen_t socklen = (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+#else
+    const socklen_t socklen = sizeof(struct sockaddr_in);
+#endif
     const char *error_log = (type == IPERF_TRANS_TYPE_TCP) ? "tcp client send" : "udp client send";
 
     buffer = s_iperf_ctrl.buffer;
@@ -225,11 +233,15 @@ static esp_err_t IRAM_ATTR iperf_run_tcp_server(void)
     struct timeval timeout = { 0 };
     socklen_t addr_len = sizeof(struct sockaddr);
     struct sockaddr_storage listen_addr = { 0 };
-    struct sockaddr_in6 listen_addr6 = { 0 };
-    struct sockaddr_in listen_addr4 = { 0 };
 
+    struct sockaddr_in listen_addr4 = { 0 };
+#ifdef CONFIG_LWIP_IPV6
+    struct sockaddr_in6 listen_addr6 = { 0 };
     ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
-
+#else
+    ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Invalid AF types");
+#endif
+#ifdef CONFIG_LWIP_IPV6
     if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
         // The TCP server listen at the address "::", which means all addresses can be listened to.
         inet6_aton("::", &listen_addr6.sin6_addr);
@@ -250,7 +262,9 @@ static esp_err_t IRAM_ATTR iperf_run_tcp_server(void)
         ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Error occurred during listen: errno %d", errno);
 
         memcpy(&listen_addr, &listen_addr6, sizeof(listen_addr6));
-    } else if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
+    } else
+#endif
+    if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
         listen_addr4.sin_family = AF_INET;
         listen_addr4.sin_port = htons(s_iperf_ctrl.cfg.sport);
         listen_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.source_ip4;
@@ -313,12 +327,15 @@ static esp_err_t iperf_run_tcp_client(void)
     int err = 0;
     esp_err_t ret = ESP_OK;
     struct sockaddr_storage dest_addr = { 0 };
-    struct sockaddr_in6 dest_addr6 = { 0 };
     struct sockaddr_in dest_addr4 = { 0 };
     struct timeval timeout = { 0 };
-
+#ifdef CONFIG_LWIP_IPV6
+    struct sockaddr_in6 dest_addr6 = { 0 };
     ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
-
+#else
+    ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Invalid AF types");
+#endif
+#ifdef CONFIG_LWIP_IPV6
     if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
         client_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
         ESP_GOTO_ON_FALSE((client_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
@@ -331,7 +348,9 @@ static esp_err_t iperf_run_tcp_client(void)
         ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to connect: errno %d", errno);
         ESP_LOGI(TAG, "Successfully connected");
         memcpy(&dest_addr, &dest_addr6, sizeof(dest_addr6));
-    } else if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
+    } else
+#endif
+    if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
         client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
         ESP_GOTO_ON_FALSE((client_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
 
@@ -378,11 +397,14 @@ static esp_err_t IRAM_ATTR iperf_run_udp_server(void)
     esp_err_t ret = ESP_OK;
     struct timeval timeout = { 0 };
     struct sockaddr_storage listen_addr = { 0 };
-    struct sockaddr_in6 listen_addr6 = { 0 };
     struct sockaddr_in listen_addr4 = { 0 };
-
+#ifdef CONFIG_LWIP_IPV6
+    struct sockaddr_in6 listen_addr6 = { 0 };
     ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
-
+#else
+    ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
+#endif
+#ifdef CONFIG_LWIP_IPV6
     if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
         // The UDP server listen at the address "::", which means all addresses can be listened to.
         inet6_aton("::", &listen_addr6.sin6_addr);
@@ -400,7 +422,9 @@ static esp_err_t IRAM_ATTR iperf_run_udp_server(void)
         ESP_LOGI(TAG, "Socket bound, port %" PRIu16, listen_addr6.sin6_port);
 
         memcpy(&listen_addr, &listen_addr6, sizeof(listen_addr6));
-    } else if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
+    } else
+#endif
+    if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
         listen_addr4.sin_family = AF_INET;
         listen_addr4.sin_port = htons(s_iperf_ctrl.cfg.sport);
         listen_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.source_ip4;
@@ -442,11 +466,14 @@ static esp_err_t iperf_run_udp_client(void)
     int opt = 1;
     esp_err_t ret = ESP_OK;
     struct sockaddr_storage dest_addr = { 0 };
-    struct sockaddr_in6 dest_addr6 = { 0 };
     struct sockaddr_in dest_addr4 = { 0 };
-
+#ifdef CONFIG_LWIP_IPV6
+    struct sockaddr_in6 dest_addr6 = { 0 };
     ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
-
+#else
+    ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
+#endif
+#ifdef CONFIG_LWIP_IPV6
     if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
         inet6_aton(s_iperf_ctrl.cfg.destination_ip6, &dest_addr6.sin6_addr);
         dest_addr6.sin6_family = AF_INET6;
@@ -458,7 +485,9 @@ static esp_err_t iperf_run_udp_client(void)
 
         setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
         memcpy(&dest_addr, &dest_addr6, sizeof(dest_addr6));
-    } else if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
+    } else
+#endif
+    if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
         dest_addr4.sin_family = AF_INET;
         dest_addr4.sin_port = htons(s_iperf_ctrl.cfg.dport);
         dest_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.destination_ip4;

+ 19 - 2
examples/common_components/iperf/wifi_cmd.c

@@ -365,8 +365,15 @@ static void cmd_ping_on_ping_success(esp_ping_handle_t hdl, void *args)
     esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
     esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len));
     esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time));
+
+#ifdef CONFIG_LWIP_IPV6
     printf("%" PRIu32 " bytes from %s icmp_seq=%d ttl=%d time=%" PRIu32 " ms\n",
            recv_len, inet_ntoa(target_addr.u_addr.ip4), seqno, ttl, elapsed_time);
+#else
+    printf("%" PRIu32 " bytes from %s icmp_seq=%d ttl=%d time=%" PRIu32 " ms\n",
+           recv_len, inet_ntoa(target_addr.addr), seqno, ttl, elapsed_time);
+#endif
+
 }
 
 static void cmd_ping_on_ping_timeout(esp_ping_handle_t hdl, void *args)
@@ -375,7 +382,11 @@ static void cmd_ping_on_ping_timeout(esp_ping_handle_t hdl, void *args)
     ip_addr_t target_addr;
     esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
     esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
+#ifdef CONFIG_LWIP_IPV6
     printf("From %s icmp_seq=%d timeout\n", inet_ntoa(target_addr.u_addr.ip4), seqno);
+#else
+    printf("From %s icmp_seq=%d timeout\n", inet_ntoa(target_addr.addr), seqno);
+#endif
 }
 
 static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args)
@@ -391,9 +402,12 @@ static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args)
     uint32_t loss = (uint32_t)((1 - ((float)received) / transmitted) * 100);
     if (IP_IS_V4(&target_addr)) {
         printf("\n--- %s ping statistics ---\n", inet_ntoa(*ip_2_ip4(&target_addr)));
-    } else {
+    }
+#ifdef CONFIG_LWIP_IPV6
+    else {
         printf("\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&target_addr)));
     }
+#endif
     printf("%" PRIu32 " packets transmitted, %" PRIu32 " received, %" PRIu32 "%% packet loss, time %" PRIu32 "ms\n",
            transmitted, received, loss, total_time_ms);
     // delete the ping sessions, so that we clean up all resources and can create a new ping session
@@ -450,10 +464,13 @@ static int do_ping_cmd(int argc, char **argv)
     if (res->ai_family == AF_INET) {
         struct in_addr addr4 = ((struct sockaddr_in *) (res->ai_addr))->sin_addr;
         inet_addr_to_ip4addr(ip_2_ip4(&target_addr), &addr4);
-    } else {
+    }
+#ifdef CONFIG_LWIP_IPV6
+    else {
         struct in6_addr addr6 = ((struct sockaddr_in6 *) (res->ai_addr))->sin6_addr;
         inet6_addr_to_ip6addr(ip_2_ip6(&target_addr), &addr6);
     }
+#endif
     freeaddrinfo(res);
     config.target_addr = target_addr;
 

+ 26 - 0
examples/wifi/itwt/main/Kconfig.projbuild

@@ -12,6 +12,32 @@ menu "Example Configuration"
         help
             WiFi password (WPA or WPA2) for the example to use.
 
+    config EXAMPLE_ENABLE_STATIC_IP
+        bool "enable static ip"
+        default y
+        help
+            Enable static IP
+    config EXAMPLE_STATIC_IP_ADDR
+        string "Static IP address"
+        default "192.168.4.2"
+        depends on EXAMPLE_ENABLE_STATIC_IP
+        help
+            Set static IP address.
+
+    config EXAMPLE_STATIC_NETMASK_ADDR
+        string "Static netmask address"
+        default "255.255.255.0"
+        depends on EXAMPLE_ENABLE_STATIC_IP
+        help
+            Set static netmask address.
+
+    config EXAMPLE_STATIC_GW_ADDR
+        string "Static gateway address"
+        default "192.168.4.1"
+        depends on EXAMPLE_ENABLE_STATIC_IP
+        help
+            Set static gateway address.
+
     menu "iTWT Configuration"
         config EXAMPLE_ITWT_TRIGGER_ENABLE
             bool "trigger-enabled"

+ 31 - 4
examples/wifi/itwt/main/itwt.c

@@ -17,6 +17,7 @@
    set a router or a AP using the same SSID&PASSWORD as configuration of this example.
    start esp32c6 and when it connected to AP it will setup itwt.
 */
+#include <netdb.h>
 #include "freertos/FreeRTOS.h"
 #include "freertos/event_groups.h"
 #include "esp_wifi.h"
@@ -28,6 +29,7 @@
 #include "wifi_cmd.h"
 #include "esp_wifi_he.h"
 #include "esp_pm.h"
+#include "esp_timer.h"
 
 /*******************************************************
  *                Constants
@@ -69,6 +71,28 @@ EventGroupHandle_t wifi_event_group;
 /*******************************************************
  *                Function Definitions
  *******************************************************/
+
+static void example_set_static_ip(esp_netif_t *netif)
+{
+#if CONFIG_EXAMPLE_ENABLE_STATIC_IP
+    if (esp_netif_dhcpc_stop(netif) != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to stop dhcp client");
+        return;
+    }
+    esp_netif_ip_info_t ip;
+    memset(&ip, 0 , sizeof(esp_netif_ip_info_t));
+    ip.ip.addr = ipaddr_addr(CONFIG_EXAMPLE_STATIC_IP_ADDR);
+    ip.netmask.addr = ipaddr_addr(CONFIG_EXAMPLE_STATIC_NETMASK_ADDR);
+    ip.gw.addr = ipaddr_addr(CONFIG_EXAMPLE_STATIC_GW_ADDR);
+    if (esp_netif_set_ip_info(netif, &ip) != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to set ip info");
+        return;
+    }
+    ESP_LOGI(TAG, "Success to set static ip: %s, netmask: %s, gw: %s",
+             CONFIG_EXAMPLE_STATIC_IP_ADDR, CONFIG_EXAMPLE_STATIC_NETMASK_ADDR, CONFIG_EXAMPLE_STATIC_GW_ADDR);
+#endif
+}
+
 static const char *itwt_probe_status_to_str(wifi_itwt_probe_status_t status)
 {
     switch (status) {
@@ -87,20 +111,19 @@ static void got_ip_handler(void *arg, esp_event_base_t event_base,
     xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
 
     /* setup a trigger-based announce individual TWT agreement. */
-    esp_err_t err = ESP_OK;
-    int flow_id = 0;
     wifi_phy_mode_t phymode;
     wifi_config_t sta_cfg = { 0, };
     esp_wifi_get_config(WIFI_IF_STA, &sta_cfg);
     esp_wifi_sta_get_negotiated_phymode(&phymode);
     if (phymode == WIFI_PHY_MODE_HE20) {
+        esp_err_t err = ESP_OK;
+        int flow_id = 0;
         err = esp_wifi_sta_itwt_setup(TWT_REQUEST, trigger_enabled, flow_type_announced ? 0 : 1,
                                       CONFIG_EXAMPLE_ITWT_MIN_WAKE_DURA, CONFIG_EXAMPLE_ITWT_WAKE_INVL_EXPN,
                                       CONFIG_EXAMPLE_ITWT_WAKE_INVL_MANT, &flow_id);
         if (err != ESP_OK) {
             ESP_LOGE(TAG, "itwt setup failed, err:0x%x", err);
         }
-
     } else {
         ESP_LOGE(TAG, "Must be in 11ax mode to support itwt");
     }
@@ -130,7 +153,7 @@ static void itwt_setup_handler(void *arg, esp_event_base_t event_base,
         ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>flow_id:%d, %s, %s, wake_dura:%d, wake_invl_e:%d, wake_invl_m:%d", setup->flow_id,
                 setup->trigger ? "trigger-enabled" : "non-trigger-enabled", setup->flow_type ? "unannounced" : "announced",
                 setup->min_wake_dura, setup->wake_invl_expn, setup->wake_invl_mant);
-        ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>wake duration:%d us, service period:%d ms", setup->min_wake_dura << 8, setup->wake_invl_mant << setup->wake_invl_expn);
+        ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>wake duration:%d us, service period:%d us", setup->min_wake_dura << 8, setup->wake_invl_mant << setup->wake_invl_expn);
     } else {
         ESP_LOGE(TAG, "<WIFI_EVENT_ITWT_SETUP>unexpected setup command:%d", setup->setup_cmd);
     }
@@ -221,6 +244,10 @@ static void wifi_itwt(void)
     esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_11AX);
     esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
 
+#if CONFIG_EXAMPLE_ENABLE_STATIC_IP
+    example_set_static_ip(netif_sta);
+#endif
+
     ESP_ERROR_CHECK(esp_wifi_start());
 
 #if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS

+ 1 - 0
examples/wifi/itwt/sdkconfig.defaults

@@ -16,5 +16,6 @@ CONFIG_ESP_WIFI_SLP_IRAM_OPT=y
 CONFIG_ESP_GRATUITOUS_ARP=n
 CONFIG_LWIP_ESP_GRATUITOUS_ARP=n
 
+CONFIG_FREERTOS_HZ=1000
 # CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set
 # CONFIG_ESP_GRATUITOUS_ARP is not set

+ 13 - 0
examples/wifi/itwt/sdkconfig.defaults.esp32c6

@@ -18,3 +18,16 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64
 
 CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS=n
 CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS=n
+
+CONFIG_LWIP_IPV6=n
+
+CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=10
+CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y
+CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
+CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
+CONFIG_ESP_PHY_MAC_BB_PD=y
+#CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP=y
+CONFIG_MBEDTLS_HARDWARE_AES=n
+CONFIG_MBEDTLS_HARDWARE_MPI=n
+CONFIG_MBEDTLS_HARDWARE_SHA=n
+CONFIG_MBEDTLS_HARDWARE_ECC=n