LwIP是特別適用於嵌入式設備的小型開源TCP/IP協議棧,對內存資源佔用很小。ESP32 SDK即是移植了LwIP協議棧。首先對在ESP32 SDK上移植LwIP的相關代碼做簡單梳理,方便將來查找問題。
0:LwIP源碼與ESP32 LwIP組件
LwIP源碼下載:git clone https://git.savannah.gnu.org/git/lwip.git/
下載完畢後,路徑下有src文件夾即是LwIP源碼,其中:
apps:基於LwIP raw/callback API編寫的高層網絡應用,如SNTP/HTTP/HTTP服務等。
core:LwIP內核源碼,LwIP運行無需操作系統支持,可以單獨運行。
include:LwIP協議棧頭文件。
netif:與底層網絡接口相關的代碼。
api:LwIP提供兩類API編程接口:一類是LwIP內核提供的raw/callbackAPI,另一類是sequential API/socket API。前者只需要LwIP內核即可工作,但編程複雜;後者對前者進行封裝,編程簡單,但需要引入操作系統級別的郵箱、信號量等機制方可實現。api路徑下即是後者相關的源碼。
ESP32 LwIP組件源碼路徑在ESP32SDK:\esp-idf-v3.0-rc1\components\lwip:
對比兩者區別主要在路徑:
\esp-idf-v3.0-rc1\components\lwip\port
\esp-idf-v3.0-rc1\components\lwip\include\lwip\port
1:ESP32 SDK LwIP版本 2016-02
2:port:該目錄下則是移植LwIP到ESP32的部分,包括:
A:相關配置文件
B:與平臺硬件相關的接口
C:與平臺操作系統相關的接口
1:配置文件
tree/esp-idf-v3.0-rc1/components/lwip/include/lwip/port
├── arch
│ ├── cc.h LwIP數據類型與移植平臺數據類型定義
│ ├── perf.h 用於測試的宏定義,不使用
│ ├── sys_arch.h 操作系統接口層聲明
│ └── vfs_lwip.h ESP32 VFS與LwIP的接口聲明
├── arpa
│ └── inet.h 僅用於導入頭文件
├──lwipopts.h LwIP相關配置
├── netif
│ ├── ethernetif.h 以太網卡驅動接口聲明
│ └── wlanif.h wlan驅動接口聲明
└── netinet
└── in.h 僅用於導入頭文件
2:硬件相關接口
移植LwIP時主要需要編寫的地方是網卡底層驅動,LwIP本身已經做好形式上的接口(LwIP源碼路徑:\lwip\src\netif\ethernet.c),需用戶參照其接口自己實現具體的驅動部分:
\esp-idf-v3.0-rc1\components\lwip\port\netif\ethernetif.c以太網卡接口
\esp-idf-v3.0-rc1\components\lwip\port\netif\wlan.c WIFI接口
以WIFI接口爲例:
wlan發送:wlanif_init:
netif->linkoutput= low_level_output -> esp_wifi_internal_tx
wlan接收:wlanif_input:
從esp_wifi_internal_free_rx_buffer獲取接收的數據包地址
esp_wifi_internal_tx
esp_wifi_internal_free_rx_buffer等部分不開源
3:操作系統相關接口
前面說過LwIP提供兩類API,其中封裝完成編程簡單的API需要操作系統提供相關的信號量郵箱等機制實現,由於各類平臺所用的操作系統不同,因此這些接口也被LwIP提取出來,提供給用戶自己去完成,ESP32移植LwIP操作系統相關的接口路徑在:
\esp-idf-v3.0-rc1\components\lwip\port\freertos\sys_arch.c,對應關係:
接口涵義 |
LwIP接口 |
ESP32+FreeRTOS實現 |
互斥鎖相關 |
sys_mutex_new/ lock/ free等 |
XSemaphoreCreateMutex/ Take/Given等 |
信號量相關 |
sys_sem_new/ sys_arch_sem_wait等 |
基於vSemaphoreCreateBinary實現 |
郵箱相關 |
sys_mbox_new/post sys_arch_mbox_fetch等 |
基於xQueueCreate/ xQueueSendToBack實現 |
線程相關 |
sys_thread_new線程創建 sys_thread_sem_init線程鎖 |
基於xTaskCreate vSemaphoreCreateBinary實現 |
延時/時鐘 |
sys_delay_ms/sys_jiffies |
VTaskDelay/xTaskGetTickCount |
臨界區保護 |
sys_arch_protect/ sys_arch_unprotect |
sys_mutex_lock/sys_mutex_lock 最終即是: XSemaphoreCreateMutex/ Take/Given等 |
4:對LwIP移植在ESP32上移植代碼的簡單梳理,也是對在其它嵌入式平臺移植LwIP的啓發。