1、LwIP簡介
LwIP 全名為 Light weight IP,意思是輕量化的 TCP/IP 協議, 是瑞典計算機科學院(SICS)的 Adam Dunkels 開發的一個小型開源的 TCP/IP 協議棧。 LwIP 的設計初衷是:用少量的資源消耗(RAM)實現一個較為完整的 TCP/IP 協議棧,其中“完整”主要指的是 TCP 協議的完整性, 實現的重點是在保持 TCP 協議主要功能的基礎上減少對 RAM 的占用。此外 LwIP既可以移植到操作系統上運行,也可以在無操作系統的情況下獨立運行。
LwIP有無操作系統的支持都可以運行。LwIP實現的重點是在保持TCP協議主要功能的基礎上減少對RAM 的占用,它只需十幾KB的RAM和40K左右的ROM就可以運行,這使LwIP協議棧適合在低端的嵌入式系統中使用。
lwIP協議棧主要關注的是怎么樣減少內存的使用和代碼的大小,這樣就可以讓lwIP適用於資源有限的小型平台例如嵌入式系統。為了簡化處理過程和內存要求,lwIP對API進行了裁減,可以不需要復制一些數據。
2、LwIP的特性
LwIP 具有主要特性:
(1)支持 ARP 協議(以太網地址解析協議)。
(2)支持 ICMP 協議(控制報文協議),用於網絡的調試與維護。
(3)支持 IGMP 協議(互聯網組管理協議),可以實現多播數據的接收。
(4)支持 UDP 協議(用戶數據報協議)。
(5)支持 TCP 協議(傳輸控制協議),包括阻塞控制、 RTT 估算、快速恢復和快速轉發。
(6)支持 PPP 協議(點對點通信協議) ,支持 PPPoE。
(7)支持 DNS(域名解析)。
(8)支持 DHCP 協議,動態分配 IP 地址。
(9)支持 IP 協議,包括 IPv4、 IPv6 協議,支持 IP 分片與重裝功能,多網絡接口下的數據包轉發。
(10)支持 SNMP 協議(簡單網絡管理協議)。
(11)支持 AUTOIP,自動 IP 地址配置。
(12)提供專門的內部回調接口(Raw API),用於提高應用程序性能。
(13)提供可選擇的 Socket API、 NETCONN API (在多線程情況下使用) 。
LwIP 在嵌入式中使用有以下優點:
(1)資源開銷低,即輕量化。 LwIP 內核有自己的內存管理策略和數據包管理策略, 使得內核處理數據包的效率很高。另外, LwIP 高度可剪裁,一切不需要的功能都可以通過宏編譯選項去掉。 LwIP 的流暢運行需要 40KB 的代碼 ROM 和幾十 KB 的RAM, 這讓它非常適合用在內存資源受限的嵌入式設備中。
(2)支持的協議較為完整。 幾乎支持 TCP/IP 中所有常見的協議,這在嵌入式設備中早已夠用。
(3)實現了一些常見的應用程序: DHCP 客戶端、 DNS 客戶端、 HTTP 服務器、MQTT 客戶端、 TFTP 服務器、 SNTP 客戶端等等。
(4)同時提供了三種編程接口: RAW API、 NETCONN API(注: NETCONN API 即為 Sequential API, 為了統一,下文均采用 NETCONN API) 和 Socket API。 這三種 API 的執行效率、易用性、可移植性以及時空間的開銷各不相同,用戶可以根據實際需要,平衡利弊,選擇合適的 API 進行網絡應用程序的開發。
(5)高度可移植。其源代碼全部用 C 實現,用戶可以很方便地實現跨處理器、跨編譯器的移植。另外,它對內核中會使用到操作系統功能的地方進行了抽象,使用了一套自定義的 API,用戶可以通過自己實現這些 API,從而實現跨操作系統的移植工作。
(6)開源、免費,用戶可以不用承擔任何商業風險地使用它。
(7) 相比於嵌入式領域其它的 TCP/IP 協議棧,比如 uC-TCP/IP、 FreeRTOS-TCP 等,LwIP 的發展歷史要更悠久一些,得到了更多的驗證和測試。 LwIP 被廣泛用在嵌入式網絡設備中, 國內一些物聯網公司推出的物聯網操作系統,其 TCP/IP 核心就是 LwIP;物聯網知名的 WiFi 模塊 ESP8266,其 TCP/IP 固件,使用的就是 LwIP。
LwIP 盡管有如此多的優點,但它畢竟是為嵌入式而生, 所以並沒有很完整地實現TCP/IP 協議棧。相比於 Linux 和 Windows 系統自帶的 TCP/IP 協議棧, LwIP 的功能不算完整和強大。 但對於大多數物聯網領域的網絡應用程序, LwIP 已經足夠了。
3、LwIP模式
LwIP提供三種API:
(1)RAW API
RAW API把協議棧和應用程序放到一個進程里邊,該接口基於函數回調技術,使用該接口的應用程序可以不用進行連續操作。不過,這會使應用程序編寫難度加大且代 碼不易被理解。為了接收數據,應用程序會向協議棧注冊一個回調函數。該回調函數與特定的連接相關聯,當該關聯的連接到達一個信息包,該回調函數就會被協議 棧調用。這既有優點也有缺點。優點是既然應用程序和TCP/IP協議棧駐留在同一個進程中,那么發送和接收數據就不再產生進程切換。主要缺點是應用程序不 能使自己陷入長期的連續運算中,這樣會導致通訊性能下降,原因是TCP/IP處理與連續運算是不能並行發生的。這個缺點可以通過把應用程序分為兩部分來克 服,一部分處理通訊,一部分處理運算。
(2)LwIP API
LwIP API把接收與處理放在一個線程里面。這樣只要處理流程稍微被延遲,接收就會被阻塞,直接造成頻繁丟包、響應不及時等嚴重問題。因此,接收與協議處理必須 分開。LwIP的作者顯然已經考慮到了這一點,他為我們提供了 tcpip_input() 函數來處理這個問題, 雖然他並沒有在 rawapi 一文中說明。 講到這里,讀者應該知道tcpip_input()函數投遞的消息從哪里來的答案了吧,沒錯,它們來自於由底層網絡驅動組成的接收線程。我們在編寫網絡驅動時, 其接收部分以任務的形式創建。 數據包到達后, 去掉以太網包頭得到IP包, 然后直接調用tcpip_input()函數將其 投遞到mbox郵箱。投遞結束,接收任務繼續下一個數據包的接收,而被投遞得IP包將由TCPIP線程繼續處理。這樣,即使某個IP包的處理時間過長也不 會造成頻繁丟包現象的發生。這就是lwip API。
(3)BSD API
BSD API提供了基於open-read-write-close模型的UNIX標准API,它的最大特點是使應用程序移植到其它系統時比較容易,但用在嵌入式系統中效率比較低,占用資源多。這對於我們的嵌入式應用有時是不能容忍的。