فهرست منبع

lwip/esp32/examples: wifi throughput optimizations

1. Put some lwip udp rx/tx relating functions to IRAM
2. Put some wifi rx/tx relating functions to IRAMa
3. Reduce wifi dynamic malloc from 4 to 1 for each ebuf
4. Update iperf example accordingly
5. Update libphy.a to v383
Liu Zhi Fu 8 سال پیش
والد
کامیت
2242bf9b37

+ 0 - 2
components/esp32/ld/esp32.common.ld

@@ -89,7 +89,6 @@ SECTIONS
     *libesp32.a:core_dump.o(.literal .text .literal.* .text.*)
     *libesp32.a:core_dump.o(.literal .text .literal.* .text.*)
     *libapp_trace.a:(.literal .text .literal.* .text.*)
     *libapp_trace.a:(.literal .text .literal.* .text.*)
     *libxtensa-debug-module.a:eri.o(.literal .text .literal.* .text.*)
     *libxtensa-debug-module.a:eri.o(.literal .text .literal.* .text.*)
-    *libphy.a:(.literal .text .literal.* .text.*)
     *librtc.a:(.literal .text .literal.* .text.*)
     *librtc.a:(.literal .text .literal.* .text.*)
     *libsoc.a:(.literal .text .literal.* .text.*)
     *libsoc.a:(.literal .text .literal.* .text.*)
     *libhal.a:(.literal .text .literal.* .text.*)
     *libhal.a:(.literal .text .literal.* .text.*)
@@ -116,7 +115,6 @@ SECTIONS
     *(.jcr)
     *(.jcr)
     *(.dram1 .dram1.*)
     *(.dram1 .dram1.*)
     *libesp32.a:panic.o(.rodata .rodata.*)
     *libesp32.a:panic.o(.rodata .rodata.*)
-    *libphy.a:(.rodata .rodata.*)
     *libsoc.a:rtc_clk.o(.rodata .rodata.*)
     *libsoc.a:rtc_clk.o(.rodata .rodata.*)
     *libapp_trace.a:(.rodata .rodata.*)
     *libapp_trace.a:(.rodata .rodata.*)
     *libgcov.a:(.rodata .rodata.*)
     *libgcov.a:(.rodata .rodata.*)

+ 1 - 1
components/esp32/lib

@@ -1 +1 @@
-Subproject commit b35fc86bbc5f96e8d52cc32527dbfbabaed0d6fc
+Subproject commit 32402930b3b2d28bf894cba918d08446b04a38e6

+ 11 - 0
components/lwip/Kconfig

@@ -16,6 +16,17 @@ config L2_TO_L3_COPY
         Please make sure you fully understand the impact of this feature before 
         Please make sure you fully understand the impact of this feature before 
         enabling it.
         enabling it.
 
 
+config LWIP_IRAM_OPTIMIZATION
+    bool "Enable LWIP IRAM optimization"
+    default n
+    help
+        If this feature is enabled, some functions relating to RX/TX in LWIP will be
+        put into IRAM, it can improve UDP/TCP throughput by >10% for single core mode,
+        it doesn't help too much for dual core mode. On the other hand, it needs about
+        10KB IRAM for these optimizations.
+
+        If this feature is disabled, all lwip functions will be put into FLASH.
+
 config LWIP_MAX_SOCKETS
 config LWIP_MAX_SOCKETS
     int "Max number of open sockets"
     int "Max number of open sockets"
     range 1 32
     range 1 32

+ 4 - 4
components/lwip/api/api_lib.c

@@ -72,7 +72,7 @@ static err_t netconn_close_shutdown(struct netconn *conn, u8_t how);
  * @param apimsg a struct containing the function to call and its parameters
  * @param apimsg a struct containing the function to call and its parameters
  * @return ERR_OK if the function was called, another err_t if not
  * @return ERR_OK if the function was called, another err_t if not
  */
  */
