基于嵌入式TCP/IP软件体系结构的优化设计与实现
另外,TCP/IP一般采用C语言或者混合汇编,而使用可重入函数和一般指针(generic pointer)使得程序代码增大,运行速度变慢。所以使用函数指针时,应手动重建调用树(Call tree),或将函数指针调用的函数设置为可重入函数,同时使用"指定存储类型"的指针(memory-specific pointer),防止数据包的不必要的拷贝以及优化计算校验和和内存拷贝函数。另外,Reentrant类型的函数比一般函数速度要慢很多,但是某些时候为了程序结构的需要必须使用Reentrant,这就需要在速度和结构之间作一个选择。
嵌入式TCP/IP的实现
TCP/IP的嵌入式实现一般通过以软件方式嵌入到ROM中,然后通过轻网络通讯技术与专用嵌入式网关连接,在嵌入式处理器中运行TCP/IP协议,提供TCP/IP到用户的轻型网络的连接和路由功能。
内存管理方法和无多余数据包拷贝的实现
嵌入式TCP/IP的内存管理可以用链表方法,即根据数据包大小分配相应大小的内存块。如图4所示,链表将内存块链接起来,used字段表示该内存块是否正在使用,pSstart和pEend则表示数据部分有效数据的开始地址和结束地址。
分配时,搜索内存链表找到一个没有分配的比所需空间大的内存块,截取所需的大小。该内存块被截取以后可能还有较多剩余,这时将剩余部分从原内存块中分离出来,成为一个新的内存块,并插入链表。释放时,将used值置为假,如果pNext或者pPre指向的链表单元也是空闲的,则将其和自己合并,以防止内存分片。在协议层之间传送数据包只需传送内存块的起始地址。这种内存管理方法空间浪费小但是运算量相对较大。
整序、重发和窗口控制的实现
对于嵌入式TCP/IP系统,可以使用队列缓存的方式来实现整序、重发和窗口控制。队列的一个元素指向一个数据包,队列的最大长度没有限制。
对于整序,使用ooSeq队列,如果发现接收的TCP包序号并不是期望的,但序号在接收窗口内,此时不能立刻接收这个包也不应丢弃,可先将这个包放入ooSeq队列。当期望TCP包被接收后,再查看ooSeq队列现在是否有TCP包成为了期望的数据包,如果有则将其取出并处理。
对于重发,使用unacked队列,每一个需要被应答的TCP数据包发送以后都要放入unacked队列,等到被应答以后才从队列中删除。TCP重发定时只针对unacked队列第一个TCP包,如果定时超出,重新发送,重发次数超出规定值,则报错。
对于窗口控制,使用unsend队列,如果发现对方的窗口过小无法接收这个数据包,则只发送部分数据,将多余部分放入unsend队列,等待对方发来TCP包通知新的窗口大小时,再次判断是否可以发送。如果在unsend队列不为空的情况下,需要发送的数据包都应插入unsend队列。
嵌入式TCP/IP的性能分析
图5给出了将优化设计后的TCP/IP移植到ARM9处理器、CS8900A网络控制器中,时钟频率为133MHz下,与Internet连接的情况。
系统支持最大发起连接数约为380,最大并发连接率约为170cps。随着呼叫数的增加,平均分组到达也随之增加,导致网络传输数据的增加,从而最大建立时间变长。但最小的建立连接时间基本保持不变,说明系统具有良好的性能。
图6给出了随建立时间变化的接通率。图中存在一个临界点,成功的连接率随着TCP连接尝试数目增加而减少,直至为0,而响应时间也急剧上升,这是由嵌入式处理器的处理能力有限造成的。
结语
本文从实现相应的功能又节省系统资源角度出发,对嵌入式TCP/IP协议簇进行优化设计,可以在各种嵌入式处理器上实现Internet接入。
经过优化设计的嵌入式TCP/IP支持套接字形式的多个TCP连接、支持多个网络设备、支持通过网关发送数据包和数据包转发功能,以及支持TCP包的整序、重发和窗口控制流量控制。实践证明,这种设计方式灵活,能按用户需求实现复杂的功能。
- 基于Linux操作系统下的TCP/IP网络通信研究与应用(01-10)
- 巧解无线路由器不正常工作技巧(02-13)
- 排忧解难 让宽带路由更好“服务”自己 (03-05)
- 网站安全课程:DDOS攻击防御全攻略(03-11)
- TCP/IP基础(03-17)
- IP地址系列知识------IPv4地址和IPv6地址(03-17)