LWIP -- 以太网网卡接口部分初始化

在《SylixOS_LWIP协议栈学习:网络接口结构》中,提到过netif 结构体netdev结构体
    其中 netdev结构体是对 netif 结构体的一层封装。它们都是用来描述一个 以太网网卡 接口的。
   
我们举个例子来看一个以太网网卡接口结构是怎样被初始化,还有数据包是如何接收和发送的。
    static struct netdev_funcs net_drv = {                         ①
       .init      = __enetCoreInit,
       .transmit  = __enetCoreTx,
       .receive   = __enetCoreRecv,
};
   pNetDev->speed        = 0;                              ②
   pNetDev->mtu          = 1500;
   pNetDev->hwaddr_len   = 6;
   pNetDev->drv          =&net_drv;
   lib_strcpy(ip,     "192.168.3.202");                         ③
   lib_strcpy(gw,     "192.168.3.1");
   lib_strcpy(netmask, "255.255.255.0");
   netdev_add(pNetDev, ip, netmask, gw, IFF_UP |IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST) == 0) ;
                                                      ④
①声明了网卡驱动函数,分别是以太网初始化函数,以太网发送函数,以太网接收函数。
②声明了网卡驱动参数(省略了一部分)。
③声明了三个分别用于暂存 IP 地址、子网掩码和网关地址的变量。
④网卡驱动程序调用netdev_add函数来增加一个网络接口。

再来看看netdev_add函数源码
int  netdev_add (netdev_t *netdev, const char *ip, const char *netmask, const char *gw, int if_flags)
{
......
  netif = (struct netif *)netdev->sys;
  lib_bzero(netif, sizeof(struct netif));
......
  if (netifapi_netif_add(netif, &ip4, &netmask4, &gw4, netdev, netdev_netif_init, tcpip_input)) {
    return (-1);
  }
......
  if (netdev->init_flags & NETDEV_INIT_AS_DEFAULT) {
    netifapi_netif_set_default(netif);
  }
}
netdev_add 函数其实是netif_add的封装。最终还是通过 调用netif_add函数来增加一个网络接口。(其中 netdev->sys  是预留的用于存储netif结构体的成员变量)
其中netdev_netif_init 是用户自己定义的底层接口初始化函数, tcpip_input 函数是向 IP 层递交数据包的函数。

再来看看netif_add函数源码:
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)
{
......
  netif->state = state; //指向用户关心的信息,这里为 NULL
  netif->num = netifnum++; //设置 num 字段,
  netif->input = input; // input 函数被赋值 ,(tcpip_input向 IP 层递交数据包的函数)
......
  netif_set_addr(netif, ipaddr, netmask, gw); //设置变量 enc28j60 的三个地址

  if (init(netif) != ERR_OK) { //用户自己的底层接口初始化函数(netdev_netif_init自己定义的底层接口初始化函数)
      return NULL;
  }
  netif->next = netif_list; //将初始化后的节点插入链表 netif_list
  netif_list = netif; // netif_list 指向链表头
......
}
上面的初始化函数调用了用户自己定义的底层接口初始化函数,这里为netdev_netif_init函数,再来看看它的源代码:
/* lwip netif add call back function */
static err_t  netdev_netif_init (struct netif *netif)
{
......
  netif->output = etharp_output;  //IP 层发送数据包函数
......
  netif->linkoutput = netdev_netif_linkoutput; //ARP 模块发送数据包函数
......
}
至此,以太网网卡接口部分初始化结束。

总结:
    在SylixOS中对LWIP进行了一次封装,最终使用的还是netif结构体和netif_add函数。
    netif_add函数中填充了input、output、linkoutput等函数用于IP层从网卡上取得一个数据包、IP层向网卡发送一个数据包  、ARP 模块向网卡发送一个数据包。

你可能感兴趣的:(网络,SylixOS)