uIP协议栈分析_协议栈

uIP协议栈分析_协议栈转载地址:http://blog.sina.com.cn/s/blog_abd39cc70101fj1f.htmluIP特性uIP协议栈往掉了完整的TCP/IP中不常用的功能,简化了通讯流程,但保存了网络通讯必须使用的协议,设计重点放在了IP/TCP/ICMP/UDP/ARP这些网络层和传输层协议上,保证了其代码的通用性和结构的稳定性。由于uIP协议栈专门为嵌进式系统而设计,因此还具有…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

转载地址:http://blog.sina.com.cn/s/blog_abd39cc70101fj1f.html

uIP特性

uIP协议栈往掉了完整的TCP/IP中不常用的功能,简化了通讯流程,但保存了网络通讯必须使用的协议,设计重点放在了IP/TCP/ICMP/UDP/ARP这些网络层和传输层协议上,保证了其代码的通用性和结构的稳定性。

由于uIP协议栈专门为嵌进式系统而设计,因此还具有如下优越功能:

(1)    代码非常少,其协议栈代码不到6K,很方便阅读和移植。

(2)    占用的内存数非常少,RAM占用仅几百字节。

(3)    其硬件处理层、协议栈层和应用层共用一个全局缓存区,不存在数据的拷贝,且发送和接收都是依靠这个缓存区,极大的节省空间和时间。

(4)    支持多个主动连接和被动连接并发。

(5)    其源代码中提供一套实例程序:web服务器,web客户端,电子邮件发送程序(SMTP客户端),Telnet服务器, DNS主机名解析程序等。通用性强,移植起来基本不用修改就可以通过。

(6)    对数据的处理采用轮循机制,不需要操纵系统的支持。

由于uIP对资源的需求少和移植轻易,大部分的8位微控制器都使用过uIP协议栈, 而且很多的著名的嵌进式产品和项目(如卫星,Cisco路由器,无线传感器网络)中都在使用uIP协议栈。

uIP架构

uIP相当于一个代码库,通过一系列的函数实现与底层硬件和高层应用程序的通讯,对于整个系统来说它内部的协议组是透明的,从而增加了协议的通用性。uIP协议栈与系统底层和高层应用之间的关系如图2-1所示。

    从上图可以看出,uIP协议栈主要提供了三个函数供系统底层调用。即uip_init(), uip_input() 和uip_periodic()。其与应用程序的主要接口是UIP_APPCALL( )。

uip_init()是系统初始化时调用的,主要初始化协议栈的侦听端口和默认所有连接是封闭的。

当网卡驱动收到一个输进包时,将放进全局缓冲区uip_buf中,包的大小由全局变量uip_len约束。同时将调用uip_input()函数,这个函数将会根据包首部的协议处理这个包和需要时调用应用程序。当uip_input()返回时,一个输出包同样放在全局缓冲区uip_buf里,大小赋给uip_len。假如uip_len是0,则说明没有包要发送。否则调用底层系统的发包函数将包发送到网络上。

uIP周期计时是用于驱动所有的uIP内部时钟事件。当周期计时激发,每一个TCP连接都会调用uIP函数uip_periodic()。类似于uip_input()函数。uip_periodic()函数返回时,输出的IP包要放到uip_buf中,供底层系统查询uip_len的大小发送。

由于使用TCP/IP的应用场景很多,因此应用程序作为单独的模块由用户实现。uIP协议栈提供一系列接口函数供用户程序调用,其中大部分函数是作为C的宏命令实现的,主要是为了速度、代码大小、效率和堆栈的使用。用户需要将应用层进口程序作为接口提供给uIP协议栈,并将这个函数定义为宏UIP_APPCALL()。这样,uIP在接受到底层传来的数据包后,在需要送到上层应用程序处理的地方,调用UIP_APPCALL( )。在不用修改协议栈的情况下可以适配不同的应用程序。

uIPMCS-51单片机上的移植

1.为此项目建立一个keil C工程,建立src目录存放源文件。

2.通过阅读uip-1.0\unix\main.c,了解uIP的的主循环代码架构,并将main.c放到src目录下。

3.仿照uip-1.0\unix\tapdev.c写网卡驱动程序,与具体硬件相关。这一步比较费点时间,不过好在大部分网卡芯片的驱动程序都有代码鉴戒或移植。驱动需要提供三个函数,以RTL9019AS驱动为例。

etherdev_init():网卡初始化函数,初始化网卡的工作模式。

u16_t etherdev_read(void):读包函数。将网卡收到的数据放进全局缓存区uip_buf中,返回包的长度,赋给uip_len。

