毕业设计论文(修改).doc

DZ054精简的ARM-TCPIP接口的开发和研究

收藏

压缩包内文档预览:(预览前20页/共59页)
预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图
编号:149922598    类型:共享资源    大小:7.73MB    格式:RAR    上传时间:2021-10-10 上传人:好资料QQ****51605 IP属地:江苏
20
积分
关 键 词:
DZ054 精简 ARM TCPIP 接口 开发 研究
资源描述:
DZ054精简的ARM-TCPIP接口的开发和研究,DZ054,精简,ARM,TCPIP,接口,开发,研究
内容简介:
西南科技大学毕业设计精简的ARM-TCP/IP接口的开发和研究罗小民信息工程学院 621010摘要随着计算机的发展,网络技术应用逐步广泛,人们希望能够通过计算机和嵌入式设备通信并进行控制。本课题的设计目的就是通过一个转接装置,能实现串口和以太网接口之间的通信。本次试验主要是设计ZNE-100模块的开发板,完成RS-232串口电路及RS-485串口电路设计以及以太网接口RJ-45的电路设计,熟悉ZNE-100模块的功能及各个管脚的信号。然后用VC为软件开发平台,开发适用于工程控制的协议栈,进而嵌入以ARM为内核的协议栈控制器,尝试用现有的ARM芯片(LPC2114)代替ZNE-100模块,实现单一芯片的TCP/IP功能化。关键词:嵌入式 以太网 RS-232 RS-485 协议栈 ARM TCP/IPLuo xiao-minSWUST School of information engineering 621010AbstractKeywords: Ethernet RS-232 RS-485 协议栈 ARM TCP/IP目 录1. 绪论1.1 项目意义1.2 项目的背景1.3 课题目标1.4 课题关键问题1.5 TCP/IP网络在工业控制中的优势2实验方案3. 实验硬件设备3.1 ZNE-100转换模块(1) ZNE-100模块功能特点(2) ZNE-100模块产品特性(3) 硬件电路3.2 ARM芯片微处理器(1) LPC2114特性(2) 结构概述 4. TCP/IP协议下的网络通信原理4.1 网络硬件(1)服务器和工作站(2) 网络适配器(网卡)(3)传输介质(网线)4.2 网络软件(1)协议分层(2)各层的设计问题(3)接口和服务(4)面向连接的服务和无连接的服务4.3 TCP/IP参考模型5串口通信5.1串口通信的基本原理5.2串口信号线的接法5.3 串行接口标准(1)RS-232串行接口标准(2) RS-485串行接口标准6. ARM-TCP/IP接口硬件电路设计6.1 5V DC供电电源电路设计6.2 串口接口电路设计(1)RS-485接口电路(2)RS-232 接口电路6.3 I/O线信号电路设计6.4 复位电路设计6.5 以太网接口电路设计6.6 ZNE-100模块的管脚电路设计7调试8.总结致谢参考文献附录1. 绪论1.1 项目意义随着INTERNET的飞速发展,网络应用越来越广泛,对各种工业控制设备的网络功能要求也越来越高。当前的要求是希望工业控制设备能够支持TCP/IP以及其它INTERNET协议,从而能够通过用户熟悉的浏览器查看设备状态、设置设备参数,或者将设备采集到的数据通过网络传送到WINDOWS或UNIX/LINUX服务器上的数据库中。这就要求工控系统必须具备两方面的功能:一是要在现场完成复杂的测控任务,因为通常一些任务都具有一定的实时性要求;二是要求测控系统能够与某一类型的控制网相连,以实现远程监控。在目前应用的大多数测控系统中,嵌入式系统的硬件采用的是8/16位单片机;软件多采用汇编语言编程,由于这些程序仅包含一些简单的循环处理控制流程。因此,单片机与单片机或上位机之间的通信通常通过RS232、RS485来组网。这些网络存在通信速度慢、联网功能差、开发困难等问题。工业以太网已逐步完善,在工业控制领域获得越来越多的应用。工业以太网使用的是TCP/IP协议,因而便于联网,并具有高速控制网络的优点。精简的ARM-TCP/IP接口的开发和研究可以提供有效的手段,为工业级的串口通信转换为TCP通信开发一种低成本低功耗,高效率高可靠性的介入转换设备。1.2 项目的背景TCP/IP作为一种成熟的通信体制和通信系统已经成功地在世界上建立了大部分的INTERNET连接,越来越多的设备和系统需要使用TCP/IP的方式接入以太网。而且大量的旧设备如老的数字化设备:数控机床、模拟或数字方式的智能传感器、旧的图形工作站等等都需要作为一个子部分或子系统接入以太网。而全部以新的带TCP/IP以太网接入的换代设备来进行全部取代也是不可行的,这样做会造成资源极大的浪费。所以研究一种精简的、模块化的智能TCP/IP接口是对这一问题的比较合适的解决。而ARM芯片的推出则为这种智能接口提供了良好的硬件基础。以PHILIP公司的LPC2114ARM7芯片结合TCP/IP的控制芯片(如REALTALK8139)制作一块智能机板,整和标准的RS232串口,是我的整个毕业设计的思路。串口通信技术在数据通信中的应用极为广泛。但是,其固有的通信距离小、抗干扰能力差等缺点使其无法满足对实时性要求较高的现代工业控制。随着近年来网络技术和以ARM为代表的32位处理器的发展,通过网络实现ARM与PC机高速、可靠的通信已成为可能。ARM的技术优势(比较NIOS) :ARM公司不做芯片,把所有的精力都方在核心的制定上,做到了“专精”;熟悉ARM体系结构的人都知道,ARM内核分级明确,NIOS的内核从性能上讲相当于ARM9。NOIS是由altera公司主推的MCU内核,由altera负责全部的设计制造,没有其他重量级厂商和公司的有利支持;与此相反,ARM公司获得了上百家公司的支持,并且拥有二十多家超级牛x的公司的支持,比如微软、TI、intel、philips三星、ATMEL、circus logic、夏普等,这些大公司依靠自己雄厚的技术背景,基于ARM的内核做得非常的稳定。现在国内基于arm7/9的廉价而且性能优异的开发板狂多,而且这些公司都有一定的实力基础,确保了板子的可学习性。相反,虽然altera宣称自己的NIOS可以被用于几乎所有主流的FPGA板子上,但却又推出了天价(对我们学生而言)NIOS开发套件,这是不是有点“此地无银三百两”的嫌疑?于ARM9所宣称的主频200MHz,处理速度220MIPS,各个厂商都已经臻于完美,做到了极限,然而,对于NIOS所给出的主频180MHZ,处理速度600MIPS试问众位兄弟,有几人能够实现?对于处理能力,专家说NIOS处理速度完全可以凌驾于ARM10,暂且不说理论与现实的差别,试问DSP是干什么的?哪个拼得过处理速度达几十亿条的DSP?如果需要另外接DSP来实现海量数据处理功能,那么NIOS的软硬一体化还有优势吗?讲到性能比拼时,NIOS的拥护者最后的杀手理由是用双NIOS或者多NIOS来与硬核处理器抗衡,然而真正做出完美的双核NIOS的试问又有几人?虽然从理论上讲,自由的NIOS核心允许自主地制定许多外设,但是必须看到,真正地应用时,我们往往不需要很多地接口功能。ATMEL、三星等厂家不是白痴,他们确定硬核ARM的端口,自然有他们的道理,也就是说已经能够满足绝大部分需要了;从另一个角度上讲,实际NIOS设计时,几乎所有人都要受到FPGA管脚的制约,甚至因为管脚不够而限制了一些最基本的功能(比如以太网),试问NIOS的“自由”何在?“制造N多端口”的荣耀与满足何在?FPGA是数字型芯片,如果需要用到模拟信号,必须外接ADC、DAC等数据采集卡,而ARM芯片厂商早早地解决了这个问题,比如PHILIPS LPC2138甚至拥有双8路(也就是16路)10位的ADC加上2路DAC!(你这一段写的很不好,语句不通加上有很多的口语,这个是论文,不是写小说。从内容上说,你只需要从8位,16位还有PC CPU这些产品的性能和应用性上做比较就行了,不用专门找个NIOS(NIOS是一个软件内核)来比较。建议你重写)1.3 课题目标(a)提出对ARM控制器系统的TCP/IP改造方案 (b)设计实现所提出方案的硬件体系(c)设计ARM控制程序,能够将通用的2/16进制数据转换成标准的TCP/IP数据报,通过网络传输(d)联调通过1.4 课题关键问题(1) ARM控制器的硬件体系 (2) 对TCP/IP协议的解析和网卡设备的底层解析 (3) 设计ARM-TCP/IP系统1.5 TCP/IP网络在工业控制中的优势以太网是当今应用最为普遍的局域网技术。早在七十年代,Xerox、Digital和Intel三家公司就开始联合开发用“以太”命名的网络技术,于1981年推出EtherNet协议,1982年推出修改版DIX Ethernet V2。在DIX协议发展的同时,美国电气和电子工程师学会IEEE 802委员会致力于制定开放式网络结构标准的制定。1983年IEEE 802委员会以DIX Ethemet V2为基础制定了IEEE 8023标准。尽管DIX Ethernet V2与IEEE8023在帧定义的细节上有所不同,但由于两者在介质访问控制技术上,即标准采用的核心技术上相同,所以通常人们就把IEEE8023看作是以太网标准了。在网络的层次化结构参考模型中,最低两层是数据链路层(Layer 2)(包括MAC子层)和物理层(Layer 1)。IEEE8023就是关于物理层和媒介访问层(MAC层)的协议标准,标题为”CSMACD(载波监听多路访问冲突检测)MAC(媒介访问控制)和物理层规范”。CSMACD也称为LWT(Litsen While Talk,译为“边听边说”)。网上所有节点具有同等的访问权限。如果节点要发送数据,它必须先听一下传输媒介(线)上是否有其他节点已在传送数据,如果没有,它就可以开始发送数据。如果它听到其他节点,已在传送,它必须等待线上空闲自己才可发送。以太网上数据传送的基本单位形式是帧。以太帧除了包括所传送的内容数据的字节外,还包括源MAC地址字节和目的MAC地址字节以及其他辅助字节。MAC地址是由IEEE8023标准委员会分配给网卡制造商的。每张网卡出厂时都被赋予一个全球唯一的、共6个字节的MAC地址。以太网上的节点在监听线上的数据传输时,根据目的MAC地址是否与本节点网卡的MAC地址相符决定是否收下数据帧或将其丢弃。如果一个以上节点要发送数据且都探知线上空闲,于是在它们开始发送数据后一会儿线上就会发生数据冲突。节点在听到冲突后发出干扰(Jamming)信号,通知所有节点,使它们都知道发生了冲突并停止发送。各节点等待一段相互不同的随机时间后,再开始尝试重新发送。以太网技术发展过程中8023标准系列陆续形成新的版本。它们在MAC层控制技术上一直都采用CSMACD(载波监听多路访问冲突检测),而在物理层则不断推出新的规范,在保持兼容性的同时使媒介和拓扑结构都发生了质的变化,大幅度地提高了传输速率:从10Mbps,到100Mbps,到1Gbps,到10Gbps,甚至更高。以太网的特点是基带传输、技术相对比较简单、开放性好、价格低廉,所以普及非常迅速。全世界90以上的局域网市场份额都属于以太网。在以太网发展的同时,也正是Intemet取得惊人发展的历史时期。Intemet能把世界上不同地点、不同类型的计算机连在一起,其通信路由的建立以及端对端的通信机制的建立(即为上层具体应用创造架构条件)所采用的主要协议是TCPIP。(在网络层次结构中)向下看虽然TCPIP也支持其他局域网协议,但事实上以太网是TCPIP使用得最普遍的物理网络,几乎每一台具有上网功能的PC机都配置了以太网卡,TCPIP+以太网主宰了当今IT网络的基本架构。以太网在工业领域的发展:PC和网络应用的普及使信息技术成了促进专业技术和业务经营发展的基础手段。工业控制领域企业信息管理级的网络本身就是在盯技术的应用普及过程中发展起来的。根据企业信息管理级网络所须承担的通信业务性质,直接采用TCPIP+以太网组成企业信息管理级网络是普遍的做法,如图1所示。这样的网络结构有利于建立专业的信息管理体系(ITIS),利用IT技术不断升级的软硬件产品和服务,如数据库、Intranet和Intemet范围的文件共享、查询、电邮、远程控制、ERP、CRM等,从而为企业的经营和生产提供高效率的信息服务。 车间控制级和现场级网络所承担的信息传输直接关系到制造过程的实时控制和处理,在网络传输质量和环境条件方面的一些要求,传统的(主要适合于办公室应用的)以太网本来是不能完全满足的。然而由于以太网技术本身的发展,使它在工业网络应用中的一些困难逐步得到了解决。在网络传输质量方面,由于以太网采用的是CSMACD技术,其早期的拓扑结构是总线型的共享结构,整个网络成为一个冲突域,不能满足工业现场网络对通信的确定性和实时性的要求。但自10BASE-T(1EEE8023x)推出以后,以太网采用了星型结构,特别是10BASE-TX(IEEE8023x)推出以后,使用交换技术,整个网络被划分为一段一段小的冲突域,而且它们被交换机彼此隔离,同时又可采用全双工方式避免冲突,再加上100BASE诸版本的推出、网速大大提高,使通信的确定性和实时性显著改善。所以从技术方案上来说,现在的以太网用于工业现场已没有实质性的障碍。从硬件实现上来说,针对工业现场在环境温湿度、抗电磁干扰、防静电、低压供电以及用电安全规定等要求,有许多公司专门设计制造适于工业应用的以太网设备。如CISCO、3COM、西门子、Synergetic、Hirschman、三菱、JetterAG、Contemporary Control、Moxa等公司已推出了品种繁多的工业以太网设备和部件,包括交换机、集线器、网卡、接插件、线缆等。传统的工业控制网络是很贵的。出于用户投资价值保护的考虑,同时也因各种现场总线标准背后的企业集团的利益所在,现场总线各类标准的既定存在还不会一下子消失,但各个现场总线标准组织已纷纷采取措施、顺应以太网技术向工业控制领域渗透的大趋势。具体做法是把以太网和TCPIP纳入现场总线的整个体系,作为体系的低层(Layerl-3)协议,而在高层(Layer7)则利用原有体系的应用层协议、开发高低层间新的接口和原体系保留模块与新模块间的接口(软硬件),从而形成新的或更新版的现场总线标准,如HSE(High Speed Ethernet)、Profinet、EthernetIP、MODBUSIP等。这种在技术上与IEEE8023标准兼容的、能满足工业现场严酷的应用条件要求的网络即所谓的工业以太网。我国的工业自动化行业同样非常重视工业以太网技术的开发。基于高速以太网的现场总线控制设备研究被列为863重点项目。浙江大学浙大中控主持,联合浙江大学、中国科学院沈阳自动化研究所、重庆邮电学院、大连理工大学、清华大学、上海工业自动化仪表研究所等单位共同起草制定的用于工业测量与控制系统的EPA(Ethernet for Process Automation)系统结构与通信规范是我国拥有自主知识产权的工业以太网标准。根据美国权威调查机构ARC(Automation Research Company)的报告,今后Ethernet不仅继续垄断商业计算机网络通信和工业控制系统的上层网络通信市场,也必将领导未来现场总线的发展,Ethernet和TCPIP将成为现场总线的基础协议。美国VDC(Venture Development Corp)报告也指出,Ethernt在工业领域的应用将越来越广泛,市场占有率将从2000年的11增加到2005年的23。TCP/IP技术是工业控制技术发展的重要趋势,它将每个工控设备作为接点联入以太网并赋予每个节点机独立的IP。把以太网应用于工业自动控制领域至少具有以下优势:简化了工业通信网络的标志,可以利用通用的硬件设备,可选设备的品种型号丰富;利用了世界上广泛使用的TCP/IP协议,具有很高的普及性及通用性,具有跨平台集成的良好技术支持;数据传输速率高,现在传输速率在100Mbps的快速以太网已经非常普及,Gigabit以至于10G的高速以太网也已经问世。今后,凡采用以太网的场合都可以随着以太网技术的升级而享受更高技术所带来的便利。随着交换TCP/IP协议各种网络的开发和应用,使该协议自我完善和发展,胜任工业控制的各种要求。非常容易实现与其它操作模式或通信在数据链路层的集成,并有条件与已有的办公自动化网络和谐地共存于一个物理网,使通过办公自动化网络的远程终端监视建筑设备运行状况的实现成本大幅度降低;通过以太网连接的Internet可以与世界上任何地方的网络连接,并能廉价地实现远程维护和远程诊断;控制网络所采用的信号传输物理介质和广泛采用的综合布线的材料兼容,在施工中可以大大简化相应的施工节拍和技术措施。Ethernet仅仅只有物理层和链路层规范,它通常与TCP/IP等平台无关的协议结合应用。我们所指的Ethernet实际上是指基于TCP/IP协议的Ethernet,即Ethernet/IP。过去,以生产PLC为主的公司都使用Ethernet完成信息级通信,其中,西门了公司的SIMATICNET将Ethernet应用到车间级,并有向下层通信的趋势。随着FF HSE的开发成功,Ethernet将广泛应用于工业控制系统的监控网络。特别令人感兴趣的是,国际上有些公司已推出了完全以工业Ethernet为基础的控制系统,其工厂级、监控级和现场级均采用基于TCP/P通信协议的工业Ethernet,配备Wed server功能,而且这种趋势愈来愈明显。人们预测,像当年工业PC进入工业自动化领域一样,Ethernet/IP将会十分迅速地进入工业控制的各级网络。基于TCP/IP的Ethernet构成的工厂网络的最大优点是将工厂的商务网、车间的制造网络和现场级的仪表、设备网络构成了畅通的透明网络,并与WEB功能相结合,与工厂的电子商务、物资供应链和ERP等形成整体,这就是施奈德的透明工厂概念。2实验方案利用ZNE100模块将嵌入式设备(ARM2100)接入网络,由于ZNE-100模块内部集成了TCP/IP 协议栈,我们可以利于它轻松完成嵌入式设备的网络功能。然后用现有的ARM芯片(LPC2114)代替ZNE-100模块,实现单一芯片的TCP/IP功能化,从而代替整个ZNE-100模块。根据2114的串口GPIO口,外接RJ45口,利用双绞线实现串口数据通信。嵌入式设备ZNE100模块计算机串口以太网接口实验原理图在软件设计方面用汇编语言对串口通信进行控制,然后开发适合工程控制的协议栈,用ARM作为协议栈的控制芯片。3. 实验硬件设备3.1 ZNE-100转换模块ZNE-100 是周立功公司开发的一款嵌入式网络模块,它内部集成了TCP/IP 协议栈,用户利于它可以轻松完成嵌入式设备的网络功能。(1) ZNE-100模块功能特点: Serial (TTL) to 10M Ethernet,Serial 最大波特率为115200 bps; 可利用Web browser 和Windows utility 轻松进行设定; TCP Server, UDP Server, Real COM driver 作业模式; 支持动态(DHCP) ;或静态获取IP 地址; 尺寸小(4431.5mm);(2) ZNE-100模块产品特性: 32 位ARM7 CPU; 16KB RAM; 128KB FLASH; 10M 以太网接口(使用排针方式引出); 1.5KV 电磁隔离; 串口TTL 电平方式,波特率300115200 bps; 串口任意校验; 串口数据位5,6,7,8 可设定; 串口停止位1,2 位可设定; 支持TCP/IP 协议包括:ETHERNET、ARP、IP、ICMP、UDP、TCP、HTTP、DHCP; 工作方式可选择为TCP Server 或UDP Server,工作端口可设定; 可使用配置工具ZnetCom Utility for Windows98/me/NT/2000/XP 进行配置; 可使用网页浏览器进行配置; 输入电压5V DC 功耗低最大工作电流38 mA 工作温度065 保存温度2585(3) 硬件电路从俯视图图2.1我们可以看出ZNE-100 模块有两排外引管脚,左边一排是12 针,右边一排是11 针。左边排针的最上方引脚为模块的引脚1,依次往下是212 引脚,右边最上方是最后一个引脚23 脚。另外图2.1显示ZNE-100 模块的上方有3 个孔,它们是用于恢复出厂设置值和升级固件的。我们就称之为内部设置孔 ZNE模块外形ZNE-100 模块管脚名称管脚信号管脚信号1Ethernet TX2Ethernet TX23*保留3Ethernet RX22*保留4Ethernet RX21*保留5连接显示LED20*保留6TXD19EHTER_TXD_LED7RXD18*保留8485_TXD_EN17*保留9*保留16*保留10nRST 模块复位脚15EHTER_RXD_LED11GND14VCC (+5V DC)12GND13VCC (+5V DC)表中的Ethernet TX+、Ethernet TX-、Ethernet RX+、Ethernet RX-管脚是以太网信号;TXD、RXD 是串口信号;管脚5、16、19 为LED 信号,方向为输出;485_TXD_EN 是485发送控制端,方向为输出,保证RS485 半双工传输,发送数据时为高电平,接收数据为低电平;nRST 模块复位脚,低电平有效,在该管脚输入一大于20us 的负脉冲,模块复位(模块内部有上电复位电路,该管脚可悬空)3.2 ARM芯片微处理器采用RISC架构的ARM微处理器一般具有如下特点: 1、体积小、低功耗、低成本、高性能; 2、支持Thumb(16位)/ARM(32位)双指令集,能很好的兼容8位/16位器件; 3、大量使用寄存器,指令执行速度更快; 4、大多数数据操作都在寄存器中完成; 5、寻址方式灵活简单,执行效率高; 6、指令长度固定。这里只介绍LPC2114。LPC2114是基于一个支持实时仿真和跟踪的32位ARM7TDMI-STM CPU的微控制器,并带有128 k字节(kB)嵌入的高速Flash存储器。128位宽度的存储器接口和独特的加速结构使32位代码能够在最大时钟速率下运行。对代码规模有严格控制的应用可使用16位Thumb模式将代码规模降低超过30%,而性能的损失却很小。 由于LPC2114较小的64脚封装、极低的功耗、多个32位定时器、4路10位ADC以及多达9个外部中断使它们特别适用于工业控制、医疗系统、访问控制和POS机。 在64脚的封装中,最多可使用46个GPIO。在144脚的封装中,可使用的GPIO高达76(使用了外部存储器)112个(单片应用)。由于内置了宽范围的串行通信接口,它们也非常适合于通信网关、协议转换器、嵌入式软modern以及其它各种类型的应用。 器件管脚数片内RAM片内FLASH10位A/D通道数LPC21146416KB128B4LPC2114器件信息(1) LPC2114特性 32位64脚ARM7TDMI-S微控制器。 16K字节静态RAM。 128K字节片内Flash程序存储器(在工作温度范围内,片内Flash存储器至少可擦除和写10,000次)。128位宽度接口/加速器实现高达60MHz的操作频率。 外部8或16位总线。 片内Boot装载程序实现在系统编程(ISP)和在应用中编程(IAP)。Flash编程时间:1ms可编程512字节,扇区擦除或整片擦除只需400ms。 EmbeddedICE-RT接口使能断点和观察点。当前台任务使用片内RealMonitor软件调试时,中断服务程序可继续执行。 嵌入式跟踪宏单元(ETM)支持对执行代码进行无干扰的高速实时跟踪。 4路10位A/D转换器,转换时间低至2.44us。 2个32位定时器(带4路捕获和4路比较通道)、PWM单元(6路输出)、实时时钟和看门狗。 多个串行接口,包括2个16C550工业标准UART、高速C接口(400 kbit/s)和2个SPI接口。 通过片内PLL可实现最大为60MHz的CPU操作频率。 向量中断控制器。可配置优先级和向量地址。 多达46个通用I/O口(可承受5V电压),12个独立外部中断引脚(EIN和CAP功能)。 片内晶振频率范围:130 MHz。 2个低功耗模式:空闲和掉电。 通过外部中断将处理器从掉电模式中唤醒。 可通过个别使能/禁止外部功能来优化功耗。 双电源 CPU操作电压范围:1.651.95 V(1.8 V+/ 8.3%) I/O操作电压范围:3.03.6 V(3.3 V+/ 10%) (2) 结构概述 LPC2114/2124/2212/2214包含一个支持仿真的ARM7TDMI-S CPU、与片内存储器控制器接口的ARM7局部总线、与中断控制器接口的AMBA高性能总线(AHB)和连接片内外设功能的VLSI外设总线(VPB,ARM AMBA总线的兼容超集)。LPC2114/2124/2212/2214将ARM7TDMI-S配置为小端(little-endian)字节顺序。 AHB外设分配了2M字节的地址范围,它位于4G字节ARM存储器空间的最顶端。每个AHB外设都分配了16k字节的地址空间。LPC2114/2124/2212/2214的外设功能(中断控制器除外)都连接到VPB总线。AHB到VPB的桥将VPB总线与AHB总线相连。VPB外设也分配了2M字节的地址范围,从3.5GB地址点开始。每个VPB外设在VPB地址空间内都分配了16k字节地址空间。 片内外设与器件管脚的连接由管脚连接模块控制。该模块必须由软件进行控制以符合外设功能与管脚在特定应用中的需求。 ARM7TDMI-S处理器 ARM7TDMI-S是通用的32位微处理器,它具有高性能和低功耗的特性。ARM结构是基于精简指令集计算机(RISC)原理而设计的。指令集和相关的译码机制比复杂指令集计算机要简单得多。这样使用一个小的、廉价的处理器核就可实现很高的指令吞吐量和实时的中断响应。 由于使用了流水线技术,处理和存储系统的所有部分都可连续工作。通常在执行一条指令的同时对下一条指令进行译码,并将第三条指令从存储器中取出。 ARM7TDMI-S处理器使用了一个被称为THUMB的独特结构化策略,它非常适用于那些对存储器有限制或者需要较高代码密度的大批量产品的应用。 在THUMB后面一个关键的概念是“超精简指令集”。基本上,ARM7TDMI-S处理器具有两个指令集: 标准32位ARM指令集 16位THUMB指令集 THUMB指令集的16位指令长度使其可以达到标准ARM代码两倍的密度,却仍然保持ARM的大多数性能上的优势,这些优势是使用16位寄存器的16位处理器所不具备的。因为THUMB代码和ARM代码一样,在相同的32位寄存器上进行操作。 THUMB代码仅为ARM代码规模的65%,但其性能却相当于连接到16位存储器系统的相同ARM处理器性能的160%。 LPC2114/2124/2212/2214方框图 4. TCP/IP协议下的网络通信原理4.1 网络硬件在这里只讨论局域网,现在局域网大多采用以太网的拓扑结构,物理上由服务器、工作站、集线器、交换机、路由器、网卡、 RJ45水晶头、网线等组成。(1)服务器和工作站大多数时候服务器是网络的核心(当然对等网也可以没有服务器)。作为普通的办公、教学等应用服务器可以采用一般配置较高的普通电脑,注意内存和硬盘的容量应适当大一点,主板、机箱等配件也应选购名牌的产品,保证质量稳定可靠,而在显卡、显示器、多媒体等方面则不必过多花费。如果资金不存在问题,或应用要求高(如证券交易),则最好采用专用的服务器。专用网络服务器与普通电脑的主要区别在于:专用服务器具有更好的安全性和可靠性、更加注重系统的I/O 吞吐能力,一般采用了双电源、热拔插、SCSI RAID硬盘等技术。当然专用网络服务器的价格也不菲。工作站实际上就是普通的电脑,386以上档次的电脑都可作为组网的工作站。一般根据资金、应用等具体情况使用当时流行配置的电脑作为工作站。网络工作站可以不配置软驱和光驱,而且硬盘可以选择容量较小的,这样不仅可以充分利用服务器的资源,节省资金,还可防止病毒感染,保证网络安全。(2) 网络适配器(网卡)网卡的主要作用是将计算机数据转换为能够通过介质传输的信号。当网络适配器传输数据时,它首先接收来自计算机的数据。为数据附加自己的包含校验及网卡地址报头,然后将数据转换为可通过传输介质发送的信号。RJ-45接口的网卡总线结构看,ISA接口的网卡现在已基本被淘汰,普遍采用了PCI接口,另外还有PCMIA接口的笔记本电脑专用网卡。网卡的端口方面,以前BNC头(T形连接器,用于连接同轴电缆)和AVI(粗缆连接器)曾被广泛使用,目前已基本被淘汰。现在网卡主要采用RJ-45连接器,类似普通的电话电缆连接器(RJ-11),但要大一些,它使用具有四对导线的双绞线电缆。从数据传输方式看,现在网卡都支持全双工模式,所谓“全双工”,简单说就是指当A传送数据给B时,B同时也可以传送数据给A。而网卡与主机之间的数据传输方式,采用了Bus Master方式;可以不占用CPU资源,因此速度很快。网卡上的RJ-45接口和指示灯(3)传输介质(网线) 常见的网线分细同轴线缆、粗同轴线缆和双绞线、光缆等。以前同轴线缆采用较多,主要是因为同轴电缆组成的总线形结构网络成本较低,但单条电缆的损坏可能导致整个网络瘫痪,维护也难,这已经是一种将近淘汰的网络形式。以下重点介绍双绞线。根据最大传输速度的不同,双绞线分为不同的类别: 3类、5类及超5类。3类双绞线的速率为10Mb/S, 5类双绞线的速率可达100Mb/S,超5类更可达155Mb/s以上,可以适合未来多媒体数据传输的需求。双绞线还分为屏蔽双绞线(STP)和非屏蔽双绞线(UTP),STP双绞线内部包了一层皱纹状的屏蔽金属物质,并且多了一条接地用的金属铜丝线,因此它的抗干扰性比UTP双绞线强,但价格也要贵很多。对于UTP双绞线,阻抗值在1MHZ时通常为100欧姆,中心芯线24AMG(直径为0.5mm), 每条双绞线最大传输距离为100米。 由于网线布线大多涉及到建筑结构与内部装修,因此在布线完成后,如果想重新布线是非常困难的, 所以即使网卡等设备还是10Base-T的,但是在规划网络时,应该考虑到未来的需求,所以应采用5类甚至超5类的双绞线。非屏蔽双绞线和双绞线配套使用的还有RJ-45水晶头,用于制作双绞线与网卡RJ-45接口间的接头,其质量好坏直接关系整个网络的稳定性,不可忽视。双绞线的水晶头4.2 网络软件(1)协议分层 为了减少协议设计的复杂性,大多数网络都按层或级的方式来组织,每一层都建在它的下层之上。不同的网络,其层的数量、各层的名字、内容和功能都不尽相同。然而,在所有的网络中,每一层的目的都是向它的上一层提供一定的服务,而把如何实现这一服务的细节对上一层加以屏蔽。一台机器上的第N层与另外一台机子的第N层进行对话。通话的规则就是第N层协议。协议基本上是通信双方关于关于通信如何进行达成的一致。下图说明了一个5层的协议。不同的机器里包含对应的层的实体叫对等进程。换言之,正是对等进程利用协议进行通信。第5层第3层第1层第1层第4层第2层第2层第3层第4层第5层物理介质主机1主机2第5层协议第4层协议第3层协议第2层协议第1层协议层、协议和接口 实际上,数据不是从A一台机器的第N层直接传送到另外一台机器的第N层,而是每一层都把数据和控制信息交给它的下一层,直到最下层。第一层下面是物理介质,它进行实际的通信。在上图,同层之间的双向中间断开的箭头表示虚拟通信,实线表示物理通信。每一对相邻层之间都有一个接口。接口定义下层向上层提供的原语操作和服务。网络设计者在决定一个网络应包括多少层,每一层应当作什么的时候,其中一个很重要的考虑就是要在相邻层之间定义一个清晰的接口。为达到这些目的,又要求每一层能完成一组特定的有明确含义的功能。除了尽可能的减少必须在相邻层之间传递信息的数量外,一个清晰的接口可以使同一层能轻易地用一种实现来替换一种完全不同的实现,只要新的实现能向上层提供旧的实现所提供的同一组服务就可以了。层和协议的集合被称为网络体系结构。体系结构的描述必须包含足够的信息,使实现者可以用来为每一层编写程序和设计硬件,并使之符合有关协议。协议实现的细节和接口的描述都不是体系结构的内容,因为它们都隐藏在机器内部,对外部来说是不可见的。只要机器都能正确地使用全部协议,网络上所有机器的接口不必完全相同。某一系统所使用的协议列表,每层一个协议,被称为协议栈。(2)各层的设计问题每一层都需要识别发送方和接收方的机制。因为网络中通常有很多计算机,其中一些有多个进程。某台机器上需要建立连接的进程必须能有某种手段来指定想和谁通信。因为有多个目标,所以需要有某种寻址手段来指明特定的目标。另一组设计决策与数据传送的规则有关。在某些系统中,数据仅在一个方向上传输,即单工通信。在另一些系统中,数据能在任意一个方向上传输,但不是同时传输,即半双工通信。还有一些系统,数据能同时双向传输,即全双工通信。协议还需确定每条连接对应多少条逻辑通道,它们的优先级如何。在很多网络中,每个连接至少提供两条逻辑通道,一条给出正常数据,另外一条留给紧急数据。物理通信并非完美无缺的,所以差错控制是另一个重要的问题。已知的检错和纠错代码有多种,连接的双方必须一致同意使用哪一种。另外,接收方还应通知发送方哪些报文已经被正确地接收到了,那些还没有收到。并不是所有的通信都能保持报文发送的先后顺序。为了解决可能出现的顺序错误,协议必须明确地保证接收方能够把各报文按原来的顺序重新组合在一起。一个易于想到的方法是对这些信息编号。不过,这仍未解决收到顺序错误报文时应该怎么做的问题。如何避免出现高速发送方发送数据过快,使低速接收方难以应付的局面这一问题在各层都存在。一些方案要求接收方向发送方直接或间接地反馈接收方地当前状态。另一些方案是限制发送方以商定的速率发送数据。另一个必须在好几层中解决的问题是,所有的进程都应该能接收任意长的报文。这一特性要求我们能把报文分割、传输和重新组装。与之相关的另一个问题是:当进程要传送的数据单元太小时,发送的效率又太低。这里的解决方案是把几个传向同一目标的短报文收集成一个长报文,然后在接收方再分解为原报文。当每一对通信进程建立一个独立的连接不方便或不合算时,可以利用下一层的同一连接为多个无关的对话服务。只要这种多路复用和解多路复用是透明的,任意一层都可以采用这种方法。比如,物理层需要多路复用,物理层上的所有连接的通信量就只能在有限的几条物理线路上传送。(3)接口和服务 每一层中的活动单元通常被称为实体。实体既可以是软件实体,也可以是硬件实体。不同机器上同一层的实体叫做对等实体。N层实体实现的服务为N+1层所利用。在这种情况下,N层被称为服务提供者,N1层为服务用户。N层利用N1层的服务来提供它自己的服务。 服务是在服务接入点SAP提供给上层使用的。N层SAP就是N1层可以访问N层服务的地方。每个SAP都有一个唯一地标明它的地址。相邻层之间要交换信息,对接口必须有一致同意的规则。在典型的接口上,N1层实体通过SAP把一个接口数据单元IDU传递给N层实体。IDU由服务数据单元SDU和一些控制信息组成。SDU是将要跨过网络传递给对等实体,然后向上交给N1层的信息。控制信息用于帮助下一层完成人物,它本身不是数据的一部分。ICISDUICISDUSAP第N1层接口第N层IDUSDUn-PDUSAP=服务接入点IDU=接口数据单元SDU=服务数据单元PDU=协议数据单元ICI=接口控制信息处于接口两边的两层接口之间的关系为了传递SDU,N层实体可能将SDU分成几段,每一段加上一个报头后作为独立的协议数据单元PDU送出。例如分组就是PDU。PDU被对等实体用于执行它们的同层协议。它们被用于分辨那些PDU包含数据,那些PDU包含控制信息,并提供序号和计数等。(4)面向连接的服务和无连接的服务面向连接的服务以电话系统为模式。要和某个人通话,先拿起电话,拨号码,谈话,然后挂断。同样,在使用面向连接的服务时,用户首先要建立连接,使用连接,然后释放连接。无连接服务以邮政系统为模式。每个报文带有完整的目的地址,并且每个报文都独立于其他报文,经由系统选定的路线传递。在正常情况下,当有两个报文发往同一目的地时,先发的先收到。但是,也有可能先发的报文在途中延误了,后发的报文反而先收到。而这种情况在面向连接的服务中是绝不可能发生的。4.3 TCP/IP参考模型TCP/IP是Internet主机和设备之间通信的“语言”。OSI TCP/IP7应用应用6表示5会话4传输传输3网络互连网2数据链接主机至网络1物理TCP/IP参考模型每一层负责不同的功能:1. 链路层,有时也称作数据链路层或网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。2. 网络层,有时也称作互连网层,处理分组在网络中的活动,例如分组的路由选择。在TCP/IP协议组件中,网络层协议包括IP协议(网际协议),ICMP协议(Internet互连网控制报文协议),以及IGMP协议(Internet组管理协议)。3. 运输层主要为两台主机上的应用程序提供端到端的通信。在TCP/IP协议组件中,有两个互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议)。TCP为两台主机提供高可靠性的数据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。而另一方面,UDP则为应用层提供一种非常简单的服务。它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。任何必需的可靠性必须由应用层来提供。这两种运输层协议分别在不同的应用程序中有不同的用途,这一点我们将在后面看到。4. 应用层负责处理特定的应用程序细节。几乎各种不同的TCP/IP实现都会提供下面这些通用的应用程序:Telnet 远程登录FTP 文件传输协议SMTP 用于电子邮件的简单邮件传输协议SNMP 简单网络管理协议5串口通信串行通讯的基本概念:与外界的信息交换称为通讯。基本的通讯方式有并行通讯和串行通讯两种。一条信息的各位数据被同时传送的通讯方式称为并行通讯。并行通讯的特点是:各数据位同时传送,传送速度快、效率高,但有多少数据位就需多少根数据线,因此传送成本高,且只适用于近距离(相距数米)的通讯。一条信息的各位数据被逐位按顺序传送的通讯方式称为串行通讯。串行通讯的特点是:数据位传送,传按位顺序进行,最少只需一根传输线即可完成,成本低但送速度慢。串行通讯的距离可以从几米到几千米。根据信息的传送方向,串行通讯可以进一步分为单工、半双工和全双工三种。信息只能单向传送为单工;信息能双向传送但不能同时双向传送称为半双工;信息能够同时双向传送则称为全双工。串行通讯又分为异步通讯和同步通讯两种方式。在单片机中,主要使用异步通讯方式。5.1串口通信的基本原理串行端口的本质功能是作为CPU和串行设备间的编码转换器。当数据从CPU经过串行端口发送出去时,字节数据转换为串行的位。在接收数据时,串行的位被转换为字节数据。5.2串口信号线的接法目前较为常用的串口有9针串口(DB9)和25针串口(DB25),通信距离较近时(hwType != arp_TypeEther | /* have ethernet hardware, */ ap-protType != 0x800 | /* and internet software, */ ap-opcode != ARP_REQUEST | /* and be a resolution req. */ ap-dstIPAddr != sin_lclINAddr /* for my addr. */ ) return ( 0 ); /* or we ignore it. */ /* format response. */ op = (arp_Header *)sed_FormatPacket(ap-srcEthAddr, 0x806); op-hwType = arp_TypeEther; op-protType = 0x800; op-hwProtAddrLen = (sizeof(eth_HwAddress) opcode = ARP_REPLY; op-srcIPAddr = sin_lclINAddr; MoveW(sed_lclEthAddr, op-srcEthAddr, sizeof(eth_HwAddress); ap-dstIPAddr = op-srcIPAddr; MoveW(ap-srcEthAddr, op-dstEthAddr, sizeof(eth_HwAddress); sed_Send(sizeof(arp_Header); return ( 1 );/* * Do an address resolution bit. */sar_MapIn2Eth(ina, ethap) longword ina; eth_HwAddress *ethap; register arp_Header *op; extern in_HwAddress sin_lclINAddr; register i; longword endTime; longword rxMitTime; sed_Receive( 0 ); endTime = clock_ValueRough() + 2000; while ( endTime clock_ValueRough() ) op = (arp_Header *)sed_FormatPacket(&sed_ethBcastAddr0, 0x806); op-hwType = arp_TypeEther; op-protType = 0x800; op-hwProtAddrLen = (sizeof(eth_HwAddress) opcode = ARP_REQUEST; op-srcIPAddr = sin_lclINAddr; MoveW(sed_lclEthAddr, op-srcEthAddr, sizeof(eth_HwAddress); op-dstIPAddr = ina; /* .and send the packet */ sed_Send( sizeof(arp_Header) ); rxMitTime = clock_ValueRough() + 250; while ( rxMitTime clock_ValueRough() ) op = (arp_Header *)sed_IsPacket(); if ( op ) if ( sed_CheckPacket(op, 0x806) = 1 & op-protType = 0x800 & op-srcIPAddr = ina & op-opcode = ARP_REPLY ) MoveW(op-srcEthAddr, ethap, sizeof(eth_HwAddress); return ( 1 ); sed_Receive(op); return ( 0 );附录 2发送数据程序#include tinytcp.h#include sed.h#define en10pages (en10size) pageshift)octet *sed_va; /* virtual address of ethernet card */eth_HwAddress sed_lclEthAddr; /* local ethernet address */eth_HwAddress sed_ethBcastAddr; /* Ethernet broadcast address */BOOL sed_respondARPreq; /* controls responses to ARP reqs */char bufAinUse, bufBinUse; /* tell whether bufs are in use */* * Initialize the Ethernet Interface, and this package. Enable input on * both buffers. */sed_Init() int recState; register i, j; recState = 7; /* = mine + broad - errors */ /* Map the Ethernet Interface in, and initialize sed_va */ sed_va = (octet *)SED3CVA; /* our virtual addr */ /* Map memory for 3Com board (must be 8k boundary) */ /* INSERT CODE HERE */ map_ethernet_board(); /* Reset the Ethernet controller */ MECSR(sed_va) = RESET; for (i=0; i10; i+); /* delay a bit. */ /* just copy on-board ROM to on-board RAM, to use std. address */ Move(MEAROM(sed_va), sed_lclEthAddr, 6); Move(sed_lclEthAddr, MEARAM(sed_va), 6); MECSR(sed_va) |= AMSW; /* and tell board we did it */ /* * and initialize the exported variable which gives the Eth broadcast * address, for everyone else to use. */ for (i=0; i3; i+) sed_ethBcastAddri = 0xFFFF; /* accept packets addressed for us and broadcast packets */ MECSR(sed_va) = (MECSR(sed_va)&PA) | recState; /* declare both buffers in use. */ bufAinUse = bufBinUse = TRUE;/* * Format an ethernet header in the transmit buffer, and say where it is. * Note that because of the way the 3Com interface works, we need to know * how long the packet is before we know where to put it. The solution is * that we format the packet at the BEGINNING of the transmit buffer, and * later copy it (carefully) to where it belongs. Another hack would be * to be inefficient about the size of the packet to be sent (always send * a larger ethernet packet than you need to, but copying should be ok for * now. */octet *sed_FormatPacket( destEAddr, ethType ) register octet *destEAddr; register octet *xMitBuf; xMitBuf = &(octet *)MEXBUF(sed_va)-0x800; Move( destEAddr, xMitBuf, 6 ); Move( sed_lclEthAddr, xMitBuf + 6, 6 ); *(short *)(xMitBuf+12) = ethType; return ( xMitBuf+14 );/* * Send a packet out over the ethernet. The packet is sitting at the * beginning of the transmit buffer. The routine returns when the * packet has been successfully sent. */sed_Send( pkLengthInOctets ) register int pkLengthInOctets; register octet *fromO, *toO; register pkLength; register csr; pkLengthInOctets += 14; /* account for Ethernet header */ pkLengthInOctets = (pkLengthInOctets + 1) & (1); if (pkLengthInOctets E10P_MIN) pkLengthInOctets = E10P_MIN; /* and min. ethernet len */ /* and copy the packet where it belongs */ pkLength = pkLengthInOctets; fromO = &(octet *)MEXBUF(sed_va)-0x800 + pkLength; toO = (octet *)MEXBUF(sed_va); while ( pkLength- ) *-toO = *-fromO; /* send the packet */ MEXHDR(sed_va) = 2048 - pkLengthInOctets; MECSR(sed_va) |= TBSW; /* and wait until it has really been sent. */ for (pkLength=0; pkLength 15; pkLength+) while ( (! (csr = MECSR(sed_va) & JAM) & (csr & TBSW) ) ; if (csr & JAM ) /* Ethernet Collision detected. */#ifdef DEBUG printf(sed: JAM: MECSR=%xn, csr);#endif MEBACK(sed_va) = clock_ValueRough(); MECSR(sed_va) |= JAM; else break; if ( pkLength = 15 ) SysBug(Go and Buy a New Ethernet Interface.); /* else we sent the packet ok. */* * Enable the Ethernet interface to receive packets from the network. If * the argument is zero, enable both buffers. If the argument is nonzero, * take it as the address of the buffer to be enabled. */sed_Receive( recBufLocation ) octet *recBufLocation; word enables = 0; if (recBufLocation = 0) bufAinUse = FALSE; bufBinUse = FALSE; enables = (ABSW | BBSW); recBufLocation -= 16; if (recBufLocation = (octet *)MEAHDR(sed_va) bufAinUse = FALSE; enables = ABSW; if (recBufLocation = (octet *)MEBHDR(sed_va) bufBinUse = FALSE; enables = BBSW; MECSR (sed_va) |= enables;/* * Test for the arrival of a packet on the Ethernet interface. The packet may * arrive in either buffer A or buffer B; the location of the packet is * returned. If no packet is returned withing timeout milliseconds, * then the routine returns zero. * * Note: ignores ethernet errors. may occasionally return something * which was received in error. */octet *sed_IsPacket() register oldStatus; register octet *pb; pb = 0; if ( ! bufAinUse & (MECSR(sed_va)&ABSW) = 0 ) pb = (octet *)MEAHDR(sed_va); if ( ! pb & ! bufBinUse & (MECSR(sed_va)&BBSW) = 0 ) pb = (octet *)MEBHDR(sed_va); if ( pb ) if ( (octet *)pb) = (octet *)MEAHDR(sed_va) ) bufAinUse = 1; else bufBinUse = 1; pb += 16; /* get past the ethernet header */ return ( pb );/* * Check to make sure that the packet that you received was the one that * you expected to get. */sed_CheckPacket( recBufLocation, expectedType ) word *recBufLocation; word expectedType; register recHeader = recBufLocation-8; if ( (recHeader&R_ERROR) != 0 | (recHeader&R_OFFSET) state = tcp_StateSYNSENT; s-timeout = tcp_LONGTIMEOUT; if ( lport = 0 ) lport = clock_ValueRough(); s-myport = lport; if ( ! sar_MapIn2Eth(ina, &s-hisethaddr0) ) printf(tcp_Open of 0x%x: defaulting ethernet address to broadcastn, ina); Move(&sed_ethBcastAddr0, &s-hisethaddr0, sizeof(eth_HwAddress); s-hisaddr = ina; s-hisport = port; s-seqnum = 0; s-dataSize = 0; s-flags = tcp_FlagSYN; s-unhappy = true; s-dataHandler = datahandler; s-next = tcp_allsocs; tcp_allsocs = s; tcp_Send(s);/* * Passive open: listen for a connection on a particular port */tcp_Listen(s, port, datahandler, timeout) tcp_Socket *s; word port; procref datahandler; s-state = tcp_StateLISTEN; if ( timeout = 0 ) s-timeout = 0x7ffffff; /* forever. */ else s-timeout = timeout; s-myport = port; s-hisport = 0; s-seqnum = 0; s-dataSize = 0; s-flags = 0; s-unhappy = 0; s-dataHandler = datahandler; s-next = tcp_allsocs; tcp_allsocs = s;/* * Send a FIN on a particular port - only works if it is open */tcp_Close(s) tcp_Socket *s; if ( s-state = tcp_StateESTAB | s-state = tcp_StateSYNREC ) s-flags = tcp_FlagACK | tcp_FlagFIN; s-state = tcp_StateFINWT1; s-unhappy = true; /* * Abort a tcp connection */tcp_Abort(s) tcp_Socket *s; if ( s-state != tcp_StateLISTEN & s-state != tcp_StateCLOSED ) s-flags = tcp_FlagRST | tcp_FlagACK; tcp_Send(s); s-unhappy = 0; s-dataSize = 0; s-state = tcp_StateCLOSED; s-dataHandler(s, 0, -1); tcp_Unthread(s);/* * Retransmitter - called periodically to perform tcp retransmissions */tcp_Retransmitter() tcp_Socket *s; BOOL x; for ( s = tcp_allsocs; s; s = s-next ) x = false; if ( s-dataSize 0 | s-unhappy ) tcp_Send(s); x = true; if ( x | s-state != tcp_StateESTAB ) s-timeout -= tcp_RETRANSMITTIME; if ( s-timeout state = tcp_StateTIMEWT ) printf(Closed. n); s-state = tcp_StateCLOSED; s-dataHandler(s, 0, 0); tcp_Unthread(s); else printf(Timeout, abortingn); tcp_Abort(s); /* * Unthread a socket from the socket list, if its there */tcp_Unthread(ds) tcp_Socket *ds; tcp_Socket *s, *sp; sp = &tcp_allsocs; for (;) s = *sp; if ( s = ds ) *sp = s-next; break; if ( s = NIL ) break; sp = &s-next; /* * busy-wait loop for tcp. Also calls an application proc */tcp(application) procref application; in_Header *ip; longword timeout, start; int x; sed_Receive(0); timeout = 0; while ( tcp_allsocs ) start = clock_ValueRough(); ip = sed_IsPacket(); if ( ip = NIL ) if ( clock_ValueRough() timeout ) tcp_Retransmitter(); timeout = clock_ValueRough() + tcp_RETRANSMITTIME; application(); continue; if ( sed_CheckPacket(ip, 0x806) = 1 ) /* do arp */ sar_CheckPacket(ip); else if ( sed_CheckPacket(ip, 0x800) = 1 ) /* do IP */ if ( ip-destination = sin_lclINAddr & in_GetProtocol(ip) = 6 & checksum(ip, in_GetHdrlenBytes(ip) = 0xFFFF ) tcp_Handler(ip); /* recycle buffer */ sed_Receive(ip); x = clock_ValueRough() - start; timeout -= x; return ( 1 );/* * Write data to a connection. * Returns number of bytes written, = 0 when connection is not in * established state. */tcp_Write(s, dp, len) tcp_Socket *s; byte *dp; int len; int x; if ( s-state != tcp_StateESTAB ) len = 0; if ( len (x = tcp_MaxData - s-dataSize) ) len = x; if ( len 0 ) Move(dp, &s-datas-dataSize, len); s-dataSize += len; tcp_Flush(s); return ( len );/* * Send pending data */tcp_Flush(s) tcp_Socket *s; if ( s-dataSize 0 ) s-flags |= tcp_FlagPUSH; tcp_Send(s); /* * Handler for incoming packets. */tcp_Handler(ip) in_Header *ip; tcp_Header *tp; tcp_PseudoHeader ph; int len; byte *dp; int x, diff; tcp_Socket *s; word flags; len = in_GetHdrlenBytes(ip); tp = (tcp_Header *)(byte *)ip + len); len = ip-length - len; /* demux to active sockets */ for ( s = tcp_allsocs; s; s = s-next ) if ( s-hisport != 0 & tp-dstPort = s-myport & tp-srcPort = s-hisport & ip-source = s-hisaddr ) break; if ( s = NIL ) /* demux to passive sockets */ for ( s = tcp_allsocs; s; s = s-next ) if ( s-hisport = 0 & tp-dstPort = s-myport ) break; if ( s = NIL ) #ifdef DEBUG if ( tcp_logState & tcp_LOGPACKETS ) tcp_DumpHeader(ip, tp, Discarding);#endif return; #ifdef DEBUG if ( tcp_logState & tcp_LOGPACKETS ) tcp_DumpHeader(ip, tp, Received);#endif /* save his ethernet address */ MoveW(&(eth_Header *)ip) - 1)-source0), &s-hisethaddr0, sizeof(eth_HwAddress); ph.src = ip-source; ph.dst = ip-destination; ph.mbz = 0; tocol = 6; ph.length = len; ph.checksum = checksum(tp, len); if ( checksum(&ph, sizeof ph) != 0xffff ) printf(bad tcp checksum, received anywayn); flags = tp-flags; if ( flags & tcp_FlagRST ) printf(connection resetn); s-state = tcp_StateCLOSED; s-dataHandler(s, 0, -1); tcp_Unthread(s); return; switch ( s-state ) case tcp_StateLISTEN: if ( flags & tcp_FlagSYN ) s-acknum = tp-seqnum + 1; s-hisport = tp-srcPort; s-hisaddr = ip-source; s-flags = tcp_FlagSYN | tcp_FlagACK; tcp_Send(s); s-state = tcp_StateSYNREC; s-unhappy = true; s-timeout = tcp_TIMEOUT; printf(Syn from 0x%x#%d (seq 0x%x)n, s-hisaddr, s-hisport, tp-seqnum); break; case tcp_StateSYNSENT: if ( flags & tcp_FlagSYN ) s-acknum+; s-flags = tcp_FlagACK; s-timeout = tcp_TIMEOUT; if ( (flags & tcp_FlagACK) & tp-acknum = (s-seqnum + 1) ) printf(Openn); s-state = tcp_StateESTAB; s-seqnum+; s-acknum = tp-seqnum + 1; s-unhappy = false; else s-state = tcp_StateSYNREC; break; case tcp_StateSYNREC: if ( flags & tcp_FlagSYN ) s-flags = tcp_FlagSYN | tcp_FlagACK; tcp_Send(s); s-timeout = tcp_TIMEOUT; printf( retransmit of original synn); if ( (flags & tcp_FlagACK) & tp-acknum = (s-seqnum + 1) ) s-flags = tcp_FlagACK; tcp_Send(s); s-seqnum+; s-unhappy = false; s-state = tcp_StateESTAB; s-timeout = tcp_TIMEOUT; printf(Synack received - connection establishedn); break; case tcp_StateESTAB: if ( (flags & tcp_FlagACK) = 0 ) return; /* process ack value in packet */ diff = tp-acknum - s-seqnum; if ( diff 0 ) Move(&s-datadiff, &s-data0, diff); s-dataSize -= diff; s-seqnum += diff; s-flags = tcp_FlagACK; tcp_ProcessData(s, tp, len); break; case tcp_StateFINWT1: if ( (flags & tcp_FlagACK) = 0 ) return; diff = tp-acknum - s-seqnum - 1; s-flags = tcp_FlagACK | tcp_FlagFIN; if ( diff = 0 ) s-state = tcp_StateFINWT2; s-flags = tcp_FlagACK; printf(finack received.n); tcp_ProcessData(s, tp, len); break; case tcp_StateFINWT2: s-flags = tcp_FlagACK; tcp_ProcessData(s, tp, len); break; case tcp_StateCLOSING: if ( tp-acknum = (s-seqnum + 1) ) s-state = tcp_StateTIMEWT; s-timeout = tcp_TIMEOUT; break; case tcp_StateLASTACK: if ( tp-acknum = (s-seqnum + 1) ) s-state = tcp_StateCLOSED; s-unhappy = false; s-dataSize = 0; s-dataHandler(s, 0, 0); tcp_Unthread(s); printf(Closed. n); else s-flags = tcp_FlagACK | tcp_FlagFIN; tcp_Send(s); s-timeout = tcp_TIMEOUT; printf(retransmitting FINn); break; case tcp_StateTIMEWT: s-flags = tcp_FlagACK; tcp_Send(s); /* * Process the data in an incoming packet. * Called from all states where incoming data can be received: established, * fin-wait-1, fin-wait-2 */tcp_ProcessData(s, tp, len) tcp_Socket *s; tcp_Header *tp; int len; int diff, x; word flags; byte *dp; flags = tp-flags; diff = s-acknum - tp-seqnum; if ( flags & tcp_FlagSYN ) diff-; x = tcp_GetDataOffset(tp) = 0 ) dp += diff; len -= diff; s-acknum += len; s-dataHandler(s, dp, len); if ( flags & tcp_FlagFIN ) s-acknum+;#ifdef DEBUG printf(consumed fin.n);#endif switch(s-state) case tcp_StateESTAB: /* note: skip state CLOSEWT by automatically closing conn */ x = tcp_StateLASTACK; s-flags |= tcp_FlagFIN; s-unhappy = true;#ifdef DEBUG printf(sending fin.n);#endif break; case tcp_StateFINWT1: x = tcp_StateCLOSING; break; case tcp_StateFINWT2: x = tcp_StateTIMEWT; break; s-state = x; s-timeout = tcp_TIMEOUT; tcp_Send(s);/* * Format and send an outgoing segment */tcp_Send(s) tcp_Socket *s; tcp_PseudoHeader ph; struct _pkt in_Header in; tcp_Header tcp; longword maxsegopt; *pkt; byte *dp; pkt = (struct _pkt *)sed_FormatPacket(&s-hisethaddr0, 0x800); dp = &pkt-maxsegopt; pkt-in.length = sizeof(in_Header) + sizeof(tcp_Header) + s-dataSize; /* tcp header */ pkt-tcp.srcPort = s-myport; pkt-tcp.dstPort = s-hisport; pkt-tcp.seqnum = s-seqnum; pkt-tcp.acknum = s-acknum; pkt-tcp.window = 1024; pkt-tcp.flags = s-flags | 0x5000; pkt-tcp.checksum = 0; pkt-tcp.urgentPointer = 0; if ( s-flags & tcp_FlagSYN ) pkt-tcp.flags += 0x1000; pkt-in.length += 4; pkt-maxsegopt = 0x02040578; /* 1400 bytes */ dp += 4; MoveW(s-data, dp, s-dataSize); /* internet header */ pkt-in.vht = 0x4500; /* version 4, hdrlen 5, tos 0 */ pkt-in.identification = tcp_id+; pkt-in.frag = 0; pkt-in.ttlProtocol = (250in.checksum = 0; pkt-in.source = sin_lclINAddr; pkt-in.destination = s-hisaddr; pkt-in.checksum = checksum(&pkt-in, sizeof(in_Header); /* compute tcp checksum */ ph.src = pkt-in.source; ph.dst = pkt-in.destination; ph.mbz = 0; tocol = 6; ph.length = pkt-in.length - sizeof(in_Header); ph.checksum = checksum(&pkt-tcp, ph.length); pkt-tcp.checksum = checksum(&ph, sizeof ph);#ifdef DEBUG if ( tcp_logState & tcp_LOGPACKETS ) tcp_DumpHeader(&pkt-in, &pkt-tcp, Sending);#endif sed_Send(pkt-in.length);/* * Do a ones complement checksum */checksum(dp, length) word *dp; int length; int len; longword sum; len = length 1; sum = 0; while ( len- 0 ) sum += *dp+; if ( length & 1 ) sum += (*dp & 0xFF00); sum = (sum & 0xFFFF) + (sum 16) & 0xFFFF); sum = (sum & 0xFFFF) + (sum 16) & 0xFFFF); return ( sum );/* * Dump the tcp protocol header of a packet */tcp_DumpHeader( ip, tp, mesg ) in_Header *ip; char *mesg; register tcp_Header *tp = (tcp_Header *)(byte *)ip + in_GetHdrlenBytes(ip); static char *flags = FIN, SYN, RST, PUSH, ACK, URG ; int len; word f; len = ip-length - (tcp_GetDataOffset(tp) + i
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
提示  人人文库网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
关于本文
本文标题:DZ054精简的ARM-TCPIP接口的开发和研究
链接地址:https://www.renrendoc.com/paper/149922598.html

官方联系方式

2:不支持迅雷下载,请使用浏览器下载   
3:不支持QQ浏览器下载,请用其他浏览器   
4:下载后的文档和图纸-无水印   
5:文档经过压缩,下载后原文更清晰   
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

网站客服QQ:2881952447     

copyright@ 2020-2025  renrendoc.com 人人文库版权所有   联系电话:400-852-1180

备案号:蜀ICP备2022000484号-2       经营许可证: 川B2-20220663       公网安备川公网安备: 51019002004831号

本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知人人文库网,我们立即给予删除!