17.LWIP学习

好久没更新了,最近花了点时间研究了下LWIP,看着很复杂,实际也还好。编程

LWIP学习推荐看野火的资料,若是加freertos操做系统的话直接利用cubemx生成便可,省心省力。api

先开个头,后面有时间再编辑详细介绍。服务器

1.简介网络

LWIP是轻量化的 TCP/IP协议,包括无操做系统运行(RAW)和有操做系统运行。数据结构

官方源码下载地址:http://download-mirror.savannah.gnu.org/releases/lwip/socket

LWIP有三种编程接口:tcp

RAW/CALLBACK API: 内核回调型的API,利用回调函数的机制实现数据的传递,主要用于无操做系统运行环境(也支持操做系统)。函数

NETCONN API:基于操做系统的IPC(信号量和邮箱)机制。用于操做系统运行环境,此时LWIP内核被时限为一个独立的线程(tcpip_thread),用户操做的数据结构是netbuf。学习

SOCKET API: 套接字,即socket网络编程,一样基于netconn api实现。操作系统

2.网卡管理函数

网络接口经过netif结构体来管理网络,即netif是LWIP抽象出来的网卡,netif结构体包括链表指针,IP,网关,链接状态等。配置IP和网关等以后,使用函数

netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) 来添加网卡,其中传递进来的回调函数netif_init_fn init来实现网卡真正的初始化。

与netif相关的底层函数:

static void low_level_init(struct netif *netif)    网卡初始化函数

static err_t low_level_output(struct netif *netif, struct pbuf *p)   网卡的发送函数,将类型为pbuf的数据包发送出去

static struct pbuf * low_level_input(struct netif *netif)  网卡的数据接收函数

err_t ethernetif_init(struct netif *netif) :上层网卡的管理函数,调用low_level_init

void ethernetif_input(struct netif *netif):上层网卡的输入函数,调用low_level_input

3.LWIP内存管理

 

 

4.无操做系统RAW编程

所以网卡配置流程(以LAN8720A为例):

网卡初配置(IP,网关等)——添加网卡,调用netif_add函数——调用ethernetif_init()——调用low_level_init ()进行本质上的网卡初始化——调用HAL_ETH_Init()——调用HAL_ETH_MspInit()进行管脚配置。

数据回传处理流程:

while死循环中调用 MX_LWIP_Process( ), 而该函数实际调用ethernetif_input(),本质上调用low_level_input, 即不断轮询ETH外设所接收到的数据。

TCP服务器端流程:

tcp_server_init() 进行tcp控制块的建立,并监听端口,同时绑定接收回调函数  tcp_server_accept() 和tcp_server_recv()进行数据的回传。

所以须要配置的文件有 lwip.c, tcpechoserver.c

 

5.如何实现网线的热插拔

很简单,另外开辟一个低优先级的任务进行网线插拔状态的轮询。当检测到网线硬件链接时,初始化ETH的相关DMA配置,而后挂起任务便可。参考以下:

https://download.csdn.net/download/weixin_42480952/11419174