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