Hi, I am experiencing a particular behaviour with opening/closing TCP sockets. In my application I must regularly transmit from my device RTP packets every millisecond. I am also listening on a RTP stream and I receive and handle packets every millisecond. This works fine until I try to open a TCP socket (telnet or http connection). In this case it often happens that my transmitted packets are delayed and the received packet are not available on the stack when I need them. It seems that all tcpip thread is stuck in doing some operations related to TCP and UDP traffic cannot be received or transmitted. I attach 2 wireshark tracks, one that shows the problem and one that don't. The problem is visible because my device (192.168.10.108) in one case cannot send a UDP packet after exactly 1 ms from the previous one, just after a TCP socket opening, and in the other case it succeds. My computer is 192.168.10.1, and I am opening a telnet connection on the device.
Lwip statistics shows no error on TCP or UDP, and actually there are no errors because packets are not lost. I am running my code on an NXP MIMXRT1051, lwip version is STABLE-2_1_3_RELEASE and I attach also my lwipopts.h file. Tcpip thread has the highest priority on my SW while both telnet server or http server have a very low priority. UDP thread that sends and receive data has the immediately lower priority than tcpip thread. I tried many things like using custom pool instead of lwip malloc, or using hw acceleration or even using last lwip beta but the problem persists. I don't know if this can be called a real issue because my real time requirements are strict and lwip may not guarantee to satisfy them but could you help me in trying to solve this issue? Are there any lwip options that I can set to give priority to UDP or try to make TCP more reactive on opening or closing of sockets? Thank you very much for your help. Greetings, Leonardo Leonardo Fibucchi FIRMWARE ENGINEERING SPECIALIST Powersoft S.p.A. Via E. Conti, 5 - Scandicci (Fi) 50018 - Italy OFFICE: +39 055 7350230 <http://www.powersoft-audio.com/en/>[cid:PS_553e4174-d089-4113-aa68-7863aa6108ea.png]<http://www.powersoft-audio.com/en/> [cid:FB_c651e92c-f558-4470-9dc8-0cde2dc49cf4.png] <https://www.facebook.com/powersoft> [cid:Teams_6088ac53-fdc7-460a-97b3-533e03f1ad3d.png] <https://teams.microsoft.com/l/chat/0/0?users=leonardo.fibuc...@powersoft.com> [cid:IN_2180daad-e9b1-4c84-9ac3-d130a49ed1c3.png] <https://www.linkedin.com/company/powersoft> <https://www.linkedin.com/company/powersoft> [cid:YT_c74db1a3-a814-4e66-b04f-15ff9bd7940d.png] <https://www.youtube.com/user/powersoftaudio> <https://www.youtube.com/user/powersoftaudio> [cid:IG_b8aafa87-2c84-4406-9c9e-91da1b7684d0.png] <https://www.instagram.com/powersoft.audio/> <https://www.instagram.com/powersoft.audio/> <http://www.powersoft-audio.com/en/>
Track with problem.pcapng
Description: Track with problem.pcapng
Track good.pcapng
Description: Track good.pcapng
/** ****************************************************************************** * @file lwipopts.h * This file is based on \src\include\lwip\opt.h ****************************************************************************** * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. * Copyright 2016-2018 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ #if USE_RTOS /** * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain * critical regions during buffer allocation, deallocation and memory * allocation and deallocation. */ #define SYS_LIGHTWEIGHT_PROT 1 /** * NO_SYS==0: Use RTOS */ #define NO_SYS 0 /** * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) */ #define LWIP_NETCONN 1 /** * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) */ #define LWIP_SOCKET 1 #define LWIP_TIMEVAL_PRIVATE 0 #define SO_REUSE 1 /** * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and * SO_RCVTIMEO processing. */ #define LWIP_SO_RCVTIMEO 1 /** * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and * SO_SNDTIMEO processing. */ #define LWIP_SO_SNDTIMEO 1 #define LWIP_PPP_API 0 #define PPPOS_SUPPORT 0 #define LWIP_HAVE_SLIPIF 1 #else /** * NO_SYS==1: Bare metal lwIP */ #define NO_SYS 1 /** * LWIP_NETCONN==0: Disable Netconn API (require to use api_lib.c) */ #define LWIP_NETCONN 0 /** * LWIP_SOCKET==0: Disable Socket API (require to use sockets.c) */ #define LWIP_SOCKET 0 #endif #define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 1 #define LWIP_MDNS_RESPONDER 1 #define LWIP_NUM_NETIF_CLIENT_DATA 1 /* Maybe can be useful for mDNS to set LWIP_NETIF_EXT_STATUS_CALLBACK to 1 ????? */ #define LWIP_NETIF_EXT_STATUS_CALLBACK 1 /* ---------- Core locking ---------- */ #define LWIP_TCPIP_CORE_LOCKING 1 void sys_lock_tcpip_core(void); #define LOCK_TCPIP_CORE() sys_lock_tcpip_core() void sys_unlock_tcpip_core(void); #define UNLOCK_TCPIP_CORE() sys_unlock_tcpip_core() void sys_check_core_locking(void); #define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking() void sys_mark_tcpip_thread(void); #define LWIP_MARK_TCPIP_THREAD() sys_mark_tcpip_thread() #define LWIP_NETIF_LOOPBACK 0 #define LWIP_NETIF_HOSTNAME 0 /* ---------- Memory options ---------- */ /** * MEM_ALIGNMENT: should be set to the alignment of the CPU * 4 byte alignment -> #define MEM_ALIGNMENT 4 * 2 byte alignment -> #define MEM_ALIGNMENT 2 */ #ifndef MEM_ALIGNMENT #define MEM_ALIGNMENT 4 #endif /** * 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. */ #ifndef MEM_SIZE #define MEM_SIZE (20 * 1024) #endif #include <stdint.h> extern uint8_t ram_heap[MEM_SIZE]; #define LWIP_RAM_HEAP_POINTER ram_heap #include "macros.h" /** Allocates a memory buffer of specified size that is of sufficient size to align * its start address using LWIP_MEM_ALIGN. * You can declare your own version here e.g. to enforce alignment without adding * trailing padding bytes (see LWIP_MEM_ALIGN_BUFFER) or your own section placement * requirements.\n * e.g. if you use gcc and need 32 bit alignment:\n * \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[size] \_\_attribute\_\_((aligned(4)))\n * or more portable:\n * \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u32_t variable_name[(size + sizeof(u32_t) - 1) / * sizeof(u32_t)] */ #define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) \ AT_OCRAM_BSS_SECTION_SYM(u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)], variable_name) /** * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. * Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution * speed (heap alloc can be much slower than pool alloc) and usage from interrupts * (especially if your netif driver allocates PBUF_POOL pbufs for received frames * from interrupt)! * ATTENTION: Currently, this uses the heap for ALL pools (also for private pools, * not only for internal pools defined in memp_std.h)! */ #define MEMP_MEM_MALLOC 0 /** * MEMP_NUM_NETCONN: the number of struct netconns. * (only needed if you use the sequential API, like api_lib.c) */ #define MEMP_NUM_NETCONN 20 #define MEMP_NUM_NETBUF 20 #define MEMP_NUM_TCPIP_MSG_INPKT 20 /* 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. */ #ifndef MEMP_NUM_PBUF #define MEMP_NUM_PBUF 32 #endif /* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One per active UDP "connection". */ #ifndef MEMP_NUM_UDP_PCB #define MEMP_NUM_UDP_PCB 16 #endif /* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. */ #ifndef MEMP_NUM_TCP_PCB #define MEMP_NUM_TCP_PCB 10 #endif /* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. */ #ifndef MEMP_NUM_TCP_PCB_LISTEN #define MEMP_NUM_TCP_PCB_LISTEN 4 #endif /* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. */ #ifndef MEMP_NUM_TCP_SEG #define MEMP_NUM_TCP_SEG 22 #endif /* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. */ #ifndef MEMP_NUM_SYS_TIMEOUT #define MEMP_NUM_SYS_TIMEOUT 10 #endif #define MEMP_NUM_REASSDATA 20 #define MEMP_NUM_FRAG_PBUF 20 /* ---------- Pbuf options ---------- */ /* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ #ifndef PBUF_POOL_SIZE #define PBUF_POOL_SIZE 12 #endif /* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ /* Default value is defined in lwip\src\include\lwip\opt.h as * LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)*/ /* ---------- TCP options ---------- */ #ifndef LWIP_TCP #define LWIP_TCP 1 #endif #ifndef TCP_TTL #define TCP_TTL 255 #endif /* Controls if TCP should queue segments that arrive out of order. Define to 0 if your device is low on memory. */ #ifndef TCP_QUEUE_OOSEQ #define TCP_QUEUE_OOSEQ 0 #endif /* TCP Maximum segment size. */ #ifndef TCP_MSS #define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */ #endif /* TCP sender buffer space (bytes). */ #ifndef TCP_SND_BUF #define TCP_SND_BUF (6 * TCP_MSS) // 2 #endif /* TCP sender buffer space (pbufs). This must be at least = 2 * TCP_SND_BUF/TCP_MSS for things to work. */ #ifndef TCP_SND_QUEUELEN #define TCP_SND_QUEUELEN (3 * TCP_SND_BUF) / TCP_MSS // 6 #endif /* TCP receive window. */ #ifndef TCP_WND #define TCP_WND (2 * TCP_MSS) #endif /* Enable backlog*/ #ifndef TCP_LISTEN_BACKLOG #define TCP_LISTEN_BACKLOG 1 #endif /* ---------- Network Interfaces options ---------- */ /* Support netif api (in netifapi.c). */ #ifndef LWIP_NETIF_API #define LWIP_NETIF_API 1 #endif /* ---------- ICMP options ---------- */ #ifndef LWIP_ICMP #define LWIP_ICMP 1 #endif /* ---------- DHCP options ---------- */ /* Define LWIP_DHCP to 1 if you want DHCP configuration of interfaces. */ #define LWIP_DHCP 1 #define LWIP_AUTOIP 1 #define LWIP_DHCP_AUTOIP_COOP 1 /* how many DHCP attempts before assigning an autoip. If you put 0 it starts trying to assign an autoip immediately. */ #define LWIP_DHCP_AUTOIP_COOP_TRIES 0 /* ---------- DNS options ---------- */ #ifndef LWIP_DNS #define LWIP_DNS 0 #endif /* ---------- IGMP options ---------- */ /* LWIP_IGMP==1: Turn on IGMP module. */ #ifndef LWIP_IGMP #define LWIP_IGMP 1 #endif /* ---------- UDP options ---------- */ #ifndef LWIP_UDP #define LWIP_UDP 1 #endif #ifndef UDP_TTL #define UDP_TTL 255 #endif /* ---------- Statistics options ---------- */ #define LWIP_STATS 1 #define LWIP_STATS_DISPLAY 1 #define MEM_STATS 1 #define MEMP_STATS 1 #define LWIP_ERRNO_STDINCLUDE #define UDP_DEBUG LWIP_DBG_OFF #define TCP_DEBUG LWIP_DBG_OFF #define IP_DEBUG LWIP_DBG_OFF #define IP_REASS_DEBUG LWIP_DBG_OFF #define ICMP_DEBUG LWIP_DBG_OFF #define MEMP_DEBUG LWIP_DBG_OFF #define PBUF_DEBUG LWIP_DBG_OFF #define SOCKETS_DEBUG LWIP_DBG_OFF #define API_MSG_DEBUG LWIP_DBG_OFF #define AUTOIP_DEBUG LWIP_DBG_OFF #define DHCP_DEBUG LWIP_DBG_OFF #define IP_REASS_MAX_PBUFS 24 /* -------------------------------------- ---------- Checksum options ---------- -------------------------------------- */ /* Some MCU allow computing and verifying the IP, UDP, TCP and ICMP checksums by hardware: - To use this feature let the following define uncommented. - To disable it and process by CPU comment the the checksum. */ //#define CHECKSUM_BY_HARDWARE #ifdef CHECKSUM_BY_HARDWARE /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ #define CHECKSUM_GEN_IP 0 /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/ #define CHECKSUM_GEN_UDP 0 /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/ #define CHECKSUM_GEN_TCP 0 /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/ #define CHECKSUM_CHECK_IP 0 /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/ #define CHECKSUM_CHECK_UDP 0 /* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/ #define CHECKSUM_CHECK_TCP 0 #else /* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/ #define CHECKSUM_GEN_IP 1 /* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/ #define CHECKSUM_GEN_UDP 1 /* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/ #define CHECKSUM_GEN_TCP 1 /* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/ #define CHECKSUM_CHECK_IP 1 /* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/ #define CHECKSUM_CHECK_UDP 1 /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/ #define CHECKSUM_CHECK_TCP 1 #endif /** * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. * The stack size value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #ifndef DEFAULT_THREAD_STACKSIZE #define DEFAULT_THREAD_STACKSIZE 3000 #endif /** * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. * The priority value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #ifndef DEFAULT_THREAD_PRIO #define DEFAULT_THREAD_PRIO 3 #endif #define SLIPIF_THREAD_STACKSIZE 2000 #define SLIPIF_THREAD_PRIO DEFAULT_THREAD_PRIO #include <stdbool.h> /** * LWIP_PBUF_CUSTOM_DATA: Store private data on pbufs (e.g. timestamps) * This extends struct pbuf so user can store custom data on every pbuf. */ #define LWIP_PBUF_CUSTOM_DATA \ bool rxTimestamp_valid; \ uint32_t rxTimestamp; \ bool txRequestToTimestamp; #define LWIP_PBUF_INIT_CUSTOM_DATA(p) \ do \ { \ (p)->txRequestToTimestamp = false; \ } while (0) /* ------------------------------------ ---------- Debugging options ---------- ------------------------------------ */ #define LWIP_DEBUG #ifdef LWIP_DEBUG #define U8_F "c" #define S8_F "c" #define X8_F "02x" #define U16_F "u" #define S16_F "d" #define X16_F "x" #define U32_F "lu" #define S32_F "ld" #define X32_F "lx" #define SZT_F "u" #endif #define TCPIP_MBOX_SIZE 32 #define TCPIP_THREAD_STACKSIZE 1024 #define TCPIP_THREAD_PRIO 12 /** * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed * to sys_mbox_new() when the recvmbox is created. */ #define DEFAULT_RAW_RECVMBOX_SIZE 12 /** * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed * to sys_mbox_new() when the recvmbox is created. */ #define DEFAULT_UDP_RECVMBOX_SIZE 20 /** * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed * to sys_mbox_new() when the recvmbox is created. */ #define DEFAULT_TCP_RECVMBOX_SIZE 12 /** * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. * The queue size value itself is platform-dependent, but is passed to * sys_mbox_new() when the acceptmbox is created. */ #define DEFAULT_ACCEPTMBOX_SIZE 12 #if (LWIP_DNS || LWIP_IGMP || LWIP_IPV6) && !defined(LWIP_RAND) /* When using IGMP or IPv6, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value*/ #include "lwip/arch.h" u32_t lwip_rand(void); #define LWIP_RAND() lwip_rand() #endif #endif /* __LWIPOPTS_H__ */ /*****END OF FILE****/
_______________________________________________ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users