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/>



Attachment: Track with problem.pcapng
Description: Track with problem.pcapng

Attachment: 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

Reply via email to