我是靠谱客的博主 灵巧小虾米,最近开发中收集的这篇文章主要介绍7.9(lwip),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

什么是半双工?什么是全双工模式?




lwip_commom_init()函数分析:
   netif_add()函数中参数lwip_netip中定义了网络接口,这个函数除了IP地址、子网掩码、默认网关,还包括了两个函数地址作为参数,ethernetif_init和ethernet_input。这两个函数地址会赋值到netif结构体的相关字段。ethernetif_init()在下一节中将会讲到,这个函数函数由ALIENTEK提供,ethernet_input()函数在etharp.c文件中,属于LWIP源码,是ARP层数据包输入函数。

Netif_Init_Flag=netif_add(&lwip_netif,&ipaddr,&netmask,&gw,NULL,&ethernetif_init,&ethernet_input);该函数最后两个参数是一个函数指针,该函数是有输入参数的函数。其函数定义为:
   typedef err_t (*netif_init_fn)(struct netif *netif);
   typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp);
   由上可知,实际上是 同时将IP、子网掩码、网关和两个函数添加在网卡列表中

7、如果使用 DHCP的话就开启DHCP服务,通过调用dhcp_start()函数开启DHCP服务。使用DHCP服     务来获取IP地址、子网掩码和默认网关等信息,如果使用静态IP地址的话就 ip_comm_default_ip_set()函数设置的地址信息。


8、使用dhcp获取iplwIP中主要有memp.h, memp_std.h, memp.c, mem.h, mem.c几个类组成了内存管理模块。
9.  一、tcppcbnew = tcp_new();//创建一个新的pcb,该TCP protocol控制块不放入任何

PCB列表中,直到绑定(即二步骤),才放入列表中!!!!
                ->tcp_alloc(TCP_PRIO_NORMAL); //TCP_PRIO_NORMAL = 64;
       ->pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
 
->(MEMP_TCP_PCB难点)  
                                   if  LWIP_TCP
   LWIP_MEMPOOL(TCP_PCB,  MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb),  "TCP_PCB")
   LWIP_MEMPOOL(TCP_PCB_LISTEN,  MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen),  "TCP_PCB_LISTEN")
   LWIP_MEMPOOL(TCP_SEG,        MEMP_NUM_TCP_SEG,         sizeof(struct tcp_seg),        "TCP_SEG")
                                                    #endif /* LWIP_TCP */
                       ->(LWIP_MEMPOOL难点)
              typedef enum{
  #define LWIP_MEMPOOL(name, num,size,desc)  MEMP_##name,
  #include "lwip/memp_std.h"
       MEMP_MAX
                  }memp_t;

1、该枚举类型将

2、如果定义了LWIP_TCP_PCB,则


             ->(memp_malloc()难点)  if !MEMP_OVERFLOW_CHECK          //opt.h中定义了MEMP_OVERFLOW_CHECK=0

                                                        memp_malloc(memp_t type)  
                                                 #else 
                                          memp_malloc_fn(mem_t type,const char *file,const int line)
                                        #endif
                  {
  struct memp *memp;
  SYS_ARCH_DECL_PROTECT(old_level);
                                     ->  #ifndef   SYS_ARCH_PROECT   //如果该宏定义未定义
                                       #if  SYS_LIGHTWEIGH_PORT     //初始化 = 0,如果定义则宏定义下面的值
                                       #define    SYS_ARCH_DECL_PROTECT(lev)  sys_prot_t  lev    //等同于定义了一个sys_prot_t的变量lev
                                        #define SYS_ARCH_PROEC(lev)           lev = sys_arch_protect()   
                                       #define SYS_ARCH_UNPROTECT         (lev)  sys_arch_unprotect(lev)
                     sys_prot_t   sys_arch_protect(void);
                   void sys_arch_unprotect(sys_prot_t prval);
                                                      #else 
              #define SYS_ARCH_DECL_PROTECT(lev)
              #define SYS_ARCH_PROTECT(lev)
              #define SYS_ARCH_UNPROTECT(lev)
              #endif                      
       }
                     3、 上面的定义假如默认为MEMP_OVERFLOW_CHECK=0,则定义为memp_malloc(mem_t type) {     }
                                 ,由上可知在c语言中的函数名也可以宏定义。

     
      二、err = tcp_blind(tcppcbnew,IP_ADDR_ANY,TCP_SERVER_PORT);   //这就是所谓的将pcb块绑定,即将端口号和本地IP绑定在一起
      if(tcppcbnew == ERR_OK)  //如果绑定完成                       //只有这样,新建的pcb控制块才会进入监听等状态,实现功能
      {
err = tcp_bind(tcppcbnew,IP_ADDR_ANY,TCP_SERVER_PORT);  //设置tcppcb进入监听状态
tcp_accept(tcppcbconn,tcp_server_accept);  //初始化LWIP的tcp_accpt的回调函数

    //这个部分设置了newpcb的各部分的回调函数,此概念很重要!!!

// 将tcp_setver_accept函数赋给pcb控制块tcppcbconn的

}else res = 1;
创建tcp_new()= tcppcbnew成功后,而且绑定完成后,res = 0,否则不会进入键盘检测。res = 0,进入键盘检测。键盘检测主要检测的是tcp_server_flag=1<<7/1<<6/1<<5来标记发送数据、收到数据、是否连接上?(涉及到重要的概念:回调函数)。
        在tcp.c中都会有关于对pcb块的回调成员函数初始化的函数,tcp_recv()、tcp_err、tcp_poll()等函数,然后回调函数都是在tcp_server_demo.c中进行了定义(即应用层),利用这些接口对pcp进行操作。  其中只要绑定成功,且tcp_accpt进入监听,回调函数tcp_accept(tcppcbconn,tcp_server_accpt)成功,则1>>5在tcp_accpt()中置位。  连接上后,如果连接标志位connflag为0,则在显示连接的同时,将connflag置1,进行之后的if(connflag==1)判断。

tcp_server_flag = 1<<6;用来标记收到数据,在lwIP tcp_recv()函数的回调函数tcp_server_recv()中,接受到数据则,tcp_server_flag |= 1<<6置位。

而对于tcp_server_flag&1<<7=1条件成立,是只要按键KEY_WKUP按下即置位相应位为1,在tcp_server_poll()函数中进行调用判断即可。

  总而言之,以上设置的标志位都是为了在应用层判断显示等操作,真正进行底层操作的是PCB控制块中的回调函数在起作用!!!!!!

 


lwip轮询任务函数:lwip_periodic_handle()中对于不同的传输方式,根据不同的条件判断:
  lwip_localtime - TCPTimer->TCP_TMR_INTERVAL  
 lwip_localtime - ARPTimer->ARP_TMR_INIERVAL  

                 来调用不同函数tcp_tmr()、etharp()、dhcp_fine_tmr()函数。tcp_tmr()函数中对tcp_fasttmr() 250ms调用一次 tcp_slowtmr() 500ms调用一次
        tcp_fasttmr()用于每TCP_FAST_INTERVAL(250ms)处理从上层(应用层)“拒绝”回来的数据。
        tcp_slowtmr()用于每500ms执行转发定时器并且该定时器将等待足够时间的的PCB移除。它同时将增量多个定时器,如PCB中的不活跃定时器。
        在main()函数中我们要注意到不管是在等待DHCP完成还是DHCP成功后我们都要周期性的调用lwip_periodioc_handle()函数,因为这个函数中周期性的调用协议栈内核的一些定时函数以满足LWIP的内核要求。

最后

以上就是灵巧小虾米为你收集整理的7.9(lwip)的全部内容,希望文章能够帮你解决7.9(lwip)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部