如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
狗拿耗子lwip———狗拿耗子第四篇1、lwip的背景lwip是SwedishInstituteofComputerScience开发的用于嵌入式系统的TCP\IP协议栈,从网上的评论看似乎用的人不少。它的实现是应该参考了BSD的实现,在介绍TCP的时候,大家就会发现,其拥塞控制的实现算法机会与BSD的一模一样。lwip的整个代码写的比YASS2差一截,难以入手介绍,我打算按照TCP的server与client的角度分别走一遍代码。lwip的内核运行在同一个任务中,lwip提供的系统调用通过mailbox与内核进行通信,然后用户阻塞在一个专门的mailbox上,内核完成用户的请求后post该mailbox,用户得以继续执行。有的协议栈的实现却是,每层跑在一个任务中,这样层与层间的相互调用将会引起上下文的切换。更重要的是lwip可以运行在裸机的环境中,即不需要操作系统的支持。这对一些低成本的设备还是很具有吸引力的。lwip的官方网站为http://savannah.nongnu.org/projects/lwip/,目前最新的版本是1.3.0,而本文参考的是1.2.0。2、netconn_new系统调用2.1相关的数据结构enumnetconn_type{NETCONN_TCP,NETCONN_UDP,NETCONN_UDPLITE,NETCONN_UDPNOCHKSUM,NETCONN_RAW};structnetconn{enumnetconn_typetype;enumnetconn_statestate;union{structtcp_pcb*tcp;structudp_pcb*udp;structraw_pcb*raw;}pcb;err_terr;sys_mbox_tmbox;sys_mbox_trecvmbox;sys_mbox_tacceptmbox;sys_sem_tsem;intsocket;u16_trecv_avail;void(*callback)(structnetconn*,enumnetconn_evt,u16_tlen);};1狗拿耗子zstructnetconn用一个union将udp、tcp、raw的pcb包含起来,实现由netconn到不同协议的分发,这是c语言编程的一个常用技巧。zsys_mbox_tmbox,用户阻塞在该mailbox上,内核处理完用户的请求后,post该mailbox,用户继续执行。zsys_mbox_trecvmbox,如其名,用户用该mailbox接收来自内核的数据。zsys_mbox_tacceptmbox,用户调用accept阻塞在该mailbox上,内核接收到来自网络的连接请求并完成三次握手后,post该mailbox。zsys_sem_tsem,系统调用netconn_write发现内核没有足够空间时wait该semaphore,内核在适当的时候会post该semaphore,则操作系统唤醒运行在用户任务的系统调用,再次尝试发送数据。2.2流程structnetconn*netconn_new_with_proto_and_callback(enumnetconn_typet,u16_tproto,void(*callback)(structnetconn*,enumnetconn_evt,u16_tlen)){structnetconn*conn;structapi_msg*msg;conn=memp_malloc(MEMP_NETCONN);......conn->err=ERR_OK;conn->type=t;conn->pcb.tcp=NULL;/*表示没有关联pcb*/if((conn->mbox=sys_mbox_new())==SYS_MBOX_NULL){memp_free(MEMP_NETCONN,conn);returnNULL;}conn->recvmbox=SYS_MBOX_NULL;conn->acceptmbox=SYS_MBOX_NULL;conn->sem=sys_sem_new(0);......conn->state=NETCONN_NONE;conn->socket=0;conn->callback=callback;conn->recv_avail=0;if((msg=memp_malloc(MEMP_API_MSG))==NULL){memp_free(MEMP_NETCONN,conn);returnNULL;}msg->type=A