很久没更新了,最近花了点时间研究了下LWIP,看着很复杂,实际也还好。
LWIP学习推荐看野火的资料,如果加freertos操作系统的话直接利用cubemx生成即可,省心省力。
先开个头,后面有时间再编辑详细介绍。
1.简介
LWIP是轻量化的 TCP/IP协议,包括无操作系统运行(RAW)和有操作系统运行。
官方源码下载地址:http://download-mirror.savannah.gnu.org/releases/lwip/
LWIP有三种编程接口:
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