ARM-Linux环境下 UDP协议的通信应用研究
摘要:进行 UDP协议通信时,发送端和接收端的状态是相对独立的,发送端不与接收端建
立连接,而是不停向接收端发送,为了确保不丢失报文,上位机采取了按固定次数重发相
同内容报文的机制。这种机制虽然可以有效确保报文不丢失,但大量冗余数据报被发送,
网络资源利用率不高。显然重发次数越多,冗余数据报越多,效率越低。要想有效保证数
据报准确发送的同时又不产生过多冗余数据报,那么重复发送的次数的确定就成为问题的
关键。以下给出一种确定上位机重发次数的方法。
关键词:ARM;Linux;交叉编译环境;UDP协议;重发机制;重发次数
中图分类号:TP393文献标识码:A文章编号:1009-3044(2011)13-3001-03
The Application Research of Communicating Based on ARM-Linux Environment
and UDP-Protocol
CUI Hao, SHAO Ping-fan
(Wuhan University of Science and Technology, Wuhan 430000, China)
Abstract: The sender and recEiver are relatively independent when
communicating under UDP- protocol, the sender resending messages to receiver
times instead of creating a connection. A resend-mechanism that the key-
messages were send by upper computer in fixed times, was used in order to
ensuring not to lost key-message. Although the resend-mechanism can ensure
that the key-message wouldn’t be lose anyway, but abundant of redundancy
messages were send through the network device lead to inefficency, obviously
more resend-times more inefficency. So, how to determine the resend-times
become the crucial to improve the efficiency while ensuring the messages were
send accurately. A method of determining the resend-times will be given as
following.
Key words: ARM; Linux; crossing compile evironment; UDP-protocol; resend
mechanism; resend Times
UDP协议以其高效性和应用的简单,被广泛运用于嵌入式网络开发中。由于 UDP协议
的应用简单,在嵌入式设备开发过程中,网络资源的利用率并不高。以下将介绍一个 UDP
具体项目实验过程,描述 ARM-Linux环境的软硬件环境构建过程,并对 UDP协议下一种重
发模式中上位机的重发次数的确定提出一种可行的方法。
1 研究背景
随着嵌入式技术的快速发展,嵌入式设备已经在许多领域取代了传统的微型机设备。
本文的选题主要来自于实习期间承接的一项改造项目:某院校特长生评分系统的改造。项
目改造目的有:1) 保留原上位机。2) 改用手持式客户端进行显示及评分操作。3)保留原
有网络设备。针对要求,我们使用 S3C2440作为硬件平台,移植 Linux操作系统,并在
ARM-Linux环境下研究了 UDP协议的通信过程,进行了上位机与嵌入式系统的 UDP协议通
信实验及分析,并给出一种重发机制中的发送次数求法。
2 硬件平台介绍
S3C2440处理速度达到了 400MHZ,具有较高的性价比。为了提高开发效率,我们采用
公司自行研制开发的 ET-S3C2440开发板。
ET-S3C2440开发板简介
ET-S3C2440是公司自行开发的一款 ARM9架构的实验开发板,其结构框图如图 1。
核心板的主要器件有:32MB×2片 SDRAM,64MB NORFLASH,512MB NANDFLASH。设计了
启动方式可选,通过开关选择从 Nandflash或 Norflash启动。
实验相关电路说明
底板电路主要功能是输入输出以及网络通讯功能。按键输入部分采用扫描方式获得输
入,用一个单向地址锁存器和一个双向地址锁存器与地址总线相连,可以通过扫描地址来
获得按键输入。LCD采用三星的 寸 TFT屏作为显示输出设备。网卡芯片选用的是与原
设备匹配的 10M 的 CS8900A,关于 CS8900A与 S3C2440的硬件连接,有众多资源可供参
考,本文不再赘述。
3 系统软件平台的构建
硬件平台搭建完毕后要将操作系统和应用程序在硬件平台上运行起来。以下是对嵌入
式 Linux操作系统移植的过程。
交叉编译环境的构建
Linux 版本的内核可以登录到 下载。本文选择的是 arm-
工具链(
在宿主机上进入 Linux系统,切换当前目录到工具链所在目录,新建一个 arm目录保
存解压后的文件(mkdir /user/local/arm)并将 解压到这个目录中
(tar jxvf –C /user/local/arm)。然后将环境变量$PATH修改一
下,让$PATH中包含有 arm-linux-gcc所在的目录(编辑/etc/profile 添加语句”export
PATH=/user/local/arm/ reboot一下,这样交叉编译环境就构
建好了。
BOOTLOADER的移植
vivi是一款相当成熟和相对简单的常用 bootloader,我们以 vivi为移植原型,将
S3C2440所有 IO端口寄存器定义添加到头文件 ,删除部分硬件平台使用不到
的代码,最后将修改过的 vivi制作成镜像烧录到 flash中。[1]
Linux内核移植
获取 源代码并解压后,首先修改内核源代码所在目录中的
Makefile,将系统架构修改为 Arm(ARCH ?=arm ),交叉编译工具修改为 arm-linux-gcc
(CROSS_COMPILE ?=arm-linux-),修改输入时钟(arch/arm/mach-s3c2440/mach-
中的函数 static void __init smdk2440_map_io中,修改
s3c24xx_init_clocks(12000000)此处所用晶振为 12M)。修改 machine名称(在
arch/arm/mach-s3c2440/文件中的函数 MACHINE_START( ),修改为
MACHINE_START(S3C2440, “自定义机器名”),修改 NANDflash分区信息
(arch/arm/plat-s3c24xx/结构体 static struct mtd_partition
smdk_default_nand_part[]中保存的是 nandflah的分区信息,将其修改为当前使用的分
区信息),然后修改 nandflash的匹配时间(3c2410_platform_nand_smdk_nand_info
smdk_nand_info ={})
上述内核源代码修改完成后,还需要对一些设备的驱动进行修改。本文使用的 NEC 寸
320×240液晶屏,硬件平台使用 GPG4脚进行背光控制,需要修改 LCD背光
(/arch/arm/mach-s3c2440/中 static void __init
smdk2440_machine_init(void),将函数中的 GPIO口配置为 GPG4)。关于 CS8900A网卡的
驱动移植,相关资源很丰富,本文也不再赘述。
本实验中 nandflash采用的是 yaffs2文件系统,所以打 yaffs2文件系统补丁,压缩
包为 。
至此,Linux的内核源代码修改工作完成了,下面还需要利用 Makefile,进行内核配
置。
在 Linux 内核目录下首先 make s3c2410_defconfig使用 2410的配置模板
来配置 2440;然后 make menuconfig,这时我们可以在图形化界面中,空格键可改变各个
配置选项的被选中状态,根据需要进行配置即可。配置完成后保存好配置,最后进行内核
的编译(make dep 建立文件间依赖 make clean 清除编译残留文件 make zImage 生成内核
压缩镜像文件)。
编译过程完成后会在内核目录 arch/arm/boot/下生成 zImage内核映像文件,将这个
镜像文件烧录到 flash中,调试检验,经上述修改后的内核工作运行正常。
根文件系统的制作
根文件系统是使用 来制作完成。下载 busybox并解压完成后,修改
Makefile中的架构为 ARM架构,编译工具为 arm-linux-gcc( ARCH ?=arm;
CROSS_COMPILE ?=arm-linux-),然后 Make menuconfig,通过图形界面对 busybox进行配
置,然后对 busybox进行编译(make CONFIG_PREFIX=/opt/studyarm/rootfs install),
在目标目录下会生成目录 bin、sbin、usr和文件 linuxrc的内容。
基本目录结构生成后,应该在目标目录下建立一些未生成的必要的系统目录如
dev、etc、lib等,并通过 chmod命令改变目录权限为可写。再将一些必要的动态链接库
和静态库拷贝到 lib下,然后在 dev目录下创建设备节点,最后创建该嵌入式 Linux系统
的初始化配置文件(包括设备列表文件、口令、网络分组组名、HOSTNAME主机
名、etc/inittab初始化表单、etc/profile环境变量配置文件、用于系统初始化的.bash
脚本文件等)。[2]由于本实验需对网络编程,要求自动初始化 CS8900A网卡芯片的 IP地
址、网关、子网掩码等,所以在开机自启动脚本中加入 ifconfig语句,使得开机时自动
配置网卡参数。
根文件系统构建完成后,使用 yaffs2文件系统制作工具 ,通过命
令 mkyaffs2image rootfs 生成根文件系统镜像,然后将镜像烧写入 flash
中。
4 ARM-Linux环境下的 UDP协议通信实验
经过上述硬件设计和操作系统移植过程,本文所使用到的实验环境已经构建完毕,经
反复调试修改,嵌入式 Linux操作系统在平台下运行正常,于是进行 UDP协议通信实验。
UDP协议套接字编程基础
UDP是一个面向数据报和无连接的简单传输层协议,它不像 TCP那样通过握手过程建
立服务器与客户端的连接才可以工作。在网络通信质量较好的情况下,UDP体现出高效
率,这适合于传送少量报文的应用。[3] linux系统是通过套接字结构来进行网络编程
的,应用程序通过对套接字的几个函数调用,会返回一个用于通信的套接字描述符,而
Linux应用程序在进行任何形式的 I/O操作时,程序实际上是在读写一个文件描述符。[4]
因此 Linux下的套接字编程,可以看成是对普通文件描述符的操作,这些操作与被使用的
硬件平台无关,这是 linux设备无关性的优点。UDP协议的通信模型如图 3所示。
在上述流程中,客户端所收到的报文被存储在缓冲区中,recvfrom()函数返回了报文
存储缓冲区的首地址,我们可以很方便地对这个首地址进行数组操作,从而实现对报文的
解码。
上位机报文结构及重发机制分析
根据项目要求,上位机软件依然保留,我们使用协议嗅探工具对上位机发送的报文进
行了嗅探,得到了上位机报文的结构如表 1所示。
表 1 上位机报文结构
上位机发出的每条报文由 32个字节组成,第 0位为版本信息。第 1……12位为比赛
信息和运动员教练信息,是报文的关键信息部分,13……22位为服务器端和客户端的 IP
地址及端口号信息,23位是上位机对客户端的操作指令代码,24位是相关重发机制的代
码,30和 31两位是 CheckSum,用来保证数据传输的正确。上位机采用的重发机制是一种
上位机按照固定重发次数多次发送同一关键内容报文的机制,其第 24位重发机制位被分
为高 4位和低 4位两部分,高四位的内容是当前发送的报文的索引号,每次发送一条新内
容的报文时索引号自增 1,索引号的取值范围在 0x00—0xFF范围内循环自增。低四位是重
发编号,表示同一索引号的报文正在被第几次重发,固定的重发次数由上位机初始化时设
定。
嵌入式客户端的实验程序设计
针对报文结构,我们对接收端编写实验程序代码,代码的主要功能是从上位机接收报
文,将计算出的 CheckSum校验和与收到的校验和对比判断报文是否正确,然后从正确报
文中取出主要信息并按照报文中的上位机指令码进行输出。其结构流程图如图 3所示。
实验程序经编码、调试后在交叉编译环境中交叉编译,生成 arm-Linux环境下可执行
文件,在目标板上执行。经测试试验程序能够正确接收上位机发来的报文,对报文解码,
并能根据上位机命令对关键信息做输出处理。
对上位机重发次数的研究
进行 UDP协议通信时,发送端和接收端的状态是相对独立的,发送端不与接收端建立
连接,而是不停向接收端发送,为了确保不丢失报文,上位机采取了按固定次数重发相同
内容报文的机制。然而这种机制虽然可以有效确保报文不丢失,但是大量冗余数据报被发
送,网络资源利用率不高。重发次数越多,冗余数据报越多,效率越低。要想有效保证数
据报准确发送的同时又不产生过多冗余数据报,那么重复发送的次数的确定就成为问题的
关键。以下给出一种确定上位机重发次数的方法。
假设当前网络状况下,每次报文发送被丢失的概率为 p,系统允许接收端报文关键内
容丢失概率为 q,那么如何确定以上重发机制中的重发次数 k呢?
特殊情况下若报文重发次数为 2,分别在每条报文重发机制位注明一个索引号和一个
重发编号,发送端发送报文的次序应形如 , , , , ,……其中索引
号相同的报文关键内容相同,重发编号不同代表同一关键内容报文的不同次发送。因此只
有出现连续两次丢失数据报的情况下,报文关键内容才可能丢失。出现连续两次丢失的情
况有 2种,当 , 丢失,此时索引号为 x的报文关键信息将全部丢失。当 ,
(x+1). 1丢失,丢失报文的索引号不同,此时不会发生报文关键信息丢失,因此报文关键
内容丢失的概率 q=p2/2
当报文重发次数为 3,依然在每条报文的重发机制位注明索引号和重发号,发送报文的次
序应为 , , , , , , ,……。只有出现连续 3次丢失数据报的
情况报文关键信息才可能丢失,列出连续 3次丢失报文的情况有 3种,当 , ,
丢失,此时索引号为 x的报文信息全部丢失。当 , ,(x+1).1或 ,
(x+1).1 ,(x+1).2丢失时不影响报文的准确传递。因此此时报文关键内容丢失的概率
q=p3/3。
推广至一般情况易得当报文重发次数为 k时,报文关键内容丢失的概率 q=pk/k,移项
有 kq=pk。于是我们得到求重发次数 k的方法如下:
1) 根据网络状况获得报文丢失概率 p;
2) 根据客户需求取得报文关键内容的允许丢失率范围 q;
3) 分别作出 y=px和 y=qx的图像;
4) 求得两图像的交点的 x坐标,并将 x坐标值取整加一即为所求重发次数 k。
本文实验中,需求方允许报文关键信息丢失概率 q=,我们分别对上位机发送端
和下位机接收端收发的报文进行了统计,在某一固定时间段内,上位机共发送报文 19665
条,接收端接收报文 18636条,传输过程中丢失的报文 19665-18636=1029条,当前网络
环境下的报文丢失率为,即 p=。据此数值分别作出 y=的曲线和 y=
x的曲线,取得两曲线交点 x坐标为 x≈,最后将 x=取整加 1得到 k=3,即上位
机对同一数据报的重发次数应该定为 3次就可保证系统丢失报文的概率低于 。
5 结论与展望
本文从硬件平台搭建、Linux移植以及 UDP协议编程几个方面介绍了 arm-Linux环境
下 UDP协议通信的具体实现,并分析了一种在实际嵌入式项目中常用的上位机数据报重发
机制,最后对这种机制中的重发次数的确定方法给出了求解过程,为后续的具体项目实施
提供了实践依据,也希望为其他应用这种重发机制的嵌入式产品开发者们提供了借鉴。中
国论文联盟
参考文献:
[1] 李伟.基于 ARM9的嵌入式 Linux手持平台的设计与实现[D].武汉:武汉理工大学
硕士学位论文,2009.
[2] 范艳开.基于 ARM的嵌入式 Linux操作系统移植[D].西安:西北工业大学,2005.
[3] 刘畅,彭楚武.Linux下的 UDP协议编程[J].仪表技术,2006(1).
[4] NEil Matthew Richard Linux Programming[M].2nd
Press,2002