2012-06-01 1950 views
4

LwIP的netconn_accept()netconn_recv()函数被调用,如果我们使用的是RTOS,它会阻塞线程和等待,直到超时连接或永远取决于LWIP_SO_RCVTIME0设置。超时时间等于SYS_ARCH_TIMEOUTLWIP + RTOS - 如何避免netconn永远阻塞线程?

SYS_ARCH_TIMEOUT被定义为0xffffffff在核心包含LwIP堆栈的一部分,所以我认为它不会被改变。

实际上,我希望它检查是否有连接,如果不是则继续线程。但是,如果我打电话给netconn_accept(),它只会阻塞线程并永远等待(或很长一段时间)...我不想更改SYS_ARCH_TIMEOUT的定义值,因为我需要不同的超时时间。 。

这样做的好方法是什么?谢谢。

+0

我不知道LWIP的细节,但它有一个非阻塞套接字的概念或“选择”类功能? –

+0

lwIP中的BSD套接字实现实际上使用了OP可能无法承受的额外空间。 RAM的64kb不是一切的大空间。 –

+1

@ViktorLatypov你怎么知道我只有64kb RAM?我认识你吗...? – eepty

回答

5

对于TCP连接(或接受)的轮询通常是一种不好的做法。考虑产生专门用于阻止netconn_accept()调用的新线程。

我明白使用RTOSes的局限性,但是用最小的堆栈空间产生一个辅助线程不应该是一个主要问题。

我相信实施经典Producer-Consumer problem的解决方案并不难。

如果你在谈论FreeRTOS,它拥有所有需要的工具 - 信号量和线程。

3

创建一个新线程来尝试建立连接。只要它没有连接,将线程暂时搁置一段时间,这样RTOS就可以进行上下文切换! (切换到另一个任务)

5

根本不要使用阻塞API。 lwIP堆栈提供了一个本地的,非阻塞的,事件驱动的API,它比阻塞更有效,不需要阻塞RTOS。 YouTube视频显示(在http://youtu.be/MBk5wJ_8jEc)显示了如何将此API用于基于QP状态机框架的实时系统。

1

您可以使用netconn_set_recvtimeout函数将侦听套接字上的超时设置为很小的值,例如1ms。

例如, (错误处理不放过新,绑定,监听简单)

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); 
} 

然后调用接受将延迟最大为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 
}