开篇:润墨网以专业的文秘视角,为您筛选了一篇一种嵌入式TCP/IP协议栈的设计与实现范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!
摘要:结合嵌入式系统的特点对TCP/IP协议进行分析和精简,并且在KeilC51环境下编程实现了该协议子集,为通用TCP/IP协议的精简提供了一种较为简单的思路。
关键词:嵌入式系统;以太网;tcp/ip协议;UDP;ARP
中图分类号:TP393文献标识码:A文章编号:1009-3044(2007)04-10947-03
1 引言
目前,嵌入式系统与网络的结合已经成为嵌入式系统发展过程中所必须要面对的问题之一。嵌入式系统的网络接入一般可以通过RS-232或RS-485等间接接入,也可以通过网络协议直接与网络相互连,其中,直接接入方式正逐步成为嵌入式系统接入网络的主要方式,但是需要精简TCP/IP协议栈的支持。目前使用广泛的通用TCP/IP协议栈所包含的协议内容比较全,但同时也比较复杂。由于硬件平台的差别,这些协议站无法直接应用于嵌入式系统,主要表现在以下三个方面:
(1)嵌入式操作系统都面向特定的领域和需求,嵌入式应用对实时性要求比较高。
(2)多任务操作系统的内存分配是动态的,但是在嵌入式系统中片RAM是静态分配的,用于存放收到的数据包的的空间很有限。
(3)嵌入式系统在程序的具体实现上与通用计算机系统有所不同,主要体现在指针、参数传递、变量和数据结构的定义等方面。
因此,需要通用TCP/IP协议栈的基础上进行精简和改写,以设计出精简、高效的TCP/IP协议子集,以供嵌入式系统接入网络使用。
2 TCP协议分析与简化
通用计算机系统有足够的资源支持,但是嵌入式系统则不同,因为其CPU处理能力和系统存储能力都受到成本限制,充分利用资源、提高系统性价比是开发嵌入式应用的根本特点。
2.1 嵌入式TCP/IP协议栈的特点
嵌入式系统一般都是为了满足某一特定的需求,对网络支持的要求相对比较低,需要什么协议就添加相应的模块,不需使用完整的TCP/IP协议。嵌入式TCP/IP协议栈应具有以下的特点:
(1)代码比较简洁,占用的存储空间尽可能小,尽可能为应用程序节省系统资源。
(2)需要传输的数据量一般比较少,协议的实现代码要有较高的执行效率,具有较高的实时性。
(3)便于裁剪和扩展,对于面向不同应用的嵌入式系统应当根据特点对协议进行简化或扩展,整个协议栈在满足功能需求的前提下尽可能精简。
TCP/IP协议栈具有层次特性,各个协议都有自己的数据格式,每次发送数据都要进行上下层协议的数据交换,进行打包和拆包的过程,在这个过程中如果采用数据拷贝的策略进行数据传递则会大大增加系统开销。在嵌入式系统中,往往无法建立起数据传递的缓冲区,需要采用“零拷贝”技术用传递数据指针的方法来解决各层协议间的数据传递,以提高系统的实时性能。
2.2 TCP/IP协议的精简
TCP/IP是几百种网络协议的集合。通用计算机系统有足够的资源支持通信协议在内核实现,因此完整的TCP/IP协议栈(如图1)能够在数据传输的可靠性和数据流量的控制上做很多工作。
但是对于嵌入式系统来说,其硬件资源十分有限,同时对协议的要求也相对较低,必须对通用的TCP/IP协议进行精简。进行精简的途径有两种:
(1)将无关于系统功能的协议削减掉。即保留必需的协议,而对其它无关协议进行裁剪。
(2)对单独的协议进行简化。例如完整的ARP协议支持以太网、令牌环等网络,但是嵌入式系统可能是面向于某一具体类型网络的,对于其他的部分就可以简化掉。
图1
简化后的协议仍然需要符合规定的标准:在网络接口层,系统需实现ARP应答协议,该协议用于将IP地址映射成以太网MAC地址;在网际层,需要实现IP协议,主要负责IP报文报头的正确性,并且对TCP和ICMP报文实行分流,此外,为了能够测试系统与网络的连接,在网际层还需要实现ICMP协议中的Ping应答协议,主要用于检查网络在传输层是否连通。作为运输层的主要协议,TCP和UDP协议一般都不能缺少,对于具体的应用,一般都至少要实现其中之一。HTTP、FTP等应用层协议一般无需实现。这样简化后,就可以得到图2所示的嵌入式TCP/IP协议栈的结构:
图2 嵌入式TCP/IP协议栈结构
3 各协议的具体实现
本文实现的嵌入式TCP/IP协议运行于以89C51单片机和RTL8019AS网络控制器为核心元件的硬件平台上,协议代码在Keil C51 V7.0环境下编写。在程序的initial文件中提供了相关函数对89C51和RTL8019AS进行了初始参数设置,限于文章篇幅,与具体硬件相关的问题不再作详细说明。
3.1 ARP协议的实现
ARP协议不携带用户的有效数据,报头长度为28字节。在ARP报头中操作码域表明了ARP包是ARP请求还是ARP回答,其值为1时为请求,为2时为应答。目标以太地址为目标节点IP对应的MAC地址,解析前是未知的。发送ARP请求应使用广播方式,网段内的各个主机收到后检查包内的IP地址,如果和本机的IP地址一样则使用单播的方式返回ARP应答,在应答ARP包中源以太地址的域中填入自己的MAC地址。在具体设计时,要考虑到系统解析地址的实时性,如果每次互联都要进行地址解析,则系统的实时性要下降,一般的做法是建立一个ARP地址映射表,存放常用IP地址与MAC地址的映射,这样在解析地址时首先遍历该表,如果目标地址已经被解析过则可以省去解析过程了。解析过程中还需要为ARP缓存中每个新生成条目赋予一个初始生存时间,使用定时器中断,经过某一时间间隔对所有条目进行刷新检测,若发现有条目发生超时,将其从ARP缓存中删除。ARP缓存条目结构设计如下:
typedef struct
{unsigned long ip_addr; //IP地址
unsigned char macaddr[6]; //MAC地址
unsigned char timer; //定时器}
ARP_CACHE; //ARP缓存条目结构
3.2 IP协议及Ping 应答的实现
IP协议是TCP/IP协议族中最为核心的协议。所有的TCP、UDP、ICMP及IGMP包都以IP数据报格式传输。IP报头的标准长度为20字节。在具体项目中由于数据量比较小,可以不考虑数据报分段的问题,即不允许数据报超出IP包的有效载荷。标准以太网帧数据域为1500字节,除去IP头之外还有1480字节可以为上层协议提供有效的数据载荷,应该能够满足数据传送的要求。这样简化可以省去软件处理IP数据分段和重组的开销,可以提高系统数据传输的实时性。IP协议对上一层传下来的报文加上IP首部和IP校验和并发往下一层,同时还要对下一层传上来的报文进行校验和检查,将校验正确的去掉IP首部,送往上一层。
为了便于测试,需要实现PING程序,在收到ICMP的回显请求包后按照格式组装一个ICMP的回显应答包并发送。相关的主要函数有:
void ping_request() //PING请求
void ping_answer() //PING应答
void ping_echo() //PING应答收到后回显
3.3 UDP协议的实现
UDP际上是直接利用IP协议进行数据报的传输,也就是将报文包含在IP数据包中 。UDP的数据传输是无连接,不可靠的,因为它不像TCP那样,为了达到目标,首先要在两点之间建立一个可靠的连接,因此UDP协议无法保证数据可靠性。但UDP协议具有对网络资源开销较小,数据处理速度快的优点,UDP协议属于简单的端到端的数据传输协议,其报头只有8字节,其中源端口表示UDP应用进程的端口号,除了0~1023预定的端口外,其余的都可以使用。具体实现时要完成对应用层传下来的数据包,加上UDP首部和UDP校验和,发往下一层。以及对下一层传上来的数据包,进行校验和检查,若正确去掉UDP首部,提出数据送给应用层。需注意的是,要产生一个伪首部用于UDP数据检验和计算,涉及到的主要函数有:
unsigned char verifyudpcrc(union netcard xdata *pRxdnet) //对ucp头进行校验,错误返回0
void udp_send(union netcard xdata *pTxdnet, unsigned char xdata * psource, unsigned int len) //UDP包发送处理
void udp_recieve(union netcard xdata *pRxdnet)UDP包接收处理
3.4 TCP协议的实现
TCP协议是面向连接的、端对端的可靠通信协议,可分以下几个步骤实现:
(1)建立连接。这一过程就是我们常说的三次握手过程。
(2)验证。采取相应的措施消除传输中的错误,保障传输的可靠性,利用序列号解决通信时重复和失序的问题。
(3)流量控制。设置发送和接收窗口。
TCP协议的功能是为应用层协议提供可靠的面向连接的数据传输服务,是嵌入式应用系统协议栈中最为复杂的协议。在TCP协议实现中,由于请求发起端(客户端)与请求相应端(服务器端)在通信中所处地位不同,相应地两者的中间演变状态也不完全相同。客户端与服务器端在一个TCP连接从正常建立到正常中止分别经历5个和6个状态,相应控制信息均在TCP头部信息的6位控制标记位中得以表示。对于嵌入式系统中TCP协议的实现,应从嵌入式应用的角度出发,尽可能减少冗余状态。程序中需要构造一个TCP_STATUS结构来记录每一个TCP连接的状态信息,其结构如下:
typedef struct
{unsigned long ip_addr; //源IP 地址
unsigned int port; //端口号
unsigned long remo_sequ; //对方序列号
unsigned long local_sequ; //本方序列号
unsigned long old_sequ; //上一次序列号
unsigned long remo_ack; //对方应答号
unsigned char timer; //超时用定时器
unsigned char quiet; //连接活动性
unsigned char state; //当前状态
}TCP_STATUS; //连接状态结构
4 结束语
嵌入式系统的应用非常广泛,解决嵌入式系统的网络接入问题具有十分重要的意义。本文实现的精简TCP/IP协议栈在具体应用中有良好表现,可以满足正常的数据传输。由于设计与实现的过程中将应用层协议全部精简,协议在运行过程中的流量控制能力及协议自身的安全性都有所下降,在对安全性和稳定性要求较高的应用场合(如军事、金融等领域),需要对协议的简化有所斟酌。
参考文献:
[1]罗蕾. 嵌入式实时操作系统及应用开发[M]. 北京:北京航空航天大学出版社. 2005.
[2]徐爱钧,彭秀华. Keil Cx51 V7.0单片机高级语言编程与μVision2应用实践[M]. 北京:电子工业出版社,2004.
[3]程耕国,高厚礼. 基于TCP/IP协议单片机上网的设计与实现[J]. 武汉科技大学学报(自然科学版),2004,(2).
[4]田夏利,汪继军,薛胜军. 嵌入式Internet中UDP协议的实现[J]. 计算机与数字工程,2006,(2).
[5]er. 用TCPIP进行网际互联[M]. 北京:电子工业出版社,2000.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。