LWIP + RTOS - 如何避免netconn永远阻塞线程?

时间:2012-06-01 10:47:53

标签: c network-programming embedded rtos lwip

当调用 LwIP netconn_accept()netconn_recv()函数时,如果我们使用RTOS,它将阻塞线程并等待连接,直到超时或永远,取决于LWIP_SO_RCVTIME0的设置。超时持续时间等于SYS_ARCH_TIMEOUT

SYS_ARCH_TIMEOUT在LwIP堆栈的核心包含部分中定义为 0xffffffff ,因此我认为预计不会更改。

实际上,我希望它检查是否建立了连接,如果没有,则继续该线程。但是,如果我调用netconn_accept(),它将阻止线程并在那里永远等待(或很长时间)......我不想jsut更改SYS_ARCH_TIMEOUT的定义值,因为我在不同的情况下需要不同的超时...

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

4 个答案:

答案 0 :(得分:6)

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

我理解使用RTOS的局限性,但只产生一个具有最小堆栈空间的辅助线程不应该是一个主要问题。

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

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

答案 1 :(得分:5)

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

答案 2 :(得分:3)

创建一个新线程尝试建立该连接。只要它没有连接,就让线程进入休眠状态一段时间,这样RTOS就可以进行上下文切换! (切换到另一个任务)

答案 3 :(得分:1)

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

EG。 (错误处理留下新的,绑定,听取简单)

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
}