-static err_t
+static err_t ESP_IRAM_ATTR
 tcpip_apimsg(struct api_msg *apimsg)
 tcpip_apimsg(struct api_msg *apimsg)
 {
 {
 #if LWIP_DEBUG
 #if LWIP_DEBUG
@@ -432,7 +432,7 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
  * @return ERR_OK if data has been received, an error code otherwise (timeout,
  * @return ERR_OK if data has been received, an error code otherwise (timeout,
  *                memory error or another error)
  *                memory error or another error)
  */
  */
-static err_t
+static err_t ESP_IRAM_ATTR
 netconn_recv_data(struct netconn *conn, void **new_buf)
 netconn_recv_data(struct netconn *conn, void **new_buf)
 {
 {
   void *buf = NULL;
   void *buf = NULL;
@@ -566,7 +566,7 @@ netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
  * @return ERR_OK if data has been received, an error code otherwise (timeout,
  * @return ERR_OK if data has been received, an error code otherwise (timeout,
  *                memory error or another error)
  *                memory error or another error)
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 netconn_recv(struct netconn *conn, struct netbuf **new_buf)
 netconn_recv(struct netconn *conn, struct netbuf **new_buf)
 {
 {
 #if LWIP_TCP
 #if LWIP_TCP
@@ -678,7 +678,7 @@ netconn_sendto(struct netconn *conn, struct netbuf *buf, const ip_addr_t *addr,
  * @param buf a netbuf containing the data to send
  * @param buf a netbuf containing the data to send
  * @return ERR_OK if data was sent, any other err_t on error
  * @return ERR_OK if data was sent, any other err_t on error
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 netconn_send(struct netconn *conn, struct netbuf *buf)
 netconn_send(struct netconn *conn, struct netbuf *buf)
 {
 {
   API_MSG_VAR_DECLARE(msg);
   API_MSG_VAR_DECLARE(msg);

+ 1 - 1
components/lwip/api/api_msg.c

@@ -1440,7 +1440,7 @@ lwip_netconn_do_listen(void *m)
  *
  *
  * @param msg the api_msg_msg pointing to the connection
  * @param msg the api_msg_msg pointing to the connection
  */
  */
-void
+void ESP_IRAM_ATTR
 lwip_netconn_do_send(void *m)
 lwip_netconn_do_send(void *m)
 {
 {
   struct api_msg_msg *msg = (struct api_msg_msg*)m;
   struct api_msg_msg *msg = (struct api_msg_msg*)m;

+ 2 - 2
components/lwip/api/netbuf.c

@@ -103,7 +103,7 @@ netbuf_delete(struct netbuf *buf)
  * @return pointer to the allocated memory
  * @return pointer to the allocated memory
  *         NULL if no memory could be allocated
  *         NULL if no memory could be allocated
  */
  */
-void *
+void * ESP_IRAM_ATTR
 netbuf_alloc(struct netbuf *buf, u16_t size)
 netbuf_alloc(struct netbuf *buf, u16_t size)
 {
 {
   LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
   LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
@@ -127,7 +127,7 @@ netbuf_alloc(struct netbuf *buf, u16_t size)
  *
  *
  * @param buf pointer to the netbuf which contains the packet buffer to free
  * @param buf pointer to the netbuf which contains the packet buffer to free
  */
  */
-void
+void ESP_IRAM_ATTR
 netbuf_free(struct netbuf *buf)
 netbuf_free(struct netbuf *buf)
 {
 {
   LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
   LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);

+ 6 - 6
components/lwip/api/sockets.c

@@ -491,7 +491,7 @@ lwip_socket_thread_cleanup(void)
  * @param s externally used socket index
  * @param s externally used socket index
  * @return struct lwip_sock for the socket or NULL if not found
  * @return struct lwip_sock for the socket or NULL if not found
  */
  */
-static struct lwip_sock *
+static struct lwip_sock * ESP_IRAM_ATTR
 get_socket(int s)
 get_socket(int s)
 {
 {
   struct lwip_sock *sock;
   struct lwip_sock *sock;
@@ -962,7 +962,7 @@ lwip_listen(int s, int backlog)
   return 0;
   return 0;
 }
 }
 
 
-int
+int ESP_IRAM_ATTR
 lwip_recvfrom(int s, void *mem, size_t len, int flags,
 lwip_recvfrom(int s, void *mem, size_t len, int flags,
               struct sockaddr *from, socklen_t *fromlen)
               struct sockaddr *from, socklen_t *fromlen)
 {
 {
@@ -1340,7 +1340,7 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags)
 #endif /* LWIP_UDP || LWIP_RAW */
 #endif /* LWIP_UDP || LWIP_RAW */
 }
 }
 
 
-int
+int ESP_IRAM_ATTR
 lwip_sendto(int s, const void *data, size_t size, int flags,
 lwip_sendto(int s, const void *data, size_t size, int flags,
        const struct sockaddr *to, socklen_t tolen)
        const struct sockaddr *to, socklen_t tolen)
 {
 {
@@ -1817,7 +1817,7 @@ return_copy_fdsets:
  * Callback registered in the netconn layer for each socket-netconn.
  * Callback registered in the netconn layer for each socket-netconn.
  * Processes recvevent (data available) and wakes up tasks waiting for select.
  * Processes recvevent (data available) and wakes up tasks waiting for select.
  */
  */
-static void
+static void ESP_IRAM_ATTR
 event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
 event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
 {
 {
   int s;
   int s;
@@ -3159,7 +3159,7 @@ static void lwip_socket_drop_registered_memberships(int s)
 
 
 #if ESP_THREAD_SAFE
 #if ESP_THREAD_SAFE
 
 
-int
+int ESP_IRAM_ATTR
 lwip_sendto_r(int s, const void *data, size_t size, int flags,
 lwip_sendto_r(int s, const void *data, size_t size, int flags,
        const struct sockaddr *to, socklen_t tolen)
        const struct sockaddr *to, socklen_t tolen)
 {
 {
@@ -3176,7 +3176,7 @@ lwip_send_r(int s, const void *data, size_t size, int flags)
   LWIP_API_UNLOCK();
   LWIP_API_UNLOCK();
 }
 }
 
 
-int
+int ESP_IRAM_ATTR
 lwip_recvfrom_r(int s, void *mem, size_t len, int flags,
 lwip_recvfrom_r(int s, void *mem, size_t len, int flags,
               struct sockaddr *from, socklen_t *fromlen)
               struct sockaddr *from, socklen_t *fromlen)
 {
 {

+ 4 - 4
components/lwip/api/tcpip.c

@@ -77,7 +77,7 @@ sys_mutex_t lock_tcpip_core;
  *
  *
  * @param arg unused argument
  * @param arg unused argument
  */
  */
-static void
+static void ESP_IRAM_ATTR
 tcpip_thread(void *arg)
 tcpip_thread(void *arg)
 {
 {
 
 
@@ -195,7 +195,7 @@ tcpip_thread(void *arg)
  * @param inp the network interface on which the packet was received
  * @param inp the network interface on which the packet was received
  * @param input_fn input function to call
  * @param input_fn input function to call
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
 tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
 {
 {
 #if LWIP_TCPIP_CORE_LOCKING_INPUT
 #if LWIP_TCPIP_CORE_LOCKING_INPUT
@@ -244,7 +244,7 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
  *          NETIF_FLAG_ETHERNET flags)
  *          NETIF_FLAG_ETHERNET flags)
  * @param inp the network interface on which the packet was received
  * @param inp the network interface on which the packet was received
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 tcpip_input(struct pbuf *p, struct netif *inp)
 tcpip_input(struct pbuf *p, struct netif *inp)
 {
 {
 #if LWIP_ETHERNET
 #if LWIP_ETHERNET
@@ -363,7 +363,7 @@ tcpip_untimeout(sys_timeout_handler h, void *arg)
  * @param sem semaphore to wait on
  * @param sem semaphore to wait on
  * @return ERR_OK if the function was called, another err_t if not
  * @return ERR_OK if the function was called, another err_t if not
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 tcpip_send_api_msg(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem)
 tcpip_send_api_msg(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem)
 {
 {
   LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
   LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));

+ 3 - 3
components/lwip/core/inet_chksum.c

@@ -259,7 +259,7 @@ lwip_standard_chksum(const void *dataptr, int len)
 #endif
 #endif
 
 
 /** Parts of the pseudo checksum which are common to IPv4 and IPv6 */
 /** Parts of the pseudo checksum which are common to IPv4 and IPv6 */
-static u16_t
+static u16_t ESP_IRAM_ATTR
 inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc)
 inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc)
 {
 {
   struct pbuf *q;
   struct pbuf *q;
@@ -309,7 +309,7 @@ inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc)
  * @param proto_len length of the ip data part (used for checksum of pseudo header)
  * @param proto_len length of the ip data part (used for checksum of pseudo header)
  * @return checksum (as u16_t) to be saved directly in the protocol header
  * @return checksum (as u16_t) to be saved directly in the protocol header
  */
  */
-u16_t
+u16_t ESP_IRAM_ATTR
 inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
 inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
        const ip4_addr_t *src, const ip4_addr_t *dest)
        const ip4_addr_t *src, const ip4_addr_t *dest)
 {
 {
@@ -378,7 +378,7 @@ ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
  * @param proto_len length of the ip data part (used for checksum of pseudo header)
  * @param proto_len length of the ip data part (used for checksum of pseudo header)
  * @return checksum (as u16_t) to be saved directly in the protocol header
  * @return checksum (as u16_t) to be saved directly in the protocol header
  */
  */
-u16_t
+u16_t ESP_IRAM_ATTR
 ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
 ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
        const ip_addr_t *src, const ip_addr_t *dest)
        const ip_addr_t *src, const ip_addr_t *dest)
 {
 {

+ 6 - 6
components/lwip/core/ipv4/ip4.c

@@ -136,7 +136,7 @@ bool ip4_netif_exist(const ip4_addr_t *src, const ip4_addr_t *dest)
  * Source based IPv4 routing hook function. This function works only
  * Source based IPv4 routing hook function. This function works only
  * when destination IP is broadcast IP.
  * when destination IP is broadcast IP.
  */
  */
-struct netif *
+struct netif * ESP_IRAM_ATTR
 ip4_route_src_hook(const ip4_addr_t *dest, const ip4_addr_t *src)
 ip4_route_src_hook(const ip4_addr_t *dest, const ip4_addr_t *src)
 {
 {
   struct netif *netif = NULL;
   struct netif *netif = NULL;
@@ -162,7 +162,7 @@ ip4_route_src_hook(const ip4_addr_t *dest, const ip4_addr_t *src)
  * Source based IPv4 routing must be fully implemented in
  * Source based IPv4 routing must be fully implemented in
  * LWIP_HOOK_IP4_ROUTE_SRC(). This function only provides the parameters.
  * LWIP_HOOK_IP4_ROUTE_SRC(). This function only provides the parameters.
  */
  */
-struct netif *
+struct netif * ESP_IRAM_ATTR
 ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)
 ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)
 {
 {
   if (src != NULL) {
   if (src != NULL) {
@@ -189,7 +189,7 @@ ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)
  * @param dest the destination IP address for which to find the route
  * @param dest the destination IP address for which to find the route
  * @return the netif on which to send to reach dest
  * @return the netif on which to send to reach dest
  */
  */
-struct netif *
+struct netif * ESP_IRAM_ATTR
 ip4_route(const ip4_addr_t *dest)
 ip4_route(const ip4_addr_t *dest)
 {
 {
   struct netif *netif;
   struct netif *netif;
@@ -410,7 +410,7 @@ return_noroute:
  * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
  * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
  *         processed, but currently always returns ERR_OK)
  *         processed, but currently always returns ERR_OK)
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 ip4_input(struct pbuf *p, struct netif *inp)
 ip4_input(struct pbuf *p, struct netif *inp)
 {
 {
   struct ip_hdr *iphdr;
   struct ip_hdr *iphdr;
@@ -818,7 +818,7 @@ ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
  * Same as ip_output_if() but 'src' address is not replaced by netif address
  * Same as ip_output_if() but 'src' address is not replaced by netif address
  * when it is 'any'.
  * when it is 'any'.
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
 ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
              u8_t ttl, u8_t tos,
              u8_t ttl, u8_t tos,
              u8_t proto, struct netif *netif)
              u8_t proto, struct netif *netif)
@@ -831,7 +831,7 @@ ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
  * Same as ip_output_if_opt() but 'src' address is not replaced by netif address
  * Same as ip_output_if_opt() but 'src' address is not replaced by netif address
  * when it is 'any'.
  * when it is 'any'.
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
 ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
        u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
        u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
        u16_t optlen)
        u16_t optlen)

+ 1 - 1
components/lwip/core/ipv4/ip4_addr.c

@@ -55,7 +55,7 @@ const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST);
  * @param netif the network interface against which the address is checked
  * @param netif the network interface against which the address is checked
  * @return returns non-zero if the address is a broadcast address
  * @return returns non-zero if the address is a broadcast address
  */
  */
-u8_t
+u8_t ESP_IRAM_ATTR
 ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif)
 ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif)
 {
 {
   ip4_addr_t ipaddr;
   ip4_addr_t ipaddr;

+ 2 - 2
components/lwip/core/pbuf.c

@@ -513,7 +513,7 @@ pbuf_realloc(struct pbuf *p, u16_t new_len)
  * @return non-zero on failure, zero on success.
  * @return non-zero on failure, zero on success.
  *
  *
  */
  */
-static u8_t
+static u8_t ESP_IRAM_ATTR
 pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force)
 pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force)
 {
 {
   u16_t type;
   u16_t type;
@@ -609,7 +609,7 @@ pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force)
  * @return non-zero on failure, zero on success.
  * @return non-zero on failure, zero on success.
  *
  *
  */
  */
-u8_t
+u8_t ESP_IRAM_ATTR
 pbuf_header(struct pbuf *p, s16_t header_size_increment)
 pbuf_header(struct pbuf *p, s16_t header_size_increment)
 {
 {
    return pbuf_header_impl(p, header_size_increment, 0);
    return pbuf_header_impl(p, header_size_increment, 0);

+ 1 - 1
components/lwip/core/timers.c

@@ -535,7 +535,7 @@ sys_timeouts_sleeptime(void)
  * @param mbox the mbox to fetch the message from
  * @param mbox the mbox to fetch the message from
  * @param msg the place to store the message
  * @param msg the place to store the message
  */
  */
-void
+void ESP_IRAM_ATTR
 sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
 sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
 {
 {
   u32_t time_needed;
   u32_t time_needed;

+ 6 - 6
components/lwip/core/udp.c

@@ -146,7 +146,7 @@ again:
  * @param broadcast 1 if his is an IPv4 broadcast (global or subnet-only), 0 otherwise (only used for IPv4)
  * @param broadcast 1 if his is an IPv4 broadcast (global or subnet-only), 0 otherwise (only used for IPv4)
  * @return 1 on match, 0 otherwise
  * @return 1 on match, 0 otherwise
  */
  */
-static u8_t
+static u8_t ESP_IRAM_ATTR
 udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast)
 udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast)
 {
 {
   LWIP_UNUSED_ARG(inp);       /* in IPv6 only case */
   LWIP_UNUSED_ARG(inp);       /* in IPv6 only case */
@@ -210,7 +210,7 @@ udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast)
  * @param inp network interface on which the datagram was received.
  * @param inp network interface on which the datagram was received.
  *
  *
  */
  */
-void
+void ESP_IRAM_ATTR
 udp_input(struct pbuf *p, struct netif *inp)
 udp_input(struct pbuf *p, struct netif *inp)
 {
 {
   struct udp_hdr *udphdr;
   struct udp_hdr *udphdr;
@@ -474,7 +474,7 @@ chkerr:
  *
  *
  * @see udp_disconnect() udp_sendto()
  * @see udp_disconnect() udp_sendto()
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 udp_send(struct udp_pcb *pcb, struct pbuf *p)
 udp_send(struct udp_pcb *pcb, struct pbuf *p)
 {
 {
   if ((pcb == NULL) || IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) {
   if ((pcb == NULL) || IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) {
@@ -519,7 +519,7 @@ udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p,
  *
  *
  * @see udp_disconnect() udp_send()
  * @see udp_disconnect() udp_send()
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
 udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
   const ip_addr_t *dst_ip, u16_t dst_port)
   const ip_addr_t *dst_ip, u16_t dst_port)
 {
 {
@@ -615,7 +615,7 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
  *
  *
  * @see udp_disconnect() udp_send()
  * @see udp_disconnect() udp_send()
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
 udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
   const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif)
   const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif)
 {
 {
@@ -681,7 +681,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_i
 }
 }
 
 
 /** Same as udp_sendto_if(), but with source address */
 /** Same as udp_sendto_if(), but with source address */
-err_t
+err_t ESP_IRAM_ATTR
 udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p,
 udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p,
   const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, const ip_addr_t *src_ip)
   const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, const ip_addr_t *src_ip)
 {
 {

+ 6 - 0
components/lwip/include/lwip/port/lwipopts.h

@@ -727,6 +727,12 @@
 #define ESP_LWIP_LOGI(...)              ESP_LOGI("lwip", __VA_ARGS__)
 #define ESP_LWIP_LOGI(...)              ESP_LOGI("lwip", __VA_ARGS__)
 #define ESP_PING                        1
 #define ESP_PING                        1
 
 
+#if CONFIG_LWIP_IRAM_OPTIMIZATION
+#define ESP_IRAM_ATTR                   IRAM_ATTR
+#else
+#define ESP_IRAM_ATTR                   
+#endif
+
 #define TCP_WND_DEFAULT                 CONFIG_TCP_WND_DEFAULT
 #define TCP_WND_DEFAULT                 CONFIG_TCP_WND_DEFAULT
 #define TCP_SND_BUF_DEFAULT             CONFIG_TCP_SND_BUF_DEFAULT
 #define TCP_SND_BUF_DEFAULT             CONFIG_TCP_SND_BUF_DEFAULT
 
 

+ 3 - 3
components/lwip/netif/etharp.c

@@ -404,7 +404,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif* netif)
  * @params dst the destination MAC address to be copied into the ethernet header
  * @params dst the destination MAC address to be copied into the ethernet header
  * @return ERR_OK if the packet was sent, any other err_t on failure
  * @return ERR_OK if the packet was sent, any other err_t on failure
  */
  */
-static err_t
+static err_t ESP_IRAM_ATTR
 etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, const struct eth_addr *dst)
 etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, const struct eth_addr *dst)
 {
 {
   struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
   struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
@@ -872,7 +872,7 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
 /** Just a small helper function that sends a pbuf to an ethernet address
 /** Just a small helper function that sends a pbuf to an ethernet address
  * in the arp_table specified by the index 'arp_idx'.
  * in the arp_table specified by the index 'arp_idx'.
  */
  */
-static err_t
+static err_t ESP_IRAM_ATTR
 etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
 etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
 {
 {
   LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
   LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
@@ -916,7 +916,7 @@ etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
  * - ERR_RTE No route to destination (no gateway to external networks),
  * - ERR_RTE No route to destination (no gateway to external networks),
  * or the return type of either etharp_query() or etharp_send_ip().
  * or the return type of either etharp_query() or etharp_send_ip().
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
 etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
 {
 {
   const struct eth_addr *dest;
   const struct eth_addr *dest;

+ 1 - 1
components/lwip/netif/ethernet.c

@@ -63,7 +63,7 @@ const struct eth_addr ethzero = {{0,0,0,0,0,0}};
  * @param p the received packet, p->payload pointing to the ethernet header
  * @param p the received packet, p->payload pointing to the ethernet header
  * @param netif the network interface on which the packet was received
  * @param netif the network interface on which the packet was received
  */
  */
-err_t
+err_t ESP_IRAM_ATTR
 ethernet_input(struct pbuf *p, struct netif *netif)
 ethernet_input(struct pbuf *p, struct netif *netif)
 {
 {
   struct eth_hdr* ethhdr;
   struct eth_hdr* ethhdr;

+ 7 - 7
components/lwip/port/freertos/sys_arch.c

@@ -72,7 +72,7 @@ sys_mutex_new(sys_mutex_t *pxMutex)
 
 
 /** Lock a mutex
 /** Lock a mutex
  * @param mutex the mutex to lock */
  * @param mutex the mutex to lock */
-void
+void ESP_IRAM_ATTR
 sys_mutex_lock(sys_mutex_t *pxMutex)
 sys_mutex_lock(sys_mutex_t *pxMutex)
 {
 {
   while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS);
   while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS);
@@ -87,7 +87,7 @@ sys_mutex_trylock(sys_mutex_t *pxMutex)
 
 
 /** Unlock a mutex
 /** Unlock a mutex
  * @param mutex the mutex to unlock */
  * @param mutex the mutex to unlock */
-void
+void ESP_IRAM_ATTR
 sys_mutex_unlock(sys_mutex_t *pxMutex)
 sys_mutex_unlock(sys_mutex_t *pxMutex)
 {
 {
   xSemaphoreGive(*pxMutex);
   xSemaphoreGive(*pxMutex);
@@ -127,7 +127,7 @@ sys_sem_new(sys_sem_t *sem, u8_t count)
 
 
 /*-----------------------------------------------------------------------------------*/
 /*-----------------------------------------------------------------------------------*/
 // Signals a semaphore
 // Signals a semaphore
-void
+void ESP_IRAM_ATTR
 sys_sem_signal(sys_sem_t *sem)
 sys_sem_signal(sys_sem_t *sem)
 {
 {
     xSemaphoreGive(*sem);
     xSemaphoreGive(*sem);
@@ -149,7 +149,7 @@ sys_sem_signal(sys_sem_t *sem)
   Notice that lwIP implements a function with a similar name,
   Notice that lwIP implements a function with a similar name,
   sys_sem_wait(), that uses the sys_arch_sem_wait() function.
   sys_sem_wait(), that uses the sys_arch_sem_wait() function.
 */
 */
-u32_t
+u32_t ESP_IRAM_ATTR
 sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
 sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
 {
 {
   portTickType StartTime, EndTime, Elapsed;
   portTickType StartTime, EndTime, Elapsed;
@@ -228,14 +228,14 @@ sys_mbox_new(sys_mbox_t *mbox, int size)
 
 
 /*-----------------------------------------------------------------------------------*/
 /*-----------------------------------------------------------------------------------*/
 //   Posts the "msg" to the mailbox.
 //   Posts the "msg" to the mailbox.
-void
+void ESP_IRAM_ATTR
 sys_mbox_post(sys_mbox_t *mbox, void *msg)
 sys_mbox_post(sys_mbox_t *mbox, void *msg)
 {
 {
   while (xQueueSendToBack((*mbox)->os_mbox, &msg, portMAX_DELAY) != pdTRUE);
   while (xQueueSendToBack((*mbox)->os_mbox, &msg, portMAX_DELAY) != pdTRUE);
 }
 }
 
 
 /*-----------------------------------------------------------------------------------*/
 /*-----------------------------------------------------------------------------------*/
-err_t
+err_t ESP_IRAM_ATTR
 sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
 sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
 {
 {
   err_t xReturn;
   err_t xReturn;
@@ -266,7 +266,7 @@ sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
   Note that a function with a similar name, sys_mbox_fetch(), is
   Note that a function with a similar name, sys_mbox_fetch(), is
   implemented by lwIP.
   implemented by lwIP.
 */
 */
-u32_t
+u32_t ESP_IRAM_ATTR
 sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
 sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
 {
 {
   void *dummyptr;
   void *dummyptr;

+ 2 - 2
components/lwip/port/netif/wlanif.c

@@ -101,7 +101,7 @@ low_level_init(struct netif *netif)
  *       to become availale since the stack doesn't retry to send a packet
  *       to become availale since the stack doesn't retry to send a packet
  *       dropped because of memory failure (except for the TCP timers).
  *       dropped because of memory failure (except for the TCP timers).
  */
  */
-static err_t
+static err_t ESP_IRAM_ATTR
 low_level_output(struct netif *netif, struct pbuf *p)
 low_level_output(struct netif *netif, struct pbuf *p)
 {
 {
   wifi_interface_t wifi_if = tcpip_adapter_get_esp_if(netif);
   wifi_interface_t wifi_if = tcpip_adapter_get_esp_if(netif);
@@ -139,7 +139,7 @@ low_level_output(struct netif *netif, struct pbuf *p)
  *
  *
  * @param netif the lwip network interface structure for this ethernetif
  * @param netif the lwip network interface structure for this ethernetif
  */
  */
-void
+void ESP_IRAM_ATTR
 wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
 wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
 {
 {
   struct pbuf *p;
   struct pbuf *p;

+ 19 - 13
examples/wifi/iperf/components/iperf.c

@@ -110,7 +110,8 @@ esp_err_t iperf_start_report(void)
 {
 {
     int ret;
     int ret;
 
 
-    ret = xTaskCreate(iperf_report_task, IPERF_REPORT_TASK_NAME, IPERF_REPORT_TASK_STACK, NULL, IPERF_REPORT_TASK_PRIORITY, NULL);
+    ret = xTaskCreatePinnedToCore(iperf_report_task, IPERF_REPORT_TASK_NAME, IPERF_REPORT_TASK_STACK, NULL, IPERF_REPORT_TASK_PRIORITY, NULL, portNUM_PROCESSORS-1);
+
     if (ret != pdPASS)  {
     if (ret != pdPASS)  {
         ESP_LOGE(TAG, "create task %s failed", IPERF_REPORT_TASK_NAME);
         ESP_LOGE(TAG, "create task %s failed", IPERF_REPORT_TASK_NAME);
         return ESP_FAIL;
         return ESP_FAIL;
@@ -191,7 +192,7 @@ esp_err_t iperf_run_tcp_server(void)
     return ESP_OK;
     return ESP_OK;
 }
 }
 
 
-esp_err_t iperf_run_udp_server(void)
+esp_err_t IRAM_ATTR iperf_run_udp_server(void)
 {
 {
     socklen_t addr_len = sizeof(struct sockaddr_in);
     socklen_t addr_len = sizeof(struct sockaddr_in);
     struct sockaddr_in addr;
     struct sockaddr_in addr;
@@ -321,7 +322,8 @@ esp_err_t iperf_run_udp_client(void)
 
 
 esp_err_t iperf_run_tcp_client(void)
 esp_err_t iperf_run_tcp_client(void)
 {
 {
-    struct sockaddr_in addr;
+    struct sockaddr_in local_addr;
+    struct sockaddr_in remote_addr;
     int actual_send = 0;
     int actual_send = 0;
     int want_send = 0;
     int want_send = 0;
     uint8_t *buffer;
     uint8_t *buffer;
@@ -336,19 +338,21 @@ esp_err_t iperf_run_tcp_client(void)
 
 
     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
 
 
-    addr.sin_family = AF_INET;
-    addr.sin_port = 0;
-    addr.sin_addr.s_addr = s_iperf_ctrl.cfg.sip;
-    if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
+    memset(&local_addr, 0, sizeof(local_addr));
+    local_addr.sin_family = AF_INET;
+    local_addr.sin_port = 0;
+    local_addr.sin_addr.s_addr = s_iperf_ctrl.cfg.sip;
+    if (bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)) != 0) {
         iperf_show_socket_error_reason("tcp client bind", sockfd);
         iperf_show_socket_error_reason("tcp client bind", sockfd);
         return ESP_FAIL;
         return ESP_FAIL;
     }
     }
 
 
 
 
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(s_iperf_ctrl.cfg.dport);
-    addr.sin_addr.s_addr = s_iperf_ctrl.cfg.dip;
-    if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+    memset(&remote_addr, 0, sizeof(remote_addr));
+    remote_addr.sin_family = AF_INET;
+    remote_addr.sin_port = htons(s_iperf_ctrl.cfg.dport);
+    remote_addr.sin_addr.s_addr = s_iperf_ctrl.cfg.dip;
+    if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) < 0) {
         iperf_show_socket_error_reason("tcp client connect", sockfd);
         iperf_show_socket_error_reason("tcp client connect", sockfd);
         return ESP_FAIL;
         return ESP_FAIL;
     }
     }
@@ -359,7 +363,8 @@ esp_err_t iperf_run_tcp_client(void)
     while (!s_iperf_ctrl.finish) {
     while (!s_iperf_ctrl.finish) {
         actual_send = send(sockfd, buffer, want_send, 0);
         actual_send = send(sockfd, buffer, want_send, 0);
         if (actual_send <= 0) {
         if (actual_send <= 0) {
-            vTaskDelay(1);
+            iperf_show_socket_error_reason("tcp client send", sockfd);
+            break;
         } else {
         } else {
             s_iperf_ctrl.total_len += actual_send;
             s_iperf_ctrl.total_len += actual_send;
         }
         }
@@ -427,8 +432,9 @@ esp_err_t iperf_start(iperf_cfg_t *cfg)
         ESP_LOGE(TAG, "create buffer: out of memory");
         ESP_LOGE(TAG, "create buffer: out of memory");
         return ESP_FAIL;
         return ESP_FAIL;
     }
     }
+    memset(s_iperf_ctrl.buffer, 0, s_iperf_ctrl.buffer_len);
 
 
-    ret = xTaskCreate(iperf_task_traffic, IPERF_TRAFFIC_TASK_NAME, IPERF_TRAFFIC_TASK_STACK, NULL, IPERF_TRAFFIC_TASK_PRIORITY, NULL);
+    ret = xTaskCreatePinnedToCore(iperf_task_traffic, IPERF_TRAFFIC_TASK_NAME, IPERF_TRAFFIC_TASK_STACK, NULL, IPERF_TRAFFIC_TASK_PRIORITY, NULL, portNUM_PROCESSORS-1);
     if (ret != pdPASS)  {
     if (ret != pdPASS)  {
         ESP_LOGE(TAG, "create task %s failed", IPERF_TRAFFIC_TASK_NAME);
         ESP_LOGE(TAG, "create task %s failed", IPERF_TRAFFIC_TASK_NAME);
         free(s_iperf_ctrl.buffer);
         free(s_iperf_ctrl.buffer);

+ 5 - 5
examples/wifi/iperf/components/iperf.h

@@ -24,17 +24,17 @@ extern "C" {
 #define IPERF_DEFAULT_TIME     30
 #define IPERF_DEFAULT_TIME     30
 
 
 #define IPERF_TRAFFIC_TASK_NAME       "iperf_traffic"
 #define IPERF_TRAFFIC_TASK_NAME       "iperf_traffic"
-#define IPERF_TRAFFIC_TASK_PRIORITY   19
+#define IPERF_TRAFFIC_TASK_PRIORITY   10
 #define IPERF_TRAFFIC_TASK_STACK      4096
 #define IPERF_TRAFFIC_TASK_STACK      4096
 #define IPERF_REPORT_TASK_NAME        "iperf_report"
 #define IPERF_REPORT_TASK_NAME        "iperf_report"
-#define IPERF_REPORT_TASK_PRIORITY    10
+#define IPERF_REPORT_TASK_PRIORITY    20
 #define IPERF_REPORT_TASK_STACK       4096
 #define IPERF_REPORT_TASK_STACK       4096
 #define IPERF_REPORT_TASK_NAME        "iperf_report"
 #define IPERF_REPORT_TASK_NAME        "iperf_report"
 
 
 #define IPERF_UDP_TX_LEN     (1472)
 #define IPERF_UDP_TX_LEN     (1472)
-#define IPERF_UDP_RX_LEN     (32<<10)
-#define IPERF_TCP_TX_LEN     (32<<10)
-#define IPERF_TCP_RX_LEN     (32<<10)
+#define IPERF_UDP_RX_LEN     (16<<10)
+#define IPERF_TCP_TX_LEN     (16<<10)
+#define IPERF_TCP_RX_LEN     (16<<10)
 
 
 #define IPERF_MAX_DELAY      64
 #define IPERF_MAX_DELAY      64
 
 

+ 6 - 2
examples/wifi/iperf/sdkconfig.defaults

@@ -6,9 +6,9 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=16
 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=64
 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=64
 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=64
 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=64
 CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
 CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
-CONFIG_ESP32_WIFI_TX_BA_WIN=12
+CONFIG_ESP32_WIFI_TX_BA_WIN=32
 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
-CONFIG_ESP32_WIFI_RX_BA_WIN=12
+CONFIG_ESP32_WIFI_RX_BA_WIN=32
 
 
 CONFIG_FREERTOS_UNICORE=
 CONFIG_FREERTOS_UNICORE=
 CONFIG_FREERTOS_HZ=1000
 CONFIG_FREERTOS_HZ=1000
@@ -23,3 +23,7 @@ CONFIG_UDP_RECVMBOX_SIZE=64
 CONFIG_TCPIP_RECVMBOX_SIZE=64
 CONFIG_TCPIP_RECVMBOX_SIZE=64
 CONFIG_LWIP_ETHARP_TRUST_IP_MAC=
 CONFIG_LWIP_ETHARP_TRUST_IP_MAC=
 
 
+CONFIG_FLASHMODE_QIO=y
+CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
+CONFIG_LWIP_IRAM_OPTIMIZATION=y
+