lwIP(TCPIP)协议栈移植(不包括网卡驱动)_第1页
lwIP(TCPIP)协议栈移植(不包括网卡驱动)_第2页
lwIP(TCPIP)协议栈移植(不包括网卡驱动)_第3页
lwIP(TCPIP)协议栈移植(不包括网卡驱动)_第4页
lwIP(TCPIP)协议栈移植(不包括网卡驱动)_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、lwIP(TCP/IP)协议栈移植(不包括网卡驱动)    关键字:lwIP一、lwIP 概述lwIP是瑞士计算机科学院(Swedish Institute of Computer Science)的Adam Dunkels等开发的一套用于嵌入式系统的开放源代码TCP/IP协议栈。Lwip既可以移植到操作系统上,又可以在无操作系统的情况下独立运行.                  &#

2、160;         LwIP的特性如下:(1)    支持多网络接口下的IP转发(2)    支持ICMP协议 (3)    包括实验性扩展的的UDP(用户数据报协议)(4)    包括阻塞控制,RTT估算和快速恢复和快速转发的TCP(传输控制协议)(5)    提供专门的内部回调接口(Raw API)用于提高应用程序性能(6)   

3、; 可选择的Berkeley接口API(多线程情况下)(7)    在最新的版本中支持ppp(8)    新版本中增加了的IP fragment的支持.(9)    支持DHCP协议,动态分配ip地址.以上内容摘自网络 关于ucos 上的lwip移植 二、移植介绍       整个移植过程主要参考网络上关于移植到ucos 的说明和源码。1.  目录及文件介绍原版的lwIP1.1.0包含两个目录src 和 doc移植后增加如下文

4、件和目录Arch        Lib_arch.c本系统没用,系统中没有实现的C库函数可以写到这里        Sys_arch.c 移植的主要工作在这里,关于信号量、消息队列、任务创建        RX4000 项目目录             

5、60; Include                      Arch                          &#

6、160;         cc.h 类型定义 大小端设置 PACK定义等                                    init.h &

7、#160;                                  lib.h 跟Lib_arch.c对应 函数声明             

8、;                       perf.h 没用                          &

9、#160;         sys_arch.h 跟Sys_arch.c对应的一些类型定义和宏定义                      Netif             &

10、#160;                      Dm9000a.h                          

11、60;         Ne2kif.h               Netif                      Dm_netif.c 网卡驱动与系统关联的抽象

12、层                      Dm9000a.c网卡的硬件操作函数                      Ne2kif.c 没用Init  

13、      Lwip.c 协议栈初始化和DHCP初始化        Lwipopts.h 协议栈相关参数设置Dns        Dns.c 增加域名解析函数 gethostbyname (非可重入函数)        Dns.h2.  移植相关函数介绍1)      sys_

14、init这个很简单,就是一些全局量的初始化2)      sys_thread_new sys_arch_timeouts相关的三个全局变量如下struct sys_timeouts lwip_timeoutsLWIP_TASK_MAX;为每一个由sys_thread_new创建的任务分配一个存放信号量超时信息的列表struct sys_timeouts null_timeouts;为一个超过任务上限数的任务和不是由sys_thread_new创建的任务取超时列表时返回使用。MMAC_RTOS_TASK_ID LWIP_TASKSLWIP_TA

15、SK_MAX;任务id存放顺序与lwip_timeouts相对应sys_thread_new用来创建一个新的任务,保存任务ID。sys_arch_timeouts就是通过取得任务ID返回任务对应的timeouts结构,从而可以添加、删除和判断超时的功能3)      sys_sem_new sys_sem_free  sys_sem_signal sys_arch_sem_waitsys_sem_new创建一个信号灯并初始化灯的数量返回sys_sem_t 类型的变量,定义是这样的typedef MMAC_RTOS_SEMAPHORE&

16、#160; *sys_sem_t; 由于返回失败要返回NULL值所以就定义了系统信号量的指针为抽象信号量类型。因此在sys_sem_new和 sys_sem_free 分别要进行内存申请和释放的工作。       sys_sem_signal释放一个灯,sys_arch_sem_wait 等待信号,其中参数timeout是以ms为单位的,若wei零则表示永远等待一直到信号的来临。       在这个信号系统中本人还存在一个疑问,具体在5"存在的问题"中进行

