Hello all,

I'm working on a project using lwIP 1.4.1, FreeRTOS 7.4.2 on an
STM32F407 MCU.
I have several UDP/TCP/Multicast services running well, but when I tried to measure TCP bandwidth with Iperf as well as with dd|nc, I get very low results. Iperf basically just sends a lot of data and lwIP drops it (using netconn_recv();netbuf_delete() or netconn_recv_tcp_pbuf();pbuf_free();)

An analysis with Wireshark shows the following:
(TCP_MSS=TCP_WND=1460)
- SYN,SYNACK,ACK,PSH,PSH (as usual)
- ZeroWindow (client stuck), WindowUpdate (some ms later)
- PSH, ZeroWindow, WindowUpdate,...

As I understand it, this is how TCP works. Quite low bandwidth (a few
hundred kBps) with these settings, but it works.
When I try to increase TCP_WND to p.e. 5kB, the following problems arise:
- Dup ACKs (from lwIP)
- lots of Retransmissions (from Linux)
The bandwidth is in the Bps to kBps range (at most). I spent hours, but have no clue where to look next. Any ideas what could be the reason?(Iperf Linux to Linux results in the full line speed)

One interesting thing is: I get about 0.5% packet drop if I do a ping -f (100 Pings per second, packets seem to never arrive at the Eth interrupt). MCU load is always quite low (I have a low prio blink task that still gets its CPU time as well as )
Things I already fixed: (my design bases on ST's ethernet code)
- Check any stacks/NULL/malloc fails
- Check if pbuf fits into Tx buffer
- Check if there is enough pbuf_mem to fits Rx packet
- In packet reception I try to drain the input queue (by checking
DMARxDescToGet->Status & ETH_DMARxDesc_OWN )
- ETH_DMASR_RBUS cleared in low_level_input()

I just ran out of ideas how to fix the problem. Is this about tuning lwipopts.h? Attached, my current version.

Best regards

Claudius



#pragma once

//Options tuned for STM32F407 with FreeRTOS 7.4.2 and LwIP 1.4.1
//Defaults are in in <lwipsrc>/include/lwip/opt.h

#define SYS_LIGHTWEIGHT_PROT    1 //default 0
//#define ETHARP_TRUST_IP_MAC     0  //default 0
//#define IP_REASSEMBLY           0  //default 1
//#define IP_FRAG                 0  //default 1
//#define ARP_QUEUEING            0 //Length of queue of pending ARP requests
//#define TCP_LISTEN_BACKLOG      1  //default 0
//Use hardware based random number generator. Init done in ethernetif_init
#define LWIP_USE_HW_RAND 		1


////////////////////////////////////////////////////////////////////////////////
// ---------- Memory options ----------
// Alignment of memory blocks. Cortex-m/DMA can live with byte alignment, but
// then the DMA would need additional transfers which would slow down things.
#define MEM_ALIGNMENT           4

// MEM_SIZE: the size of the heap memory. If the application will send
// a lot of data that needs to be copied, this should be set high.
#define MEM_SIZE                (4*1500) //default 1600

// MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
// sends a lot of data out of ROM (or other static memory), this
// should be set high.
// sizeof(pbuf) = 16B...28B(USE_PTP==1)
#define MEMP_NUM_PBUF           32 //default 16

// MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
// per active UDP "connection".
// sizeof(udp_pcb) = 32B(IGMP)
#define MEMP_NUM_UDP_PCB        8  //default 4

// MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
// connections.
// sizeof(tcp_pcb)=164B
#define MEMP_NUM_TCP_PCB        24 //default 5

// MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
// connections.
//#define MEMP_NUM_TCP_PCB_LISTEN 4 //default 8

// MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
//#define MEMP_NUM_TCP_SEG        16 //default 16

// MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg
#define MEMP_NUM_TCPIP_MSG_INPKT 32 //default 8

// MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
// timeouts.
//#define MEMP_NUM_SYS_TIMEOUT    10 //default 6
//LPC
//#define MEMP_NUM_SYS_TIMEOUT 300

// MEMP_NUM_NETBUF: the number of struct netbufs. (When using seq API)
// sizeof(netbuf)=16B
#define MEMP_NUM_NETBUF          4 //default: 2

// MEMP_NUM_NETCONN: the number of struct netconns.
//sizeof(netconn)=59B
#define MEMP_NUM_NETCONN         16 //default: 4

// ---------- Pbuf options ----------
// PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
#define PBUF_POOL_SIZE          20 //default: 16
//#define PBUF_POOL_SIZE          7 //LPC default


// PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool.
// This is the maximum payload size of one pbuf.
// Bigger packets will be split into multiple chained pbufs.
// Smaller is memory efficient, bigger is speed efficient
//#define PBUF_POOL_BUFSIZE       512 //default: TCP_MSS+40+PBUF_LINK_HLEN

////////////////////////////////////////////////////////////////////////////////
// ---------- TCP options ----------
#define LWIP_TCP                1
//#define TCP_TTL                 255

// Controls if TCP should queue segments that arrive out of
// order. Define to 0 if your device is low on memory.
//STM32f4-Example: #define TCP_QUEUE_OOSEQ         0
//#define TCP_QUEUE_OOSEQ         1 //default 1

// TCP Maximum segment size.
#define TCP_MSS                 (1500 - 40) // TCP_MSS = (Ethernet MTU - IP header size - TCP header size), default 536

// TCP sender buffer space (bytes).
//#define TCP_SND_BUF             (5*TCP_MSS) // default (2 * TCP_MSS)

// TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
// as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
//#define TCP_SND_QUEUELEN        (4* TCP_SND_BUF/TCP_MSS) //default: ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))

// TCP receive window.
//Every TCP_WND bytes of payload, there will be an ACK packet
#define TCP_WND                 (2*TCP_MSS) //default: (4 * TCP_MSS)


///////////////////////////////////////
//  IP Protocol support
// ---------- ICMP options ----------
//#define LWIP_ICMP                       1 //default 1

// ---------- IGMP options ----------
#define LWIP_IGMP                       1 //default 0

// ---------- DHCP options ----------
// Define LWIP_DHCP to 1 if you want DHCP configuration
#define LWIP_DHCP               1
// Get NTP servers from DHCP
#define LWIP_DHCP_NTP			(LWIP_DHCP)
// The maximum of NTP servers
#define NTP_MAX_SERVERS                 2

#define LWIP_NETIF_HOSTNAME             1
#define LWIP_AUTOIP                     1
#define LWIP_DHCP_AUTOIP_COOP           1 //Fallback if dhcp fails
#define LWIP_DHCP_AUTOIP_COOP_TRIES     5

// ---------- UDP options ----------
//#define LWIP_UDP                1 //default 1
//#define UDP_TTL                 255 //default

// ---------- PTP options ----------
//#define LWIP_PTP                       1 //default 0


//done in Makefile #define LWIP_SNMP 1
////////////////////////////////////////////////////////////////////////////////
// ---------- Statistics options ----------
#define LWIP_STATS                        1 //default 1 (collect statistics)
#define LWIP_STATS_DISPLAY                1 //default 0 (enable display functions)
#define LWIP_PROVIDE_ERRNO                1


// --------------------------------------
// ---------- Checksum options ----------
// --------------------------------------

#ifndef CHECKSUM_BY_HARDWARE
	#define CHECKSUM_BY_HARDWARE
#endif

#ifdef CHECKSUM_BY_HARDWARE
  // CHECKSUM_GEN_*==0: Generate checksums by hardware for outgoing * packets.
  #define CHECKSUM_GEN_IP                 0
  #define CHECKSUM_GEN_UDP                0
  #define CHECKSUM_GEN_TCP                0 
  #define CHECKSUM_GEN_ICMP               0
  // CHECKSUM_CHECK_*==0: Check checksums by hardware for incoming * packets.
  #define CHECKSUM_CHECK_IP               0
  #define CHECKSUM_CHECK_UDP              0
  #define CHECKSUM_CHECK_TCP              0
  //#define CHECKSUM_CHECK_ICMP             0 doesn't exist
#else
  // CHECKSUM_GEN_*==1: Generate checksums in software for outgoing * packets.
  #define CHECKSUM_GEN_IP                 1
  #define CHECKSUM_GEN_UDP                1
  #define CHECKSUM_GEN_TCP                1
  #define CHECKSUM_GEN_ICMP               1
  // CHECKSUM_CHECK_*==1: Check checksums in software for incoming * packets.
  #define CHECKSUM_CHECK_IP               1
  #define CHECKSUM_CHECK_UDP              1
  #define CHECKSUM_CHECK_TCP              1
//  #define CHECKSUM_CHECK_ICMP             1 doesn't exist
#endif


////////////////////////////////////////////////////////////////////////////////
// API options

// LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
// NOT thread safe
#define LWIP_RAW                        0

// LWIP_NETCONN==1: Enable Netconn API (required to use api_lib.c)
#define LWIP_NETCONN                    1
#define LWIP_SO_RCVTIMEO                1
#define LWIP_NETIF_API                  1

// LWIP_SOCKET==1: Enable Socket API (required to use sockets.c)
#define LWIP_SOCKET                     0


// -----------------------------------
// ---------- DEBUG options ----------
// -----------------------------------

#define LWIP_DEBUG                      1 //default:0
//#define LWIP_NOASSERT //Kills all asserts
//#define LWIP_ERROR //Kills all LWIP_ERROR checks
//#define LWIP_DBG_MIN_LEVEL                //default:LWIP_DBG_LEVEL_ALL
////#define ETHARP_DEBUG                    LWIP_DBG_ON //default:off
////#define ICMP_DEBUG                      LWIP_DBG_ON //default:off
//#define AUTOIP_DEBUG                    LWIP_DBG_ON //default:off
//#define DHCP_DEBUG                      LWIP_DBG_ON //default:off
//#define TCP_DEBUG                       LWIP_DBG_ON //default:off
//#define TCP_INPUT_DEBUG                 LWIP_DBG_ON
//#define TCP_OUTPUT_DEBUG                LWIP_DBG_ON
//#define INET_DEBUG                      LWIP_DBG_ON
//#define IP_DEBUG                        LWIP_DBG_ON
#define IP_REASS_DEBUG                  LWIP_DBG_ON
//#define TCPIP_DEBUG                     LWIP_DBG_ON
#define TCP_FR_DEBUG                    LWIP_DBG_ON //fast retransmit
#define TCP_RTO_DEBUG                   LWIP_DBG_ON //retransmit timeout
//#define TCP_CWND_DEBUG                  LWIP_DBG_ON //congestion window
//#define TCP_WND_DEBUG                   LWIP_DBG_ON //window updating
//#define TCP_RST_DEBUG                   LWIP_DBG_ON
#define TCP_QLEN_DEBUG                  LWIP_DBG_ON //TCP queue lengths

#define MEMP_DEBUG                      LWIP_DBG_ON //default:off
#define MEM_DEBUG                       LWIP_DBG_ON //default:off
//#define IGMP_DEBUG                      LWIP_DBG_ON //default:off
//#define NTP_DEBUG                       LWIP_DBG_ON //default:off
//#define PBUF_DEBUG                      LWIP_DBG_ON //default:off creates a lot of debugging info


// ---------------------------------
// ---------- OS options ----------
// ---------------------------------

//tcpip-Thread: Main processing thread of IP
#define TCPIP_THREAD_NAME              "tcp_ip"
#define TCPIP_THREAD_PRIO               (tskIDLE_PRIORITY + 2)
#define TCPIP_THREAD_STACKSIZE          512
#define TCPIP_MBOX_SIZE                 32

//eth-Thread:
#define netifINTERFACE_TASK_NAME        "eth_if"
#define netifINTERFACE_TASK_PRIORITY	( tskIDLE_PRIORITY + 2 )
#define netifINTERFACE_TASK_STACK_SIZE	(  512 )

//app-threads: lwip Apps (not used anymore)
#define DEFAULT_THREAD_STACKSIZE        512
#define DEFAULT_THREAD_PRIO             (tskIDLE_PRIORITY + 2)

//Mailboxes for netconn objects
#define DEFAULT_RAW_RECVMBOX_SIZE       256
#define DEFAULT_UDP_RECVMBOX_SIZE       256
#define DEFAULT_TCP_RECVMBOX_SIZE       256
#define DEFAULT_ACCEPTMBOX_SIZE         32

//#define DEFAULT_UDP_RECVMBOX_SIZE       2000
//#define DEFAULT_TCP_RECVMBOX_SIZE       2000


_______________________________________________
lwip-users mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to