LWIP + RTOS - how to avoid netconn block the thread forever?
Asked Answered
T

4

7

When the LwIP netconn_accept() or netconn_recv() function is called, if we are using a RTOS, it will block the thread and wait for a connection until timeout or forever, depends on the setting of LWIP_SO_RCVTIME0. The timeout duration is equal to the SYS_ARCH_TIMEOUT.

The SYS_ARCH_TIMEOUT is defined as 0xffffffff in the core include part of the LwIP stack, so I think it is not expected to be changed.

Actually, I want it to check if a connection is made, if not then it continue the thread. However, if I call netconn_accept(), it will just block the thread and wait there forever (or a very long time)...I don't want to jsut change the define value of SYS_ARCH_TIMEOUT because I need different timeout in different situation...

What is the good way to do that? Thanks.

Tutankhamen answered 1/6, 2012 at 10:47 Comment(4)
I don't know the specifics of lwip, but does it have a concept of non-blocking sockets or a select-like function?Countryside
The BSD sockets implementation in lwIP really use extra space which OP might not be able to afford. 64kb of RAM isn't a big space for everything.Camden
@ViktorLatypov How do you know I only have 64kb RAM?? Do I know you...?Tutankhamen
I doubt that, just had enough of FreeRTOS myself :)))Camden
C
9

Polling for TCP connection (or acceptance) is usually a bad practice. Consider spawning a new thread dedicated exclusively to the blocking netconn_accept() call.

I understand the limitations of using RTOSes, but spawning just one helper thread with minimal stack space shouldn't be a major problem.

I believe that implementing a solution to the classical Producer-Consumer problem is not that hard.

If you're talking about the FreeRTOS, it has all the tools needed - semaphores and threads.

Camden answered 1/6, 2012 at 10:52 Comment(0)
F
3

Make a new thread trying to make that connection. Aslong as it is not connected, put the thread in sleep for sometime so the RTOS can make a context switch! (switch to another task)

Femme answered 1/6, 2012 at 11:25 Comment(0)
B
3

Don't use the blocking API at all. The lwIP stack provides a native, non-blocking, event-driven API, which is more efficient than blocking and does not require a blocking RTOS. A YouTube video shows (at http://youtu.be/MBk5wJ_8jEc) shows how this API has been used in a real-time system based on the QP state machine framework.

Bart answered 4/6, 2012 at 1:57 Comment(0)
R
3

You can use the netconn_set_recvtimeout function to set the timeout on the listen socket to something small, eg 1ms.

Eg. (Error handling left off new, bind, listen for simplicity)

struct netconn *conn = netconn_new(NETCONN_TCP);
if (conn)
{
    if (netconn_bind(conn, IP_ADDR_ANY, 1025/*PORT_NUMBER*/) != ERR_OK)
    {
        return;
    }
    if (netconn_listen(conn) != ERR_OK)
    {
        return;
    }
    netconn_set_recvtimeout(conn, 1);
}

Then calls to accept will delay maximum 1ms:

struct netconn *newConn;
err_t result = netconn_accept(conn, &newConn);
if (result == ERR_OK)
{
    // Handle the connected netconn here
}
else if (result == ERR_TIMEOUT)
{
    // No pending connections
}
else
{
    // A problem with the listen socket accepting the connection
}
Raddie answered 4/9, 2015 at 13:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.