17、说明4)      sys_mbox_new sys_mbox_free sys_mbox_post sys_arch_mbox_fetch同上原因在类型的定义成指针的。那sys_mbox_new 和sys_mbox_free同样要进行内存的申请和释放。在系统中消息队列发送和接收的都是指向数据的指针,因为在发送前所有的数据都已经存放在一个全局的用来管理内存的变量中。所以发送的内容就是四个字节。发送是还要判断发送msg是否为NULL。因为发送的是msg的指针,而不是内容还要取一下地址,NULL明显不能取址,所以有一个专门的static int *

18、msg_null=NULL (这里的=NULL 并不重要可以使任何值 * 也可以不要,因为要的是变量的地址在内存中的唯一性)用来发送"NULL"信息,使msg = &msg_null再发送。接收到后也要进行 *msg =&msg_null的判断。接收时也要进行msg NULL的判断,若msg为NULL就需要零时申请一个空间进行接收。还要注意发送和接收时msg的类型,发送是void* 的 ,接收是void *,要做好相应的处理。3.  移植中相关配置的介绍1)      SYS_LIGHTWEIGHT

19、_PROT我的理解应该是是否使用系统临界区变量,由于本系统没有单独的临界区变量,所以就设置成 0 ,那就用信号灯来完成该任务。且sys_arch.h中的最后三个宏也要定义成空。2)      累加和关闭所有的累加检查,因为硬件已有该功能了#define CHECKSUM_GEN_IP                 0#define CHECKSUM_GEN_UDP  

20、;              0#define CHECKSUM_GEN_TCP                0#define CHECKSUM_CHECK_IP             

21、  0#define CHECKSUM_CHECK_UDP              0#define CHECKSUM_CHECK_TCP              03)      LWIP_HAVE_LOOPIF是否开启回环,在还没有网卡驱动的时候,可以设置为 1 添加lo

22、op设备进行调试运行。4)      内存分配设定在协议栈中很多内存都是事先申请的,有协议栈自己进行管理。据我了解有三大块内存PBUF MEMP MEM。在lwipopts.h中的Memory options中定义了各块内存的种类及各种类的数量。这部分的设置要仔细斟酌。具体就不再详述了。5)      TCP_SND_BUF该设置对网络传输的速度由很大的影响。Ucos+lwIP的源码中的默认设置是256,用socket进行速度测试时却只有区区的1KB/S左右的速度。最后改成8192后速度达到 6

23、00KB/S。6)      LWIP_DHCP  本系统需要DHCP支持因此需要设置为 1。在他下面有一个DHCP_DOES_ARP_CHECK的宏设置为 0。 开启后出现错误。原因不明。4.  移植中碰到的问题总结1)  同时支持UDP及TCP及DHCP的支持不再详述看出始化代码void Task_lwip_init(void * pParam)  struct ip_addr ipaddr, netmask, gw;  sys_sem_t sem;  err_t result ;

24、  int icount = 0;  int idhcpre=0;    #if LWIP_STATS  stats_init();  #endif  / initial lwIP stack  sys_init();  mem_init();  memp_init();  pbuf_init();  netif_init();    printf("LWIP:TCP/IP initializing.n");   

25、sem = sys_sem_new(0);  tcpip_init(tcpip_init_done_ok, &sem);  sys_sem_wait(sem);  sys_sem_free(sem);  printf("LWIP:TCP/IP initialized.n");    /*  /add loop interface /SET local loop-interface   IP4_ADDR(&gw, 127,0,0,1);  IP

26、4_ADDR(&ipaddr, 127,0,0,1);  IP4_ADDR(&netmask, 255,0,0,0);  netif_add(&loop_if, &ipaddr, &netmask, &gw, NULL, loopif_init, tcpip_input);   netif_SET_default(&loop_if);  netif_SET_up(&loop_if);   /*/#if 0      IP4_ADDR

27、(&gw, 192,168,0,2);  IP4_ADDR(&ipaddr, 192,168,0,186);  IP4_ADDR(&netmask, 255,255,255,0);  netif_add(&dm9if_if, &ipaddr, &netmask, &gw, NULL, dm9_netif_init, tcpip_input);  netif_SET_default(&dm9if_if);  netif_SET_up(&dm9if_if); #else

