TCPIP协议栈lwip的移植Word版.docx

上传人:b****6 文档编号:8452011 上传时间:2023-01-31 格式:DOCX 页数:30 大小:25.29KB
下载 相关 举报
TCPIP协议栈lwip的移植Word版.docx_第1页
第1页 / 共30页
TCPIP协议栈lwip的移植Word版.docx_第2页
第2页 / 共30页
TCPIP协议栈lwip的移植Word版.docx_第3页
第3页 / 共30页
TCPIP协议栈lwip的移植Word版.docx_第4页
第4页 / 共30页
TCPIP协议栈lwip的移植Word版.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

TCPIP协议栈lwip的移植Word版.docx

《TCPIP协议栈lwip的移植Word版.docx》由会员分享,可在线阅读,更多相关《TCPIP协议栈lwip的移植Word版.docx(30页珍藏版)》请在冰豆网上搜索。

TCPIP协议栈lwip的移植Word版.docx

TCPIP协议栈lwip的移植Word版

TCP/IP协议栈lwip的移植

新建几个头文件

Include/lwipopts.h

Include/arch/cc.h

Include/arch/perf.h

Include/arch/sys_arch.h

 

除头文件外还需要添加一个C文件:

sys_arch.c。

说明在doc/sys_arch.txt中。

 

修改netif/Ethernetif.c。

结构对齐的几个宏

对于一个结构下载下来的LWIP的通用定义如下:

PACK_STRUCT_BEGIN

structicmp_echo_hdr{

  PACK_STRUCT_FIELD(u8_ttype);

 PACK_STRUCT_FIELD(u8_tcode);

 PACK_STRUCT_FIELD(u16_tchksum);

 PACK_STRUCT_FIELD(u16_tid);

 PACK_STRUCT_FIELD(u16_tseqno);

} PACK_STRUCT_STRUCT;

PACK_STRUCT_EN

#definePACK_STRUCT_FIELD(x)   

这个宏是为了字节序的转换,由于是用的小端,就不用转换了直接定义为#definePACK_STRUCT_FIELD(x)   x

#definePACK_STRUCT_STRUCT

#definePACK_STRUCT_BEGIN

#definePACK_STRUCT_END

以上三个宏都是为了做结构体对齐用:

对于gcc的编译器在结构体后跟个关键字就ok

structip_hdr{

};__attribute__((__packed__))

因此可以定义为

#definePACK_STRUCT_STRUCT__attribute__((__packed__))

#definePACK_STRUCT_BEGIN

#definePACK_STRUCT_END

对于vc的编译器就郁闷了,vc做结构体对齐是这样做的

#pragmapack

(1)     //结构体按照1字节对齐

structip_hdr{

};

#pragmapack()      //结构体按照编译器默认值对齐

但是VC的编译器不允许将预处理做为宏,也就是不允许这种宏替代#definePACK_STRUCT_BEGIN#pragmapack

(1) 

所以想靠宏替换来完成字节对齐是不行了,于是就动了大工夫做了如下处理

#ifdefWIN32

#definePACK_STRUCT_STRUCT

#definePACK_STRUCT_BEGIN

#definePACK_STRUCT_END

#else

#definePACK_STRUCT_STRUCT__attribute__((__packed__))

#definePACK_STRUCT_BEGIN

#definePACK_STRUCT_END

endif

PACK_STRUCT_BEGIN

#ifdefWIN32

#pragmapack

(1)

#endif

structicmp_echo_hdr{

  PACK_STRUCT_FIELD(u8_ttype);

 PACK_STRUCT_FIELD(u8_tcode);

 PACK_STRUCT_FIELD(u16_tchksum);

 PACK_STRUCT_FIELD(u16_tid);

 PACK_STRUCT_FIELD(u16_tseqno);

} PACK_STRUCT_STRUCT;

#ifdefWIN32

#pragmapack()

#endif

PACK_STRUCT_END

