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的启发。