void etherdev_send(void):发包函数。将全局缓存区uip_buf里的数据(长度放在uip_len中)发送出往。

所以,收包和发包主要是操纵uip_buf和uip_len。具体驱动分析可参考《第三章  网络芯片的驱动》。

4.由于uIP协议栈需要使用时钟,为TCP和ARP的定时器服务。因此使用单片机的定时器0用作时钟,每20ms让计数TIck_cnt加1,这样,25次计数(0.5S)满了后可以调用TCP的定时处理程序。10S后可以调用ARP老化程序。对uIP1.0版本,增加了timer.c/timer.h,专门用来治理时钟,都放到src下。

5.uIP协议栈的主要内容在uip-1.0\uip\下的uip.c/uip.h中,放到src下。假如需要ARP协议,需要将uip_arp.c和uip_arp.h也放到src下。

6.uipopt.h/uip-cONf.h是配置文件,用来设置本地的IP地址、网关地址、MAC地址、全局缓冲区的大小、支持的最大连接数、侦听数、ARP表大小等。需要放在src下,并且根据需要配置。在V1.00版本中对配置做了如下修改:

(1)配置IP地址,默认先关IP,在初始化中再设定。

#define UIP_FIXEDADDR   0

#define UIP_IPADDR0     192

#define UIP_IPADDR1     168

#define UIP_IPADDR2     1 

#define UIP_IPADDR3     9

#define UIP_NETMASK0    255

#define UIP_NETMASK1    255

#define UIP_NETMASK2    255

#define UIP_NETMASK3    0  

#define UIP_DRIPADDR0   192

#define UIP_DRIPADDR1   168

#define UIP_DRIPADDR2   1 

#define UIP_DRIPADDR3   1  

(2)使能MAC地址

#define UIP_FIXEDETHADDR 1  

#define UIP_ETHADDR0    0x00 

#define UIP_ETHADDR1    0x4f

#define UIP_ETHADDR2    0x49

#define UIP_ETHADDR3    0x12

#define UIP_ETHADDR4    0x12 

#define UIP_ETHADDR5    0x13

(3)使能ping功能

#define UIP_PINGADDRCONF  1

(4)封闭主动请求连接的功能

#define UIP_ACTIVE_OPEN 0

(5)将uip_tcp_appstate_t定位u8_t类型。

(6)由于单片机是大端结构,因此宏定义需要修改

#define UIP_CONF_BYTE_ORDER      UIP_BIG_ENDIAN

(7)暂时不移植打印信息,先封闭

#define UIP_CONF_LOGGING     0

(8)定义数据结构类型

typedef unsigned char u8_t;

typedef unsigned int u16_t;

typedef unsigned long u32_t;

7. 假如使用keil C的小模式编译,需要在大部分的RAM的变量前增加xdata。

8.data为keil C的关键词,代码中所有出现data的地方(主要是参数、局部变量、结构体成员)改为pucdata或ucdata。

9.解决编译过程中的错误。uIP协议栈为C语言编写,编译过程中的题目比较少,并且轻易解决。 

uIP的主控制循环

通过实际的代码说明uIP协议栈的主控制循环。 
void main(void)

{

   

   

    timer_set(&periodic_timer, CLOCK_CONF_SECOND / 2);

    timer_set(&arp_timer, CLOCK_CONF_SECOND * 10);

    

    init_Timer();

 

    uip_init();

uip_arp_init();

 

    example1_init();

 

    etherdev_init();

 

    uip_ipaddr(ipaddr, 192,168,1,9);

    uip_sethostaddr(ipaddr);

    uip_ipaddr(ipaddr, 192,168,1,16);

    uip_setdraddr(ipaddr);

    uip_ipaddr(ipaddr, 255,255,255,0);

    uip_setnetmask(ipaddr);

 

    while(1)

    {

 

 

    uip_len = etherdev_read();

 

    if(uip_len > 0)

    {

   

        if(BUF->type == htons(UIP_ETHTYPE_IP))

        {

            uip_arp_ipin();

            uip_input();

     

            if(uip_len > 0)

        {

                uip_arp_out();

                etherdev_send();

            }

        }

 

        else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {

         uip_arp_arpin();

             if(uip_len > 0)

         {

                 etherdev_send();

             }

      }

        }

 

        else if(timer_expired(&periodic_timer))

        {

        timer_reset(&periodic_timer);

        for(i = 0; i < UIP_CONNS; i++)

        {

           uip_periodic(i);

           if(uip_len > 0)

          {

              uip_arp_out();

              etherdev_send();

                }

          }         

         

          if(timer_expired(&arp_timer))

          {

             timer_reset(&arp_timer);

             uip_arp_timer();

          }

        }

  }

  return;

}