这样一改在VC下和GCC都可以了,不过每个结构上都要修改一下,这个是黑郁闷黑郁闷啊

 

 

“轻量级”保护

 "lightweight"synchronizationmechanisms-

   SYS_ARCH_DECL_PROTECT(x)-declareaprotectionstatevariable.

   SYS_ARCH_PROTECT(x)     -enterprotectionmode.

   SYS_ARCH_UNPROTECT(x)   -leaveprotectionmode.

 

这三个宏定义一个快速的“保护”和“解除保护”操作。

例如进入保护可以是屏蔽中断或使用一个信号量或mutex。

注意:

进入保护后还允许再次进入保护,旧的保护标志通过lev返回,退出保护时再恢复。

 

如果没有定义这三个宏,Sys.h中有一段代码进行了判断。

#ifndefSYS_ARCH_PROTECT

 

如果没有定义SYS_ARCH_PROTECT,那么可以在lwipopts.h中定义宏SYS_LIGHTWEIGHT_PROT,并在sys_arch.c中定义函数sys_arch_protect()和sys_arch_unprotect(lev)

#ifSYS_LIGHTWEIGHT_PROT

 

#defineSYS_ARCH_DECL_PROTECT(lev)sys_prot_tlev

/**SYS_ARCH_PROTECT

 *Performa"fast"protect.Thiscouldbeimplementedby

 *disablinginterruptsforanembeddedsystemorbyusingasemaphoreor

 *mutex. TheimplementationshouldallowcallingSYS_ARCH_PROTECTwhen

 *alreadyprotected.Theoldprotectionlevelisreturnedinthevariable

 *"lev".Thismacrowilldefaulttocallingthesys_arch_protect()function

 *whichshouldbeimplementedinsys_arch.c.Ifaparticularportneedsa

 *differentimplementation,thenthismacromaybedefinedinsys_arch.h

 */

#defineSYS_ARCH_PROTECT(lev)lev=sys_arch_protect()

/**SYS_ARCH_UNPROTECT

 *Performa"fast"setoftheprotectionlevelto"lev".Thiscouldbe

 *implementedbysettingtheinterruptlevelto"lev"withintheMACROorby

 *usingasemaphoreormutex. Thismacrowilldefaulttocallingthe

 *sys_arch_unprotect()functionwhichshouldbeimplementedin

 *sys_arch.c.Ifaparticularportneedsadifferentimplementation,then

 *thismacromaybedefinedinsys_arch.h

 */

#defineSYS_ARCH_UNPROTECT(lev)sys_arch_unprotect(lev)

sys_prot_tsys_arch_protect(void);

voidsys_arch_unprotect(sys_prot_tpval);

 

#else

 

#defineSYS_ARCH_DECL_PROTECT(lev)

#defineSYS_ARCH_PROTECT(lev)

#defineSYS_ARCH_UNPROTECT(lev)

 

#endif/*SYS_LIGHTWEIGHT_PROT*/

 

#endif/*SYS_ARCH_PROTECT*/

  

LWIP_COMPAT_MUTEX

定义此宏表示用信号量来代替mutex。

 

 

Init.c

不定义NO_SYS和“#defineNO_SYS 0”的效果是一样的。

 

下面这些宏对代码有影响:

LWIP_SOCKET

LWIP_ARP

LWIP_RAW

LWIP_UDP

LWIP_TCP

LWIP_SNMP

LWIP_AUTOIP

LWIP_IGMP

LWIP_DNS

LWIP_TIMERS

 

 

void

lwip_init(void)

