微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 一种嵌入式IPv4/IPv6双协议栈的实现

一种嵌入式IPv4/IPv6双协议栈的实现

时间:04-13 来源:互联网 点击:

1引言

随着嵌入式系统与网络的日益结合,在嵌入式系统中引入TCP/IP协议栈,以支持嵌入式设备接入网络,成为嵌入式领域重要的研究方向。并且随着 Internet技术的迅猛发展和规模的不断扩大,现行的Internet协议IPv4在地址空间、端到端的IP连接、服务质量和网络安全等方面暴露出了不足,极大地限制了IP网络的进一步发展。而IPv6所提供的巨大地址空间和网络安全等因素已经使其成为下一代因特网IP协议,为了能够支持IPv6的应用,并且考虑到从IPv4到IPv6仍然需要一个过渡期,本文实现了一种基于实时操作系统的IPv4/IPv6双协议栈结构。

2协议栈的设计要点

2.1平台无关性

本文所设计的TCP/IP双协议栈,要求不能局限于特定的硬件环境和软件系统。因此,本协议栈的实现采用将所有的TCP/IP协议都驻留在一个进程当中,协议栈模块与操作系统内核分开。通过定义一个操作系统模拟层实现平台无关性。操作系统模拟层屏蔽硬件上的差异和获取操作系统提供统一的接口,如时钟、过程同步以及信息传递机制等。对于特定的嵌入式操作系统,直接对操作系统模拟层相应部分进行修改,以符合具体的要求。操作系统模拟层主要包括下面两个部分:

⑴与处理器和编译器有关

对不同微处理器的BYTE_ORDER存储系统定义;对不同编译器的数据类型长度的定义;与CPU或编译器相关的内容的定义。

⑵与操作系统相关

协议栈进程与应用程序进程之间的同步与通讯,需要对信号量sys_sem_t、消息队列sys_mbox_t和时钟函数进行定义和操作。

2.2协议栈的裁减

标准的TCP/IP协议栈功能复杂,代码量大,且需大量的存储器资源。为了满足嵌入式应用,必须对RFC定义的协议栈进行裁减[1]。本协议栈的实现作了如下裁减:

⑴IP模块:不支持数据分片,不支持数据包转发,不支持IPv6移动功能,不支持部分IPv6的扩展报头。

⑵ICMPv6模块:支持信息报文中的请求和应答报文,支持错误报文中的目的不可达和超时报文。

⑶邻居发现模块:支持地址解析、重复性探测,省略了路由功能。

⑷TCP模块:支持多个连接,简化滑动窗口,实现快速重传、慢启动与拥塞避免算法的TCP可靠性机制;约减掉半关闭,紧急指针,大部分TCP选项等。

协议栈的层次结构如图1所示。采用独立于网络层的方式,IPv4协议和IPv6协议分开实现,条理清楚,易于裁减,同时不会增加太多代码空间。

上层应用(HTTP)
TCP
ICMPv4ICMPv6
ARPIPv4IPv6

网络驱动

3协议栈的实现

3.1内存管理

内存管理主要是针对协议栈内部缓冲区的管理。为了胜任任意大小报文的处理,并且能够达到比较高的处理效率,在这里定义了两种缓冲区实现机制:固定长度缓冲区(pbuf_pool)和变长度缓冲区(pbuf_ram)。pbuf_pool主要适合于网络设备驱动,存放从网卡接收的数据。 pbuf_ram根据数据的大小动态的分配缓冲区,如协议的报头空间。

在这里对存储空间的申请做了一定改进。由于发送数据时很难确定各层协议头部需要多大的内存空间,特别是IPv6报文可以包含若干个扩展头,所以只申请基本头部的内存空间,在使用中动态调整的可能性就会很大,使得系统的效率降低。在这里提出了一种优化方法,根据局部性原理,通常情况下一个连接在局部时间范围内需要网络层提供相同功能的概率非常大,所以在该连接的TCP_PCB控制块中增加一个变量num,用于记录上次通信时IPv6协议头所使用的字节数,并且此变量可以被网络层的函数进行修改。当传输层下次申请pbuf时,就参考这个值。如果所需的存储空间比此值大,就需重新申请能满足要求的存储空间,同时修改num的值,并作为下一次申请的参考。

3.2网络接口的实现

网络接口层在设计上主要考虑下面几个目标:⑴向协议层提供一个统一的网络通信接口,能够将上层协议模块与具体的网络接口硬件隔离开来,以利于向不同操作系统的移植;⑵支持一个网络接口配置多个IP地址的功能,因为IPv6一个接口的IP地址包括本地链路、本地站点和全局三类地址;⑶支持多播报文的收发,提供动态的多播IP与多播MAC地址的映射服务;⑷提供较好的通信性能等。

针对上述目标,设计了如下的网络接口控制结构:

struct netif {
struct netif *next; /*指向下一个netif结构的指针*/
netif_ipaddr *iplist; /*指向接口的ip地址链的首指针*/
char name[2]; /*接口名称*/
err_t (* input)(struct pbuf *p, struct netif *); /*接口输入函数指针*/
err_t (* output)(struct netif *, struct pbuf *p,netif_addr *); /*接口输出函数指针*/
err_t (* linkoutput)(struct netif *, struct pbuf *p); /*链路层输出函数指针*/
void *state; /*指向接口的状态信息*/
mac_addr netifmacaddr; /*接口的MAC地址*/
netif_multi *multilist; /*本接口的MAC多播地址链首指针*/
┊ /*省略了部分信息 */
};

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top