处理链路状态改变

[文/告别年代   Email:byeyear@hotmail.com]

基本流程

-----------------------------------------

A. link up -> link down:

   关闭MAC和DMA;

   调用netif_set_link_down

B. link down -> link up:

   打开MAC和DMA;

   调用netif_set_link_up

C. 注意:当使用RAW API时,所有使用RAW API的代码(包括处理链路状态的代码)必须运行于同一线程环境。

-----------------------------------------

 

代码分析

-----------------------------------------

有四个函数和两个标志位和链路状态改变有关:

A. netif_set_up

   该函数设置NETIF_FLAG_UP标记,并在链路已up的情况下发送arp探测。

   如果你的网络使用静态IP,那么在lwip初始化时调用该函数;

   如果你的网络使用DHCP,那么DHCP成功后会帮你调用netif_set_up。

B. netif_set_down

   除非你需要关闭网络,否则一般不需要主动调用该函数。

C. netif_set_link_up

   该函数设置NETIF_FLAG_LINK_UP标记,启动DHCP和AutoIP,并在NETIF_FLAG_UP标记有效的情况下发送arp探测。

   当链路从down变化为up时调用该函数。

   注意:初始化时如果链路有效,low_level_init将直接设置NETIF_FLAG_LINK_UP,而不调用netif_set_link_up函数,避免在lwip没有完全初始化好时启动DHCP。

D. netif_set_link_down

   在链路从up变为down时调用该函数。

E. NETIF_FLAG_UP和NETIF_FLAG_LINK_UP

   前者表示lwip协议栈已经就绪(已得到合法IP地址,且协议栈已准备好收发数据包);后者表示链路层有效。

   或者说,一个是软件(协议栈)就绪标志,一个是硬件(链路层)就绪标志。

F. 参考lwip代码中的netif.h文件对这两个标记的详细说明。

   网上很多port代码不管是否使用DHCP都在lwip初始化时设置NETIF_FLAG_UP,这是*不*正确的。

   NETIF_FLAG_UP必须在获得有效IP地址后才能置位,以保证顺利发送ARP探测。

 

情景分析

--------------------------------------------------------------

A. 静态IP,初始化时链路有效

    这是最简情况。驱动层会看到Link有效,并直接设置NETIF_FLAG_LINK_UP。

    随后lwip初始化过程中调用netif_set_up,该函数设置NETIF_FLAG_UP,并发送arp探测。

B. 静态IP,初始化时链路无效

    驱动层不会设置NETIF_FLAG_LINK_UP。

    lwip初始化过程会调用netif_set_up,该函数看到没有link,除了设置标记外不会做任何事。

    当链路变为有效后,驱动层调用netif_set_link_up,发送arp探测。

C. 动态IP,初始化时链路有效

    驱动层直接设置NETIF_FLAG_LINK_UP。

    lwip初始化过程中调用dhcp_start,启动DHCP过程。

    但lwip初始化过程不会调用netif_set_up,因为还没有获得有效IP地址。

    获得有效IP后,lwip会帮我们调用netif_set_up,发送arp探测。

D. 动态IP,初始化时链路无效

    驱动层不会设置NETIF_FLAG_LINK_UP。

    lwip初始化过程中仍然会调用dhcp_start。对dhcp_start的调用是必须的,因为dhcp过程需要的资源将在该函数中分配。

    等到链路有效后驱动层调用netif_set_link_up,该函数会启动DHCP过程。

    获得有效IP后,lwip会帮我们调用netif_set_up,发送arp探测。

E. 静态IP,链路断开后重建

    链路断开时netif_set_link_down,重建后netif_set_link_up发送arp探测。

    NETIF_FLAG_UP在设置后就一直有效。

F. 动态IP,链路断开后重建

    链路重建后netif_set_link_up重新启动DHCP过程,该过程会清除NETIF_FLAG_UP标记。

    DHCP完成后lwip自动调用netif_set_up重新置位该标记并发起arp探测。

 

总结

-------------------------------------------------------------------------------------

1. 使用静态IP

    low_level_init根据当前链路状态设置或不设置NETIF_FLAG_LINK_UP;

    lwip初始化时调用netif_set_up;

    链路状态改变时调用netif_set_link_up/netif_set_link_down。

2. 使用动态IP

    low_level_init根据当前链路状态设置或不设置NETIF_FLAG_LINK_UP;

    lwip初始化时调用dhcp_start;

    链路状态改变时调用netif_set_link_up/netif_set_link_down;

    不要在使用动态IP时直接调用netif_set_up,而是由lwip协议栈代码在成功获得IP后为你调用这个函数。

[文/告别年代   Email:byeyear@hotmail.com]

处理链路状态改变

上一篇:对于VS code的进一步使用


下一篇:使用URLConnection 来get和post数据获取返回的数据