{

 /*Sanitycheckuser-configurablevalues*/

 lwip_sanity_check();

 

 /*Modulesinitialization*/

 stats_init();

#if!

NO_SYS

 sys_init();

#endif/*!

NO_SYS*/

 mem_init();

 memp_init();

 pbuf_init();

 netif_init();

#ifLWIP_SOCKET

 lwip_socket_init();

#endif/*LWIP_SOCKET*/

 ip_init();

#ifLWIP_ARP

 etharp_init();

#endif/*LWIP_ARP*/

#ifLWIP_RAW

 raw_init();

#endif/*LWIP_RAW*/

#ifLWIP_UDP

 udp_init();

#endif/*LWIP_UDP*/

#ifLWIP_TCP

 tcp_init();

#endif/*LWIP_TCP*/

#ifLWIP_SNMP

 snmp_init();

#endif/*LWIP_SNMP*/

#ifLWIP_AUTOIP

 autoip_init();

#endif/*LWIP_AUTOIP*/

#ifLWIP_IGMP

 igmp_init();

#endif/*LWIP_IGMP*/

#ifLWIP_DNS

 dns_init();

#endif/*LWIP_DNS*/

 

#ifLWIP_TIMERS

 sys_timeouts_init();

#endif/*LWIP_TIMERS*/

}

 

 

netif_add函数

它添加一个网络接口到lwip,一个网卡应该是一个网络接口。

本地回环也是一个网络接口,它已经在tcpip_init中的lwip_init调用netif_init被添加。

/**

 *AddanetworkinterfacetothelistoflwIPnetifs.

 *

 *@paramnetifapre-allocatednetifstructure

 *@paramipaddrIPaddressforthenewnetif

 *@paramnetmasknetworkmaskforthenewnetif

 *@paramgwdefaultgatewayIPaddressforthenewnetif

 *@paramstateopaquedatapassedtothenewnetif

 *@paraminitcallbackfunctionthatinitializestheinterface

 *@paraminputcallbackfunctionthatiscalledtopass

 *ingresspacketsupintheprotocollayerstack.

 *

 *@returnnetif,orNULLiffailed.

 */

structnetif*

netif_add(structnetif*netif,ip_addr_t*ipaddr,ip_addr_t*netmask,

 ip_addr_t*gw,void*state,netif_init_fninit,netif_input_fninput)

 

 

 

 

Struct net_if

在初始化用netif_add添加到lwip中。

 

/**GenericdatastructureusedforalllwIPnetworkinterfaces.

 * Thefollowingfieldsshouldbefilledinbytheinitialization

 * functionforthedevicedriver:

hwaddr_len,hwaddr[],mtu,flags*/

