lwip-users
[Top][All Lists]
Advanced

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

RE: [lwip-users] sys_arch.c timeout of zero problem


From: David Shmelzer
Subject: RE: [lwip-users] sys_arch.c timeout of zero problem
Date: Wed, 12 Aug 2009 14:34:14 -0400

Simon,
Thanks for the informative and prompt reply.
I'm using lwIP 1.3.0.
I converted the timeout value in sys_arch_mbox_fetch() because I could
not see anywhere else that the lwIP timeout values which are in ms were
being converted to ticks required by the FreeRTOS xQueueReceive(). It
turns out, as I just discovered, this was an implementation error on
their part of the STR9 example which I am using. I checked the sys_arc.c
file in a more recent FreeRTOS lwIP example (lwIP_MCF5235_GCC) and they
include a MS_TO_TICKS macro. I've included the function below. They also
included a TICKS_TO_MS macro for converting back to ms for returning the
'timespent'. I copied this implentation to my code and it still fails.
The tick period is 8 ms. Will this implementation also fail because of
what you mentioned that a timeout value in ms that converts to 0 will
cause frequent timer calls?
-Dave



sys_arch_mbox_fetch( sys_mbox_t mbox, void **msg, u32_t timeout )
{
    void           *ret_msg;
    portBASE_TYPE   xStatus;
    portTickType    xTicksStart, xTicksEnd, xTicksElapsed;
    u32_t           timespent;

    LWIP_ASSERT( "sys_arch_mbox_fetch: mbox != SYS_MBOX_NULL", mbox !=
SYS_MBOX_NULL );
    xTicksStart = xTaskGetTickCount(  );
    if( timeout == 0 )
    {
        do
        {
            xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( 100 )
);
        }
        while( xStatus != pdTRUE );
    }
    else
    {
        xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( timeout )
);
    }

    if( xStatus == pdTRUE )
    {
        if( msg )
        {
            *msg = ret_msg;
        }
        xTicksEnd = xTaskGetTickCount(  );
        xTicksElapsed = xTicksEnd - xTicksStart;
        timespent = TICKS_TO_MS( xTicksElapsed );
    }
    else
    {
        if( msg )
        {
            *msg = NULL;
        }
        timespent = SYS_ARCH_TIMEOUT;
    }
    return timespent;
}



 

-----Original Message-----
From: address@hidden
[mailto:address@hidden On Behalf Of
address@hidden
Sent: Tuesday, August 11, 2009 1:30 PM
To: Mailing list for lwIP users
Subject: Re: [lwip-users] sys_arch.c timeout of zero problem

lwIP should not have any problems with a timeout of zero. However,
converting timeout valus inside the function sys_arch_mbox_fetch() (like
you did) is not supported and will confuse the stack. This is because of
the way the stack handles timers: it keeps the time until the next timer
expires (in miliseconds) and substracts the time sys_arch_mbox_fetch()
needed from that time. When zero, the timeout gets called.

There are two possibilities here:
a) the function returns a valid mbox message, in this case it shall
return the time (in miliseconds) it needed until the message was
received, zero if received immediately or
b) the function returns SYS_ARCH_TIMEOUT if timeout is !=0 and no
message has been received in that time; in this case the time needed is
supposed to be the value of timeout passed to the function.

Now you can easily see that returning SYS_ARCH_TIMEOUT after 0
miliseconds instead of 10 miliseconds will lead to problems as the stack
thinks 10 ms have passed but in reality, 0 ms have passed. Because of
that, timers get called much too frequently and this may lead to
detecting connection errors where there aren't any.

If you are using lwIP 1.3.0 or newer (CVS), to achieve what you want,
have a look into the netconn_recv() function: when you have
LWIP_SO_RCVTIMEO defined to 1, sys_arch_mbox_fetch() gets called with a
timeout defined in the netconn (conn->recv_timeout), an int which you
can set to whatever you want, e.g. set it to -1 and let
sys_arch_mbox_fetch() return immediately if timeout is -1.

If you are using lwIP 1.2.0 or before, I don't know a decent solution.

BTW: The above timeout implementation is not ideal and subject to change
in lwIP 1.4.0. With the intended solution (having a function like
get_time()), your approach would have worked ;-)

Simon


David Shmelzer wrote:
> My application requires that netconn_recv() be non-blocking and to 
> return immediately of there is no message waiting.
> So I modified sys_arch.c to convert small timeout values to zero for 
> the queue wait.
> But I run into problems if the xQueueReceive timeout is 0. The TCP 
> connection closes after ~5 netconn_recv calls. Everything works fine 
> if the xQueueReceive blocks for at least 1 tick.
> Does the lwIP architecture REQUIRE that netconn_recv allow the lwIP 
> thread to run?
> Is there a reason that it was designed such that a timeout of 0 means 
> wait forever instead of peek?
>
>
> Here's my modification to sys_arch.c:
>
> u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) 
> { ...
>       if ( timeout != 0 )
>       {
>             timeout >>= 2; <<<<<---- added this line which converts 
> timeout in ms to ticks
>               if ( pdTRUE == xQueueReceive( mbox, &(*msg), timeout ) )
...
>
>
>
> Thanks
> -Dave
>
>
> _______________________________________________
> lwip-users mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/lwip-users
>
>   



_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users




reply via email to

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