uIP协议栈提供的主要接口

提供的接口在uip.h中,为了减少函数调用造成的额外支出,大部分接口函数以宏命令实现的。

    1.初始化uIP协议栈:uip_init()

    2.处理输进包:uip_input()

    3.处理周期计时势件:uip_periodic()

    4.开始监听端口:uip_listen()

    5.连接到远程主机:uip_connect()

    6.接收到连接请求:uip_connected()

    7.主动封闭连接:uip_close()

    8.连接被封闭:uip_closed()

    9.发出往的数据被应答:uip_acked()

    10.在当前连接发送数据:uip_send()

    11.在当前连接上收到新的数据:uip_newdata()

    12.告诉对方要停止连接:uip_stop()

    13.连接被意外终止:uip_aborted()

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/179104.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 使用PageOffice实现文档(word,excel,pdf)在线预览编辑[通俗易懂]

    使用PageOffice实现文档(word,excel,pdf)在线预览编辑[通俗易懂]最近发现一款不错的插件的PageOffice,地址是:http://www.zhuozhengsoft.com/Technical/他可以实现word,excel、pdf在线预览以及在线编辑。虽然商用的话需要收费,但是有免费的试用版,在实现自己毕业设计或是做样品的时候是一个不错的选择。他同时支持java\c#\php.一旦有了正真的项目花钱再买也可以。同时自己也可以熟悉如何使用。接着下面实现

    2022年5月3日
    132
  • CreateMutex详解–转

    CreateMutex详解–转一、介绍原型HANDLECreateMutex(LPSECURITY_ATTRIBUTESlpMutexAttributes,//指向安全属性的指针BOOLbInitialOwner

    2022年7月3日
    22
  • java自适应网站成品源代码出售 h5网页推广展示型官网CMS系统源码

    java自适应网站成品源代码出售 h5网页推广展示型官网CMS系统源码QQ:464652874项目具体详情点击这企业门户网站系统源代码java响应式企业官网成品源码公司行业通用源代码web网站出售可二次开发源码项目介绍:企业门户网站系统能够通过互联网得到广泛的、全面的宣传,让尽可能多的企业了解和熟知企业门户网站系统的便捷高效,不仅为用户提供了服务,而且也推广了自己,让更多的用户了解自己。对于企业而言,若拥有自己的企业门户网站系统,通过企业门户网站系统让企业的宣传、营销提上一个新台阶,同时提升了企业形象。技术介绍:前端页面自适应,支持PC和H5手机端、平

    2022年7月7日
    25
  • torchvision 安装出现错误[通俗易懂]

    torchvision 安装出现错误[通俗易懂](base)C:\Users\pxsj_admin>pipinstalltorchvisionCollectingtorchvisionUsingcachedhttps://files.pythonhosted.org/packages/fb/01/03fd7e503c16b3dc262483e5555ad40974ab5da8b9879e164b56c1f4ef6f/tor…

    2022年6月24日
    45
  • 如何更好的使用谷歌搜索引擎加速器_国外搜索引擎

    如何更好的使用谷歌搜索引擎加速器_国外搜索引擎搜索引擎命令大全!1、双引号把搜索词放在双引号中,代表完全匹配搜索,也就是说搜索结果返回的页面包含双引号中出现的所有的词,连顺序也必须完全匹配。bd和Google都支持这个指令。例如搜索:“seo方法图片”2、减号减号代表搜索不包含减号后面的词的页面。使用这个指令时减号前面必须是空格,减号后面没有空格,紧跟着需要排除的词。Google和bd都支持这个指令。例如:搜索-引擎返回的则是包含“搜索”这个词,却不包含“引擎”这个词的结果3、星号星号*是常用的通配符,也可以用在搜索中。百

    2025年10月22日
    2
  • 软件缺陷报告[通俗易懂]

    软件缺陷报告[通俗易懂]1、定义概述:标识并描述发现的缺陷,具有清晰、完整和可重视问题所需的信息的文档理解:测试人员发现缺陷,记录,通过缺陷报告将缺陷报告给开发人员,并对缺陷进行跟踪管理。缺陷报告是测试人员与开发人员之间重要的沟通方式2、什么是缺陷软件缺陷就是通常说的Bug,它是指在软件中存在的影响软件正常运行的问题3、软件缺陷产生的原因1、需求不明确和变更软件需求不清晰或者开发人员对需求理解偏差,导致软件设…

    2022年9月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号