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