TCPIP协议栈lwip的移植Word版.docx
- 文档编号:8452011
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:30
- 大小:25.29KB
TCPIP协议栈lwip的移植Word版.docx
《TCPIP协议栈lwip的移植Word版.docx》由会员分享,可在线阅读,更多相关《TCPIP协议栈lwip的移植Word版.docx(30页珍藏版)》请在冰豆网上搜索。
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.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- TCPIP 协议 lwip 移植 Word