lwip-users
[Top][All Lists]
Advanced

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

Re: [lwip-users] Retransmit too quick?


From: Xun Chen
Subject: Re: [lwip-users] Retransmit too quick?
Date: Mon, 06 Jul 2015 15:29:19 -0400
User-agent: Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Thunderbird/31.7.0

Hi, Sergio,

Thank you for your time!

I am not calling any raw api from interrupts and I don't use RTOS.

I include the pseudo codes below. (Note: In my codes, only one TCP connection 
is allowed)

A) The following codes works, but I still get the (too quick) retransmit 
problem after long run, making it hard to figure out

B) Another frustrating observation from my project
1) If I call sys_check_timeouts() without any delay, the throughput rate is 
very low
2) If I call sys_check_timeouts() with 1ms delay right after it, the throughput 
rate is high
3) If I call sys_check_timeouts() every 250ms plus the 1ms delay, the 
throughput rate is the highest

Could you give me some pointer on where to look to solve the retransmit problem 
and maybe some suggestion on how I should use raw APIs? I used FreeRTOS and 
higher level lwip APIs several years ago and never had any issue like this.

Thanks a lot!

Chen

---------------------------
main()
{
...
gConnection=0;
...
lwIPInit();
..
tcp_pcb = tcp_new();
tcp_bind();
tcp_pcb = tcp_listen(tcp_pcb);
tcp_accept(tcp_pcb, echo_accept);
..

while(1){
        ...
        if (gConnection){
                if (tcp_sndbuf(active_tcp_pcb)>0){
                        if (tcp_write(active_tcp_pcb, ..., 
TCP_WRITE_FLAG_COPY)==ERR_OK){
                                tcp_output(active_tcp_pcb));
                        }
                }
        }
        if (250msElapsed()) //With this and Delay1ms, the performance is the 
best
        sys_check_timeouts();
        Delay1ms();//Without this and(250msElapsed()), the performance is 
horrible
}

err_t echo_accept(void *arg, struct tcp_pcb *pcb, err_t err){

        if (gConnection==0){
                active_tcp_pcb=pcb;
                gConnection=1;
                ...
                tcp_recv(pcb, echo_recv);
                tcp_err(pcb, err_handler);
                tcp_nagle_enable(pcb);
                return ERR_OK;
        }
        return ERR_RST; //Allow only one connection
}

err_t echo_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err){

      if (err == ERR_OK && p != NULL) {
                .... //Process the incoming data
                tcp_recved(pcb, p->tot_len);
      }
      pbuf_free(p);

      if (err == ERR_OK && p == NULL) {
            close_conn(pcb);
      }
      return ERR_OK;
}


void err_handler(void * arg, err_t err){
        close_conn(active_tcp_pcb);
}

void close_conn(struct tcp_pcb *pcb){
        ....            
      tcp_close(pcb);
      gConnection=0;
}

---------------------------




If you are using the raw api and no RTOS, then your port should (must)
be calling the lwIP timers function and you don't have to do anything
with timers
(that is what I meant by "a broken timer implementation").
Your main should be something like

        while(1){
                sys_check_timeouts();
                ...
        }

and you have to make sure it loops often (as it should).

You call the raw api functions only from the main loop, no calls on
interrupts. Do you ?






reply via email to

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