28、0; IP4_ADDR(&gw, 0,0,0,0);  IP4_ADDR(&ipaddr, 0,0,0,0);  IP4_ADDR(&netmask, 0,0,0,0);  netif_add(&dm9if_if, &ipaddr, &netmask, &gw, NULL, dm9_netif_init, udp_input);/添加udp支持  printf("LWIP:waiting for neif init n");  MMAC_RTOS_Sleep( 3500

29、);    for(idhcpre = 0; idhcpre<4;  idhcpre+ )/dhcp最多重试4遍        printf("LWIP:start dhcp request n");      result  = dhcp_start(&dm9if_if);/广播dhcp请求       IP4_ADDR(&ipaddr, 0,0,0,0); &#

30、160;    for(icount = 0; (icount < 10) && (ipaddr.addr = 0); icount + )                ipaddr.addr = dm9if_if.ip_addr.addr;            MMAC_RTOS_Sleep( 1000);   

31、;    / if failed ipaddr = ;timeout = 10 * 1000 ms           /等待dhcp是否接受到IP了      / add dns server ip      dns_add(0,&dm9if_if.dhcp->offered_dns_addr0);      dns_add(

32、1,&dm9if_if.dhcp->offered_dns_addr1);       /不需要dns的去掉上面两句      dhcp_stop(&dm9if_if); /一次dhcp结束       if (ipaddr.addr != 0)          break;      gw.addr = dm9if_if.gw.ad

33、dr;  ipaddr.addr = dm9if_if.ip_addr.addr;  netmask.addr = dm9if_mask.addr;  /netif_remove(&dm9if_if);  netif_add(&dm9if_if_tcp, &ipaddr, &netmask, &gw, NULL, dm9_netif_init, tcpip_input);/添加tcp支持   netif_SET_up(&dm9if_if_tcp);   netif_SET_up

34、(&dm9if_if);   netif_SET_default(&dm9if_if_tcp); #endif   sprintf(STRIPADDR,"%d.%d.%d.%d",ip4_addr1(&ipaddr), ip4_addr2(&ipaddr),ip4_addr3(&ipaddr),ip4_addr4(&ipaddr);  printf("LWIP:IPADDR = %sn",STRIPADDR);    if (ipaddr

35、.addr != 0)    /-  /    / http thread, a web page can be browsed / sys_thread_new(httpd_init, (void*)"httpd",TCPIP_THREAD_PRIO);    /-      sys_thread_new(test_net, NULL, TCPIP_THREAD_PRIO);    /* Block for ever. */

36、  sem = sys_sem_new(0);  sys_sem_wait(sem);2)对齐问题PBUF_LINK_HLEN 16static u8_t ip_reassbitmapMEM_ALIGN_SIZE(IP_REASS_BUFSIZE / (8 * 8);在调试的时候经常碰到内存访问错误的异常,最后查得原因是内存的起始地址不再4的倍数上,导致不能访问。因为内存申请时有字节数来的,有时要强制转换为某种结构。为了保证地址不错,PBUF_LINK_HLEN 定义为16,ip_reassbitmap的大小也变成4的倍数。因为它的大小不是4的倍数,就导致附近的内存分配起始

37、不是4的倍数。这个解决办法由点不好,但是没有办法,我用 align 等声明没有作用。3)大包ping问题原因是以太网络中,最大允许的包大小为1514字节,若用pc机ping l 2000 ip地址 测试,pc会把ip包分解成多个发送,lwIP接受后会把他数据合成方在pbuf中,并直接发送出去,可惜程序中不会把包分解发送。导致发送网络不允许的包。这样不但pc接受不到包,而且lwIP也出现问题。解决方法,在发送的地方,若包大于1514就不给发送。虽然解决不了大包ping不通问题,但至少lwIP不会死。5.  存在的问题1)没有对应得任务释放函数,除非以后的任务都是一直存在不需释放的2)D

38、NS gethostbyname 的不可重入问题3)DHCP_DOES_ARP_CHECK 设置为1 死机4)信号量中timeout 管理的疑问        操作系统中本身带有的函数就已经有timeout参数了,用它多此一举。但想想是不是为了没有timeout的操作系统准备的呢。但它在运行过程中又没有使用到,也没有找到什么代码来确定某个sem已经超时,而仅仅使用了我使用嵌入式操作系统的timeout。 三、上层开发接口       1.Socket 接口

39、 sockets.h              #define accept(a,b,c)         lwip_accept(a,b,c)#define bind(a,b,c)           lwip_bind(a,b,c)#define shutdown(a,b)         lwip_shutdown(a,b)#define close(s)              lwip_clo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论