structnetif{

 /**pointertonextinlinkedlist*/

 structnetif*next;

 

 /**IPaddressconfigurationinnetworkbyteorder*/

 ip_addr_tip_addr;

 ip_addr_tnetmask;

 ip_addr_tgw;

 

 /**Thisfunctioniscalledbythenetworkdevicedriver

  * topassapacketuptheTCP/IPstack.*/

 netif_input_fninput;     // 网卡数据接收函数,自定义设置

 /**ThisfunctioniscalledbytheIPmodulewhenitwants

  * tosendapacketontheinterface.Thisfunctiontypically

  * firstresolvesthehardwareaddress,thensendsthepacket.*/

 netif_output_fnoutput;  //发送无连接的数据包,如广播包,多播包,最终还是调用下面的linkoutput函数。

固定设置为etharp_output。

 /**ThisfunctioniscalledbytheARPmodulewhenitwants

  * tosendapacketontheinterface.Thisfunctionoutputs

  * thepbufas-isonthelinkmedium.*/

 netif_linkoutput_fnlinkoutput;  //发送有连接的数据包,已经包含MAC,类型等数据。

#ifLWIP_NETIF_STATUS_CALLBACK

 /**Thisfunctioniscalledwhenthenetifstateissettoupordown

  */

 netif_status_callback_fnstatus_callback;

#endif/*LWIP_NETIF_STATUS_CALLBACK*/

#ifLWIP_NETIF_LINK_CALLBACK

 /**Thisfunctioniscalledwhenthenetiflinkissettoupordown

  */

 netif_status_callback_fnlink_callback;

#endif/*LWIP_NETIF_LINK_CALLBACK*/

 /**Thisfieldcanbesetbythedevicedriverandcouldpoint

  * tostateinformationforthedevice.*/

 void*state;  //一般设置为网卡的私有数据,如netif->state=ethernetif;

#ifLWIP_DHCP

 /**theDHCPclientstateinformationforthisnetif*/

 structdhcp*dhcp;

#endif/*LWIP_DHCP*/

#ifLWIP_AUTOIP

 /**theAutoIPclientstateinformationforthisnetif*/

 structautoip*autoip;

#endif

#ifLWIP_NETIF_HOSTNAME

 /*thehostnameforthisnetif,NULLisavalidvalue*/

 char* hostname;

#endif/*LWIP_NETIF_HOSTNAME*/

 /**maximumtransferunit(inbytes)*/

 u16_tmtu;

 /**numberofbytesusedinhwaddr*/

 u8_thwaddr_len;

 /**linklevelhardwareaddressofthisinterface*/

 u8_thwaddr[NETIF_MAX_HWADDR_LEN];

 /**flags(seeNETIF_FLAG_above)*/

 u8_tflags;

 /**descriptiveabbreviation*/

 charname[2];

 /**numberofthisinterface*/

 u8_tnum;

#ifLWIP_SNMP

 /**linktype(from"snmp_ifType"enumfromsnmp.h)*/

 u8_tlink_type;

 /**(estimate)linkspeed*/

 u32_tlink_speed;

 /**timestampatlastchangemade(up/down)*/

 u32_tts;

 /**counters*/

 u32_tifinoctets;

 u32_tifinucastpkts;

 u32_tifinnucastpkts;

 u32_tifindiscards;

 u32_tifoutoctets;

 u32_tifoutucastpkts;

 u32_tifoutnucastpkts;

 u32_tifoutdiscards;

#endif/*LWIP_SNMP*/

#ifLWIP_IGMP

 /**Thisfunctioncouldbecalledtoaddordeleteaentryinthemulticast

     filtertableoftheethernetMAC.*/

 netif_igmp_mac_filter_fnigmp_mac_filter;

#endif/*LWIP_IGMP*/

#ifLWIP_NETIF_HWADDRHINT

 u8_t*addr_hint;

#endif/*LWIP_NETIF_HWADDRHINT*/

#ifENABLE_LOOPBACK

 /*Listofpacketstobequeuedforourselves.*/

 structpbuf*loop_first;

 structpbuf*loop_last;

#ifLWIP_LOOPBACK_MAX_PBUFS

 u16_tloop_cnt_current;

#endif/*LWIP_LOOPBACK_MAX_PBUFS*/

#endif/*ENABLE_LOOPBACK*/

};

 

 

 

structpbuf

  一个网络包可能由多个pbuf组成,字段tot_len指定这个网络包的大小,字段len是当前pbuf包含数据的大小。

判断一个网络包的最后一个包不能以next字段等于空来判断,它可能不为空,下一个pbuf为下一个网络包的内容。

应该计算tot_len来判断一个包的结束。

structpbuf{

 /**nextpbufinsinglylinkedpbufchain*/

 structpbuf*next;  //下一个pbuf

 

 /**pointertotheactualdatainthebuffer*/

 void*payload;   // 当前结构数据内容

 

 /**

  *totallengthofthisbufferandallnextbuffersinchain

  *belongingtothesamepacket.

  *

  *Fornon-queuepacketchainsthisistheinvariant:

  *p->tot_len==p->len+(p->next?

p->next->tot_len:

0)

  */

 u16_ttot_len;

 

 /**lengthofthisbuffer*/

 u16_tlen;

 

 /**pbuf_typeasu8_tinsteadofenumtosavespace*/

 u8_t/*pbuf_type*/type;

 

 /**miscflags*/

 u8_tflags;

 

 /**

  *thereferencecountalwaysequalsthenumberofpointers

  *thatrefertothispbuf.Thiscanbepointersfromanapplication,

  *thestackitself,orpbuf->nextpointersfromachain.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1