lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] long time tcp receive lwip packets lost


From: Erkan Ersoy
Subject: Re: [lwip-users] long time tcp receive lwip packets lost
Date: Sun, 18 Sep 2016 15:53:18 +0000 (UTC)


Thanks Noam ;

My question was about tcp to serial; code is like below:

if(isConnected == 1){
if(FD_ISSET(clientSocket, &readset)){
 readCount = lwip_read(clientSocket, &buffer, 200);
 if(readCount <= 0){
 printf("close connection\n");
 lwip_close(clientSocket);
 isConnected = -1;
 maxSocket--;
 continue;
 }

 //printf("rc: %u\n",readCount);
 buffer[readCount] = 0;
 ptr = buffer;
 while(*ptr != 0){
putcUSART1(*ptr);
ptr++;
 }


 //printf(buffer);

}



 

On Sunday, September 18, 2016 6:14 PM, Erkan Ersoy <address@hidden> wrote:


yes second part of mail was about uart-> tcp. Still I am not using buffer but lwip packs and sends it for me
my mss setting is 

#define TCP_MSS                 700

I am using socket API (I needed  simultaneous sending and receiving but there is not enough documentation about non-blocking netconn)

My current confusion is about tcp->uart:
the bufferless configuration works fine at first  but after a couple of hours It doesn't. It receives data as 80 byte small chunks (whole data is 2096 bytes small chunks are random parts in them) and the data piles in somewhere in lwip. after I stop sending data, I see it continues send data through uart then it stops. So i think it emptied its buffer but if I begin to send again behaviour is the same; until I restart device. And stats show no memory is overloaded. 

if I add buffer the problem may disappear for couple of hours up time but I think it will pile up data slower and become a problem in several days or something. 




On Sunday, September 18, 2016 5:11 PM, Noam Weissman <address@hidden> wrote:


Hi,
 
When you wrote “if I receive one character i will immediately wait for more after 50 ms it quits waiting”
 
Did you mean when TCP part gets a byte from UART ?
 
If this is what you do than its OK… You are working with a micro with limited RAM. If you define large MSS (1500 bytes)
Unless I am mistaken every time you allocate a buffer it will allocate a fixed size MSS buffer. So for every chunk you a
Allocate a large buffer. You are limited by the number of buffers and if you send lots of small chunks TCP may get to a
Point you will be out of buffers.
 
Also do you use netcon or Socket  API ?
 
If you use netcon it is not thread safe. That means that when you send data from UART you must either protect the
Code by critical section:
      taskENTER_CRITICAL();
      {
        AvailableSpace = tcp_sndbuf(ts->pcb);
      }
      taskEXIT_CRITICAL();
 
OR put the data in a buffer and init a sys_timeout call and let the TCP read the data and send it from within the TCP stack
Context.
 
If you do not do one of the above (In RAW or netcon API) you may get memory leaks or strange handling. It seems to work
But after some time it starts to get slower and may stop… I have been there.
 
BR,
Noam.
 
From: Erkan Ersoy [mailto:address@hidden
Sent: Sunday, September 18, 2016 4:15 PM
To: Noam Weissman
Subject: Re: [lwip-users] long time tcp receive lwip packets lost
 
Thanks Noam ;

My question was about tcp to serial code is like below:
 
if(isConnected == 1){
if(FD_ISSET(clientSocket, &readset)){
readCount = lwip_read(clientSocket, &buffer, 200);
if(readCount <= 0){
printf("close connection\n");
lwip_close(clientSocket);
isConnected = -1;
maxSocket--;
continue;
}
 
//printf("rc: %u\n",readCount);
buffer[readCount] = 0;
ptr = buffer;
while(*ptr != 0){
putcUSART1(*ptr);
ptr++;
}
 
 
//printf(buffer);
 
}
 
I will add buffer to this side (DMA based); but in spite of  there is plenty time to send data to serial port, there is a memory problem somewhere. And  I think even I add buffer  it will become problem after a long up time. It feels like there is a memory leak but I can't see in stats.
 
About serial buffering; if I feed data to tcp socket fast enough lwip buffers it for me. So my code is like below (I checked with wireshark and it doesn't send one character in a TCP packet.)
 
if(FD_ISSET(clientSocket, &writeset)){
if(xQueueReceive(rs232QueueHandle,&serialData,0)){
lwip_send(clientSocket,&serialData, 1, NULL);
while(xQueueReceive(rs232QueueHandle,&serialData,50)){
//printf("gelen: %c\n",serialData);
//lwip_write(socket, &serialData, 1);
lwip_send(clientSocket,&serialData, 1, NULL);
}
 
}
 
 if I receive one character i will immediately wait for more after 50 ms it quits waiting. that doesn't send one char per packet. But if you say it isn't a good practice I should change it too
 
On Sunday, September 18, 2016 3:45 PM, Noam Weissman <address@hidden> wrote:
 
Hi,
 
1.       You must add buffering
2.       RS232 is character based but TCP is packet based.
 
As a result of the different data handling if you do not buffer data it means that for every byte you send from
RS232 you send a TCP packet that has one data byte. That means you have a huge overhead on every byte.
This is very un-efficient and causes the system to get very slow.
 
I have implemented a Bridge, used a 255 byte buffer and set two parameters: size and time.
 
Size: If you reach a predefined number of bytes you send them in one TCP packet.
Time: If you do not get any new data into the TCP buffer after a predefined time you send what you have.
 
This way you collect data from UART and send it in chunks/packets.
 
For example you define 100 bytes as threshold or 30ms as time threshold. Every byte added from UART
To the send buffer is counted. Once the counter reaches 100 or if no new byte is added after 30ms the
TCP buffer is sent and parameters are cleared.
 
I also suggest using a small MSS size (I use 536 bytes).
 
BR,
Noam.
 
From: lwip-users [mailto:address@hidden] On Behalf Of Erkan Ersoy
Sent: Saturday, September 17, 2016 1:42 PM
To: Mailing List for LwIP Users
Subject: [lwip-users] long time tcp receive lwip packets lost
 
Hello 
I am making  a serial tcp bridge device.  it works in server mode  I have freeRTOS 9, lwip 1.4.1 and STM32F107 device
 
I wrote the bridging part and for testing purposes I didn't implement buffer to TCP to serial. So Some while receiving data some data piles up in somewhere in tcp thread (I think).
I wrote a python script that sends 2096 characters every second (some lorem ipsum text). serial speed is 115200. So there is enough time to send data and free memory. 
But after couple of hours (it is random. sometimes 2 hours sometimes 4 and yesterday it was 12 hours) device cant receive whole data somewhat it is 80 byte parts.and it piles up in tcp part. And after I stop my script I continue to get data from my serial window a few seconds. After memory  is empty if I start my script again still same problem. 
I enabled stats to see if I am getting out of memory but it looks fine. I couldn't find where my problem is. 
 
There is a web server and an udp server running in device (I didnt send request both server while testing)
I am using socket api 
 
my stats before running test (it sends stat to seperate uart every 10 seconds)
 
accept_function: newpcb->state: ESTABLISHED
socket Connected
 
ETHARP
        xmit: 5
        recv: 43
        fw: 0
        drop: 0
        chkerr: 0
        lenerr: 0
        memerr: 0
        rterr: 0
        proterr: 0
        opterr: 0
        err: 0
        cachehit: 32
 
IP
        xmit: 36
        recv: 53
        fw: 0
        drop: 0
        chkerr: 0
        lenerr: 0
        memerr: 0
        rterr: 0
        proterr: 0
        opterr: 0
        err: 0
        cachehit: 0
 
TCP
        xmit: 2
        recv: 35
        fw: 0
        drop: 0
        chkerr: 0
        lenerr: 0
        memerr: 0
        rterr: 0
        proterr: 0
        opterr: 0
        err: 0
        cachehit: 0
 
MEM HEAP
        avail: 10240
        used: 68
        max: 456
        err: 0
 
MEM UDP_PCB
        avail: 6
        used: 2
        max: 3
        err: 0
 
MEM TCP_PCB
        avail: 20
        used: 1
        max: 1
        err: 0
 
MEM TCP_PCB_LISTEN
        avail: 5
        used: 2
        max: 2
        err: 0
 
MEM TCP_SEG
        avail: 12
        used: 0
        max: 1
        err: 0
 
MEM NETBUF
        avail: 8
        used: 0
        max: 0
        err: 0
 
MEM NETCONN
        avail: 16
        used: 4
        max: 4
        err: 0
 
MEM TCPIP_MSG_API
        avail: 8
        used: 0
        max: 0
        err: 0
 
MEM TCPIP_MSG_INPKT
        avail: 8
        used: 0
        max: 3
        err: 0
 
MEM SYS_TIMEOUT
        avail: 20
        used: 6
        max: 6
        err: 0
 
MEM NETDB
        avail: 1
        used: 0
        max: 0
        err: 0
 
MEM PBUF_REF/ROM
        avail: 25
        used: 0
        max: 0
        err: 0
 
MEM PBUF_POOL
        avail: 12
        used: 0
        max: 5
        err: 0
 
SYS
        sem.used:  4
        sem.max:   5
        sem.err:   0
        mutex.used: 1
        mutex.max:  1
        mutex.err:  0
        mbox.used:  5
        mbox.max:   5
        mbox.err:   0
 
 
 
 
And after the problem (Nothing seems suspicious except cachehit I could't figure out what it is)
 
 
ETHARP
        xmit: 21
        recv: 2811
        fw: 0
        drop: 9
        chkerr: 0
        lenerr: 0
        memerr: 0
        rterr: 0
        proterr: 9
        opterr: 0
        err: 0
        cachehit: 41446
 
IP
        xmit: 41449
        recv: 37649
        fw: 0
        drop: 0
        chkerr: 0
        lenerr: 0
        memerr: 0
        rterr: 0
        proterr: 0
        opterr: 0
        err: 0
        cachehit: 0
 
TCP
        xmit: 1
        recv: 36784
        fw: 0
        drop: 0
        chkerr: 0
        lenerr: 0
        memerr: 0
        rterr: 0
        proterr: 0
        opterr: 0
        err: 0
        cachehit: 0
 
MEM HEAP
        avail: 10240
        used: 68
        max: 456
        err: 0
 
MEM UDP_PCB
        avail: 6
        used: 2
        max: 3
        err: 0
 
MEM TCP_PCB
        avail: 20
        used: 1
        max: 1
        err: 0
 
MEM TCP_PCB_LISTEN
        avail: 5
        used: 2
        max: 2
        err: 0
 
MEM TCP_SEG
        avail: 12
        used: 0
        max: 1
        err: 0
 
MEM NETBUF
        avail: 8
        used: 0
        max: 0
        err: 0
 
MEM NETCONN
        avail: 16
        used: 4
        max: 4
        err: 0
 
MEM TCPIP_MSG_API
        avail: 8
        used: 0
        max: 0
        err: 0
 
MEM TCPIP_MSG_INPKT
        avail: 8
        used: 0
        max: 3
        err: 0
 
MEM SYS_TIMEOUT
        avail: 20
        used: 6
        max: 6
        err: 0
 
MEM NETDB
        avail: 1
        used: 0
        max: 0
        err: 0
 
MEM PBUF_REF/ROM
        avail: 25
        used: 0
        max: 0
        err: 0
 
MEM PBUF_POOL
        avail: 12
        used: 0
        max: 6
        err: 0
 
SYS
        sem.used:  4
        sem.max:   5
        sem.err:   0
        mutex.used: 1
        mutex.max:  1
        mutex.err:  0
        mbox.used:  5
        mbox.max:   5
        mbox.err:   0
 
 
 
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]