【LwIP源码学习笔记1】LwIP网络接口管理

netif结构体

netif是Lwip抽象出来的网卡,结构体的声明在Lwip/include/lwip/netif.h文件中。

Lwip将每个用netif描述的网卡连接成一个链表(单向链表)。

以下是在netif.h头文件中定义的一些netif的操作函数

c 复制代码
struct netif *netif_add_noaddr(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input);

#if LWIP_IPV4
struct netif *netif_add(struct netif *netif,
                            const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
                            void *state, netif_init_fn init, netif_input_fn input);
void netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask,
                    const ip4_addr_t *gw);
#else /* LWIP_IPV4 */
struct netif *netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input);
#endif /* LWIP_IPV4 */
void netif_remove(struct netif * netif);

操作函数中第一个参数是netif指针,用这种方式达到了C++中类的封装效果,有设计模式中工厂模式的设计思想,也就是该结构体表示对象的数量是不确定的,随时可能变多或者单少,这种情况下可以使用操作函数+首个参数是结构体指针的方式,方便对多个同类对象管理。

如果系统中对象的数量是固定的并且不多,比如系统只有两个串口,或者以后最多再加一个串口,这种情况属于设计模式中的单例模式,把结构体的声明和响应的操作函数分开更好一些,如:

c 复制代码
//serial_port_a .h
struct serial_port_a {
	//串口A结构体内容
}; 

unsigned char read_serial_port_a(unsigned char *pbuf, unsigned int size);
c 复制代码
//serial_port_b .h
struct serial_port_b {
	//串口B结构体内容
}; 

unsigned char read_serial_port_b(unsigned char *pbuf, unsigned int size);

netif的使用

LwIP是通过链表管理所有网卡的,所以第一步通过netif_add()函数将网卡挂载到netif_list链表中。

netif_add()的实现在LwIP\core\netif.c文件中。

c 复制代码
struct netif *
netif_add(struct netif *netif,
#if LWIP_IPV4
          const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
#endif /* LWIP_IPV4 */
          void *state, netif_init_fn init, netif_input_fn input)

需要传入的参数:netif结构体指针、IP地址、子网掩码、默认网关、网卡初始化函数、网络数据接收函数。

netif_add()函数在TCPIP_Init()函数中被调用,TCPIP_Init()函数在User\arch\sys_arch.c里。

netif底层相关函数

最底层的有三个函数

c 复制代码
static void low_level_init(struct netif *netif)

负责根据netif初始化响应的网卡。

c 复制代码
static err_t low_level_output(struct netif *netif, struct pbuf *p)

负责把p指向的pbuf结构体内的数据发送给netif表示的网卡。

c 复制代码
static struct pbuf * low_level_input(struct netif *netif)

负责从netif表示的网卡的网卡接收数据,并且将数据封装成pbuf的形式。

函数调用过程

low_level_init被调用过程如下:

low_level_input被调用过程如下:

low_level_init创建一个进行执行ethernetif_init函数,ethernetif_init中循环检测网口中是否接收到新数据。
low_level_outputethernetif_init中与相应的网卡建立关联:

c 复制代码
  netif->linkoutput = low_level_output;
  
  /* initialize the hardware */
  low_level_init(netif);
相关推荐
Jackyzhe6 小时前
Flink学习笔记:整体架构
笔记·flink
会编程的小孩6 小时前
STM32用PWM驱动步进电机
stm32·单片机·嵌入式硬件
徒 花6 小时前
初级网安作业笔记1
笔记
kfepiza6 小时前
Debian-10编译安装Mysql-5.7.44 笔记250706
linux·数据库·笔记·mysql·debian·bash
西西西仓鼠6 小时前
python学习打卡:DAY 40 训练和测试的规范写法
学习
Magnetic_h7 小时前
【iOS】方法与消息底层分析
笔记·学习·macos·ios·objective-c·cocoa
今天背单词了吗9807 小时前
算法学习笔记:19.牛顿迭代法——从原理到实战,涵盖 LeetCode 与考研 408 例题
笔记·学习·算法·牛顿迭代法
努力做小白8 小时前
Linux驱动11 --- buildroot&杂项驱动开发方法
linux·运维·驱动开发·单片机·嵌入式硬件
DKPT8 小时前
Java设计模式之行为型模式(观察者模式)介绍与说明
java·笔记·学习·观察者模式·设计模式
小眼睛FPGA9 小时前
【RK3568+PG2L50H开发板实验例程】FPGA部分 | 以太网传输实验例程
科技·单片机·嵌入式硬件·ai·fpga开发·fpga