前言
本系列筆記主要記錄學習LWIP時的簡單筆記。
方便以后用到可以快速學習了解。
李柱明博客:https://www.cnblogs.com/lizhuming/p/15487034.html
1.1 優缺點
LwIP 具有主要特性:
- 支持 ARP 協議(以太網地址解析協議)。
- 支持 ICMP 協議(控制報文協議),用於網絡的調試與維護。
- 支持 IGMP 協議(互聯網組管理協議),可以實現多播數據的接收。
- 支持 UDP 協議(用戶數據報協議)。
- 支持 TCP 協議(傳輸控制協議),包括阻塞控制、RTT 估算、快速恢復和快速轉發。
- 支持 PPP 協議(點對點通信協議),支持 PPPoE。
- 支持 DNS(域名解析)。
- 支持 DHCP 協議,動態分配 IP 地址。
- 支持 IP 協議,包括 IPv4、IPv6 協議,支持 IP 分片與重裝功能,多網絡接口下的數據包轉發。
- 支持 SNMP 協議(簡單網絡管理協議)。
- 支持 AUTOIP,自動 IP 地址配置。
- 提供專門的內部回調接口(Raw API),用於提高應用程序性能。
- 提供可選擇的 Socket API、NETCONN API (在多線程情況下使用) 。
LwIP 在嵌入式中使用有以下優點:
- 資源開銷低,即輕量化。LwIP 內核有自己的內存管理策略和數據包管理策略, 使得內核處理數據包的效率很高。另外,LwIP 高度可剪裁,一切不需要的功能都可以通過宏編譯選項去掉。 LwIP 的流暢運行需要 40KB 的代碼 ROM 和幾十 KB 的 RAM,這讓它非常適合用在內存資源受限的嵌入式設備中。
- 支持的協議較為完整。幾乎支持 TCP/IP 中所有常見的協議,這在嵌入式設備中早已夠用。
- 實現了一些常見的應用程序:DHCP 客戶端、DNS 客戶端、HTTP 服務器、MQTT 客戶端、TFTP 服務器、SNTP 客戶端等等。
- 同時提供了三種編程接口:RAW API、NETCONN API(注:NETCONN API 即為 Sequential API)和 Socket API。這三種 API 的執行效率、易用性、可移植性以及時空間的開銷各不相同,用戶可以根據實際需要,平衡利弊,選擇合適的 API 進行網絡應用程序的開發。
- 高度可移植。其源代碼全部用 C 實現,用戶可以很方便地實現跨處理器、跨編譯器的移植。 另外,它對內核中會使用到操作系統功能的地方進行了抽象,使用了一套自定義的 API, 用戶可以通過自己實現這些 API,從而實現跨操作系統的移植工作。
- 開源、免費,用戶可以不用承擔任何商業風險地使用它。
- 相比於嵌入式領域其它的 TCP/IP 協議棧,比如 uC-TCP/IP、FreeRTOS-TCP 等, LwIP 的發展歷史要更悠久一些,得到了更多的驗證和測試。LwIP 被廣泛用在嵌入式網絡設備中, 國內一些物聯網公司推出的物聯網操作系統,其 TCP/IP 核心就是 LwIP;物聯網知名的 WiFi 模塊 ESP8266,其 TCP/IP 固件,使用的就是 LwIP。
缺點:
- 相比於 Linux 和 Windows 系統自帶的 TCP/IP 協議棧,LwIP 的功能不算完整和強大。
1.2 文件說明
1.2.1 獲取 lwip 源碼文件
LwIP 的項目主頁:http://savannah.nongnu.org/projects/lwip/
關注其:project homepage 和 download area 這兩個點即可:
- project homepage:LwIP 的使用注意、 數據的拷貝、系統初始化流程、多線程中要注意的問題、優化方法、內核模塊的分類介紹、 內核數據結構、內核重要全局變量、內核源碼文件等。
- download area:下載頁面。推薦:http://download-mirror.savannah.gnu.org/releases/lwip/
說明:contrib 包里面裝的是移植和應用 LwIP 的一些 demo。
1.2.2 lwip 文件夾說明
1.2.2.1 總目錄
下載兩個包:lwip-2.1.2.zip(源碼包)和 contrib-2.1.0.zip(contrib 包)
1.2.2.2 lwip 包
- doc 是一些應用文檔和移植 LwIP 的指南。(有點混亂,不建議參考)
- src 是 LwIP 源碼文件。
- test 是測試 LwIP 內核性能的源碼,將它們和 LwIP 源碼加入到工程中一起編譯,調用它們提供的函數,可以獲得許多與 LwIP 內核性能有關的指標。
- CHANGELOG 版本升級記錄。
- COPYING LwIP 這個開源軟件的 license。
- FILES 介紹當前目錄下的目錄信息。
- README LwIP 的一個簡單的介紹。
- UPGRADING 記錄了 LwIP 每個大版本的更新,會對用戶使用和移植 LwIP 造成的影響。
1.2.2.3 lwip\src 內核源碼
- api 文件夾里面裝的是 NETCONN API 和 Socket API 相關的源文件,只有在操作系統的環境中,才能被編譯。
- apps 文件夾里面裝的是應用程序的源文件,包括常見的應用程序,如 httpd、mqtt、tftp、sntp、snmp 等。
- core 文件夾里面是 LwIP 的內核源文件。
- include 文件夾里面是 LwIP 所有模塊對應的頭文件。
- netif 文件夾里面是與網卡移植有關的文件,這些文件為我們移植網卡提供了模板,我們可以直接使用。
LwIP 內核是由一系列模塊組合而成的,這些模塊包括:
- TCP/IP 協議棧的各種協議
- 內存管理模塊;
- 數據包管理模塊;
- 網卡管理模塊;
- 網卡接口模塊;
- 基礎功能類模塊;
- API 模塊。
每個模塊是由相關的幾個源文件和頭文件組成的,通過頭文件對外聲明一些函數、宏、數據類型,使得其它模塊可以方便地調用此模塊的功能。而構成每個模塊的頭文件都被組織在了 include 目錄中,而源文件則根據類型被分散地組織在 api、apps、core、netif 目錄中。
部分文件說明:
-
def.c 文件定義了一些基礎類函數,比如主機序和網絡序的轉換、字符串的查找和比較、整數轉換成字符串等,這些函數會被 LwIP 內核的很多模塊所調用。所以會常看到
#include “def.h”
。 -
init.c 文件對 LwIP 的用戶宏配置進行了檢查,會將配置錯誤和不合理的地方,通過編譯器的 #error & #warning 功能表示出來。另外,init.c 定義了
lwip_init();
初始化函數,這個函數會依次對 LwIP 的各個模塊進行初始化。 -
mem.c 文件實現了動態內存池管理機制,各模塊可以靈活地申請和釋放內存。
-
memp.c 文件實現了靜態內存堆管理機制,各模塊可以快速地申請和釋放內存。
-
netif.c 文件實現了網卡的操作,比如注冊/刪除網卡、使能/禁能網卡、設置網卡 IP 地址等等。netif.c 與 include 目錄中的 netif.h 文件共同構成了 LwIP 的 netif 模塊。
-
pbuf.c 文件實現了 LwIP 對網絡數據包的各種操作。網絡數據包在 LwIP 內核中以 pbuf 結構體的形式存在,這提高了 LwIP 內核對數據包處理效率,以及提高了數據包在各層之間遞交的效率。pbuf 結構體也是我們使用 RAW/Callback API 進行網絡應用程序開發的關鍵。
-
raw.c 文件實現了一個傳輸層協議的框架,我們可以在它的基礎上修改和添加代碼,實現自定義的傳輸層協議,與 UDP/TCP 一樣,它可以與 IP 層直接進行交互。這類似 RAW Socket。在實際的應用中,我們常用 UDP 和 TCP 作為傳輸層協議。但有時,底層網絡開發人員會嫌 UDP 的可靠性太差,或者 TCP 雖然可靠性強,但是很耗費時間和內存,他們需要根據實際需求,平衡利弊,定義自己的傳輸層協議。LwIP 的 raw 模塊可以滿足這個需求。
-
stat.c 文件實現了 LwIP 內核的統計功能,使用戶可以實時地查看 LwIP 內核對網絡數據包的處理情況。
-
timeouts.c 定義了 LwIP 內核的超時處理機制。LwIP 內核中多個模塊的實現需要借助超時處理機制,包括 ARP 表項的時間統計、IP 分片報文的重裝、TCP 的各種定時器、實現各種應用層協議需要的超時處理。
1.2.2.4 lwip 官方說明文檔
LwIP 官方說明文檔:http://www.nongnu.org/lwip/2_1_x/index.html
陷阱章節-Common pitfalls:
- 里面提到有無操作系統相關注意點:Mainloop Mode(主函數輪詢模式)與 OS Mode(操作系統模式)。
1.2.3 contrib 文件夾說明
就是 demo 文件夾。后面開發可參考。
資料
參考: