1、iUDP 通信实验【摘要】利用基于嵌入式实时操作系统 C/OS-II 的 ZLG/IP 软件包,利用实验板光盘提供的 UDPtest 软件可以实现实验板跟 PC 机的数据收发。【关键词】ARM UDP C/OS-II 操作系统ii目 录第 1 章 硬件实现 11.1 RTL8019AS 网络控制器介绍 1第 2 章 C/OS-II 操作系统 32.1 C/OS-II 系统简介 .32.2 C/OS-II 的特点 .32.3 任务模式 .32.4 支持的指令集 .42.5 移植 C/OS-II .4第 3 章 ZLG/IP 软件包结构和配置 .63.1 ZLG/IP 软件包结构 6第 4 章 设
2、计过程 84.1 设计步骤 .84.2 实验程序 .104.2.1 宏定义 .104.2.2 RTL8019AS 监听任务 114.2.3 UDP 通信程序 124.2.4 创建系统任务并初始化 .144.2.5 主程序 .154.2.6 定时器中断控制 .16第 5 章 实验结果 19iii第 6 章 课程设计体会 211第 1 章 硬件实现1.1 RTL8019AS 网络控制器介绍RTL8019AS 是一种全双工即插即用的以太网控制器,它在一块芯片上集成了 RTL8019 内核和一个 16KB 的 SDRAM 存储器。它兼容 RTL8019 控制软件和 NE2000 8bit 或 16bi
3、t 的传输,支持UTP,AUI,BNC 和 PNP 自动检测模式,支持外接闪烁存储器读写操作,支持 I/O 口地址的完全解码,具有 LED 指示功能。其接口符合 Ethernet2 和 IEEE802.3(10Base5,10Base2,10BaseT)标准。RTL8019AS 采用 100 脚 PQFP 封装,其主要引角功能如下:引角 14,97100:中断控制 INT0-7;引角 33:复位控制;引脚 34:使能控制角 AEN,低电平有效;引脚 6,7,70,89:数字电源,5V;引脚 14,28,83,86:数字地 GND;引脚 47,57:模拟电源:5V;引脚 44,52:模拟地;引脚
4、 713,15,16,1827:ISA 地址总线;引脚 3643,87,88,9095:ISA 数据总线;引脚 31:Boot ROM 读操作控制;引脚 32:Boot ROM 写操作控制;引脚 62:RX 接收数据显示 LED1 脚;引脚 63:TX 发送数据显示 LED2 脚;引脚 58,59:接收数据 TP IN+/-;引脚 45,46:发送数据 TP OUT+/-;引脚 50,51:外接晶体。2图 1 RTL8019AS 接线图3第 2 章 C/OS-II 操作系统2.1 C/OS-II 系统简介C/OS-II 读做“ microCOS2”,意为“微控制器操作系统版本 2”。C/OS-
5、II 是著名的、源码公开的实时内核,可用于各类 8 位、16 位和 32位单片机、arm 或 DSP 等等。 C/OS-II 是一个完整的、可移植、可固化、可剪裁的占先式实时多任务内核。应用程序处于整个系统的顶层.每个任务都可以认为自己独占了 CPU,因而可以设计成为一个无限循环。2.2 C/OS-II 的特点 可移植性(portable) 可固化(ROMmable) 可剪裁(scalable) 可剥夺(preemptive) 多任务 可确定性 任务栈 系统服务 中断管理 稳定性与可靠性多任务是指:C/OS-II 可以管理 64 个任务,然而,C/OS-II 的作者建议用户保留 8 个给 C/
6、OS-II。这样,留给用户的应用程序最多可有 56 个任务。系统服务指:C/OS-II 提供很多系统服务,例如信号量、互斥信号量、时间标志、消息邮箱、消息队列、块大小固定的内存的申请与释放及时间管理函数等。中断管理指:中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达 255 层。2.3 任务模式ARM7 处理器核具有用户、系统、管理、中止、未定义、中断和快中4断七种模式 。用户模式(USER MODE)是 ARM 通常执行状态,用于执行大多数应用程序;快速中断模式(FIQ MODE)支持数据传输或通道处理;中断模式
7、 (IRQ MODE)用于通用中断处理;超级用户模式(SVC MODE)是一种操作系统受保护的模式:数据中止模式(ABT MODE)指令预取指中止、数据中止时进入该模式;未定义模式(UND MODE)当执行未定义的指令时进入该模式;系统模式(SYS MODE) 是操作系统一种特许的用户模式。除了用户模式之外,其他模式都归为特权模式,特权模式用于中断服务、异常或者访问受保护的资源特权模式中除系统模式之外另 5 种模式又称为异常模式,在移植过程中必须设置中断向量表来处理异常。uCOS II 的移植主要处理标准中断(IRQ)、快速中断 (FIQ)和软件中断(SWI) 。2.4 支持的指令集带 T 变
8、量的 ARM7 处理器核具有两个指令集:标准 32 位 ARM 指令集和 16 位 Thumb 指令集,两种指令集有不同的应用范围,C/OS-II 包含了这些指令集的切换(TaskIsARM()和 TaskIsTHUMB()用于改变指令集)。2.5 移植 C/OS-IIC/OS-II 要求所有.C 文件的都要包含都文件 includes.h,这样使得用户项目中的每个.C 文件不用分别去考虑它实际上需要哪些头文件。使用includes.h 的缺点是它可能会包含一些实际不相关的头文件,这意味着每个文件的编译时间可能会增加,但却增强了代码的可移植性。在本移植中另外增加了一个头文件 config.h,
9、我们要求所有用户程序必须包含 config.h,在 config.h 中包含 includes.h 和特定的头文件和配置项。而 C/OS-II 的系统文件依然只是包含 includes.h,即 C/OS-II 的系统文件完全不必改动。所有的配置改变包括头文件的增减均在 config.h 中进行,而 includes.h 定下来后不必改动(C/OS-II 的系统文件需要包含的东西是固定的) 。这样,C/OS-II 的系统文件需要编译的次数大大减少,编译时间随之减少。COS-II 不使用C语言中的 short、int、long等数据类型的定义,因为它们与处理器类型有关,隐含着不可移植性。代之以移植
10、性强的整数数据类型,这样,既直观又可移植。在使用周立功提供的 C/OS-II 模板的任何功能之前,必须调用函数OSInit(),它完成 C/OS-II 的初始化并建立空闲任务。在开始多任务之前,5必须建立至少一个用户任务(不包括 C/OS-II 的空闲任务) ,这是通过调用函数 OSTaskCreate()或函数 OSTaskCreateExt()实现。最后函数 main()调用函数 OSStart()将控制权交给 C/OS-II 内核 main()函数也就结束了。C/OS-II 应用程序主函数如下:程序清单 1int main (void)OSInit(); /初始化 uC/OS-IIOST
11、askCreate(TaskStart,(void *)0, /创建起动任务OSStart(); /开始多任务6第 3 章 ZLG/IP 软件包结构和配置3.1 ZLG/IP 软件包结构为了使软件可移植性强、易维护,该软件包采用分层的方法编写。包括网络传输用到的协议、硬件驱动及 C/OS-II 的结构进行分层。ZLG/IP 包相关文件说明如 表格 1 表格 1 软件包相关文件说明传输层有两个协议传输数据:传输控制协议 TCP 和用户数据报协议 UDP。 TCP 协议是面向连接的一个协议,可靠性高,费用也高;UDP 协议是提供最少服务和费用的传输层协议。UDP 是最简单的传输层协议,它具有以下特
12、点: 无连接:UDP 不基于连接来传输数据。 不可靠:UDP 的数据报发送时没有定序,所以UDP 传送的数据是不可靠的,只有靠应用层协议中增加超时重发等功能才能提供可靠的服务。 提供应用层协议标识:UDP 报头有定义应用层协议标识和目标应用层标识。 提供 UDP 报的校验和:UDP 报头包含有整个UDP 报(包括报头和有效负载)及伪报头的校验和,计算方法与计算 IP 数据报校验和的计算方法相同。 缓冲:UDP 协议不提供任何数据接收或发送的缓文件名 简要说明ARP.C 地址解析协议CRC.C 循环冗余码校验Ethernet.C 以太网标准HARDWARE.C 硬件驱动IP.C 网络互联协议IC
13、MP.C 因特网控制消息协议Socket.C 本地端口协议TCP.C 传输控制协议UDP.C 用户数据包协议7冲区。缓冲区应该由应用层协议提供。 分段:UDP 协议不提供分段传输方式,所以应用层协议要尽量发送小的包。SOCKET 接口函数是 TCP/IP 的 API。使用 SOCKET API 函数编写 UDP 通信的任务时,分为服务器方式两种。服务器方式是先接收到数据再进行处理,而客户机则是先发生数据后等待回应处理,它们用到的 SOCKET API 函数都是相同的。如 图 2 所示就是 UDP 通信时服务器端和客户机通信函数应用过程图。s o c k e t 创建套接字B l i n d (
14、 ) 本地 I P 和端口与套接字相连R e c v f r o m ( ) 和 s e n d t o ( ) 直接完成数据收发C l o s e s o c k e t ( ) 删除套接字结束s o c k e t 创建套接字B l i n d ( ) 本地 I P 和端口与套接字相连R e c v f r o m ( ) 和 s e n d t o ( ) 直接完成数据收发C l o s e s o c k e t ( ) 删除套接字结束服务器端 客户机端图 2 UDP 通信是 SOCKET API 函数的应用8第 4 章 设计过程4.1 设计步骤由于使用 DM9000 的网络控制芯片的
15、 Magic2200 的实验箱有点问题,后来我们改用使用 RTL8019AS 网络控制芯片的EasyARM2200 教学实验平台。1) 启动 ADS1.2,使用 ARM Executable Image for COS-II(lpc22xx)工程模板建立一个工程 shiyan。2) 把 COS-II 内核源码和移植文件,ZLG/IP 软件包目录拷贝到已建工程目录下,如 图 3 所示,arm 目录为移植文件目录,Source 目录为 COS-II 内核源码,tcpip 目录为 ZLG/IP 软件包目录。图 3 项目目录结构3) 修改 tcpipincludecfg_net.h 文件,修改 MAC
16、 地址为:0x00,0x14,0x97,0x0F,0x1F,0x9D、子网掩码为 255.255.0.0、IP 地址:172.30.172.77、本地网关地址为 PC 机 IP:172.30.172.125 。如 程序清单 29程序清单 2 MAC 和 IP 设置/* first Net Port Config */#define My_Mac_1ID 0x00,0x14,0x97,0x0F,0x1F,0x9D /将 RTL8019 的物理地址存储在程序空间?#define IP_MARK_1ID 255,255,0,0 /255.255.255.0,子网掩码#define MY_IP_1ID
17、 172,30,172,77#define MY_GATEWAY_1ID 172,30,172,125/*End Net Port Config */4) 修改 shiyansrcos_cfg.h 文件,OS_MAX_EVENTS 改为42,OS_LOWEST_PRIO 改为 62,OS_MAX_QS 改为 10。5) 在 ADS 的项目窗口中添加 TCPIP 的文件组;然后把tcpip目录下的ARPArp.c、ETHERNETEthernet.c、HARDWAREHardware.c、IPIp.c、 PINGIcmp.c、SOCKETzlg_socket.c 和TCPTcp.c、 UDPUd
18、p.c 等文件添加到该文件组,最后把程序编好添加到 ADS 项目窗口的 user 文件组中,如10图 4 shiyan 工程窗口6) 在 Startup.s 文件的 ResetInit 子程序中,修改存储器接口Bank3 总线配置,如程序清单程序清单 3 存储器接口 Bank3 总线配置LDR R0, =BCFG3 ;设置 BCFG3 寄存器LDR R1, =0x10001460STR R1, R04.2 实验程序4.2.1 宏定义首先对程序进行初始化宏定义,如 程序清单 4程序清单 4 初始化宏定义#include “config.h“#include “/include/cfg_net.h
19、“void Timer1_Init(void);#define TASK_START_ID 0 #define TASK_1_ID 111#define TASK_2_ID 2#define TASK_3_ID 3#define TASK_4_ID 4#define TASK_5_ID 5#define TASK_6_ID 6#define TASK_START_PRIO 10 #define TASK_1_PRIO 11#define TASK_2_PRIO 12#define TASK_3_PRIO 13#define TASK_4_PRIO 14#define TASK_5_PRIO 1
20、5#define TASK_6_PRIO 16#define MSG_QUEUE_SIZE 20 OS_EVENT *RecPackedFlag; OS_EVENT *RecBufOverFlowFlag;OS_EVENT *RecTcpPackedFlag;OS_EVENT *RecPingPackedFlag;OS_STK task0_stack3000;OS_STK task1_stack1000;OS_STK task2_stack2000;OS_STK task3_stack1000;OS_STK task4_stack2000;4.2.2 RTL8019AS 监听任务网络控制器监听
21、程序,如 程序清单 5程序清单 5 网卡监听任务void TaskB(void *pdata) /重要的监听 RTL8019AS 任12务void * UdpTemp;uint8 eer; while (1)UdpTemp=OSQPend(RecUdpQFlag,0,if(eer=OS_NO_ERR)Udp_Process(Rec_Ptr *)UdpTemp);eer=eer; 4.2.3 UDP 通信程序UDP 通信程序见 程序清单 6程序清单 6 UDP 服务器void TaskD(void *pdata) uint8 add36=“ZLGMCUyhbabcdefghijklmnopqrs
22、tuvwxyz“;/当接收到“A”时发送的数据uint8 add110=“123456789“;/当出错是发送的数据uint8 rec_buffer100; /发送缓存区SOCKET s; uint8 couter_byte=5; /重复发送的次数int rec_coute,send_coute;uint16 iii;struct sockaddr servaddr,clientaddr;OSTimeDly(60);13servaddr.sin_family=0; /设置客户机 IPservaddr.sin_addr0=172;servaddr.sin_addr1=30;servaddr.si
23、n_addr2=172;servaddr.sin_addr3=125;servaddr.sin_port=1026; /设置服务器端口号OSTimeDly(60);s=*socket( 0, SOCK_DGRAM, UDP_PROTOCOL);/建立 SOCKETclientaddr.sin_family=0; /设置本地 IPclientaddr.sin_addr0=172;clientaddr.sin_addr1=30;clientaddr.sin_addr2=172;clientaddr.sin_addr3=77;clientaddr.sin_port=1025; /设置本地监听端口号i
24、ii=bind( (SOCKET * ) /绑定服务器地址while (1)rec_coute=recvfrom( s, rec_buffer, 100, 0, (struct sockaddr*) /接收数据if(rec_coute0)if(rec_buffer0=A) /如果第一个数据是“A ”couter_byte=5;elsesend_coute=sendto(s, rec_buffer, rec_coute, 0, (struct sockaddr*) /把接收的数据返回while(couter_byte!=0) /循环发送数据send_coute=sendto(s, add, 34
25、, 0, (struct 14sockaddr*)if(send_coute=34)OSTimeDly(40);elsesend_coute=sendto(s, add1, 9, 0, (struct sockaddr*) /出错后发送的数据OSTimeDly(40);couter_byte-; 4.2.4 创建系统任务并初始化创建系统任务并初始化如 程序清单 7程序清单 7 系统任务void task0(void *pdata) /*在第 1 个任务中设置定时器 0 及中断*/UBYTE iii;#if OS_CRITICAL_METHOD = 3 OS_CPU_SR cpu_sr;#end
26、ifTargetInit(); OSTaskCreateExt(TaskB, /重要的监听RTL8019AS 任务(void *)0,OSTaskCreateExt(TaskD, /接受数据和发送数据(void *)0,SetNetPort();InitNic(0); /RTL8019 芯片初始化,在 global.c 中定义Initial_arp();Tcp_Initial();Udp_Initial();while(1) OSTimeDly(4);doiii=Rec_Packet();while(iii!=0);void Uart_SendChar(INT8U data)16while(U
27、0LSR U0THR = data;4.2.5 主程序程序清单 8 主程序int main (void)UBYTE iii;Timer1_Init();OSInit(); OSTaskCreateExt(task0,(void *)0,RecPackedFlag= OSSemCreate(0);RecBufOverFlowFlag= OSSemCreate(0);RecTcpPackedFlag= OSSemCreate(0);RecPingPackedFlag= OSSemCreate(0);SendFlag= OSSemCreate(1);RecIcmpQFlag=OSQCreate(Re
28、cTcpQFlag=OSQCreate(RecUdpQFlag=OSQCreate(17OSStart(); 4.2.6 定时器中断控制程序清单 9 中断控制void Timer1_Init(void)OS_ENTER_CRITICAL();T1IR = 0xffffffff;T1TC = 0;T1TCR = 0x01;T1MCR = 0x03;T1MR0 = 0xffffff;OS_EXIT_CRITICAL();void Timer1(void)static uint8 m_10sec=0;static uint8 p_sec=0;static uint8 p_min=0;uint8 nu
29、m;OS_ENTER_CRITICAL();T1IR = 0x01;m_10sec+;if(m_10sec=100)p_sec+;m_10sec=0;if(Ping_IP_TTL0)Ping_IP_TTL-;18for(num=0;num0)NetPortnum.ARP_TERMp_min.TTL-;if(Gateway_IP_TTL0)NetPortnum.Gateway_IP_TTL-;if(p_sec=60)p_min+;p_sec=0;if(p_min=60)p_min=0;VICVectAddr = 0; / 通知中断控制器中断结束OS_EXIT_CRITICAL();1920第 5
30、 章 实验结果将 EasyARM2200 教学实验平台上的 JP4 跳线短接,JP6 跳线设置为 Bank0-RAM 和 Bank1-FLASH,用配套的网线连接EasyARM2200 教学实验平台和 PC 机。选用 DebugInExram 生成目标,编译连接工程。选择 ProjectDebug,启动 AXD 进行 JTAG 仿真调试,全速运行。在 PC 机端打开 Windows 操作系统的“开始”“ 运行” ,键入“ping 172.30.172.77 t”如 图 5,然后单击“确定 ”,就可以看到 PING 成功的信息,如 图 6图 5 运行 ping 命令图 6 PING 成功21在
31、PC 机端打开光盘配套 UDPtest 软件,在远程主机地址栏键入 172.30.172.77,远程端口号填入 1025,本地端口号填入 1026就可以发送数据到 EasyARM2200 教学实验平台了,结果如 图 7所示,发送的数据被完整地返回了,如果发送以“A ”开始的字符串,就会返回 5 次“ZLGMCUyhbabcdefghijklmnopqrstuv wxyz” 。结果如 图 8 所示。图 7 返回发送的数据图 8 输入以 A 开头的字符串返回结果22第 6 章 课程设计体会参考文献1周立功.ARM 嵌入式系统基础教程.北京:北京航空航天大学出版社.20082周立功.ARM 嵌入式系统实验教程(三).北京:北京航空航天大学出版社.20083 马忠梅、马广云.ARM 嵌入式处理器结构与应用基础.北京: 北京航空航天大学出版社.20034ARM 公司.ARM Architecture Reference Manual.20005Jean.Labrosse. 嵌入式实时操作系统 C/OS-II(第 2 版).邵贝贝等译 . 北京航空航天大学出版社.2003