2012-06-01 1953 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 
}