1 引言
在嵌入式系统时代,所有的设备都要网络化,这是未来科技发展的趋势。而在自动化领域有成千上万的传感器,控制器及其他设备。而他们之间最常用的通信接口就是 RS-232 串口。而随着通信技术的进步,这种简单的通信方法越来越不能适应需要。而高度成熟的网络技术为这一问题的解决提供了一种思路。在实际工作中,笔者为了通过Internet读取只有RS-232串口的传感器中数据,基于S3C4510B设计了一个串口网络服务器的最小系统。
2 硬件设计
本系统微处理器采用三星公司的硬件S3C4510B,网口控制芯片采用Realtek公司的RTL8201,串口控制芯片采用常见的MAX232.主要芯片都是高度集成,接线简洁,原理清晰。体系结构如图1所示。
2.1 S3C4510B简介
S3C4510CPU芯片是samsung公司arm7TDMI系列中的一个型号,其工作频率为50MHZ,片内集成了丰富的通用模块,含有支持10M/100M自适应的以太网控制器,可以直接通过PHY芯片引出以太网接口。已太网PHY芯片选用Intel公司的lxt972a芯片,它具有10M、100M自适应收发功能,支持全双工操作,经过网络变压器YL18-2050S连接到RJ45,进行收发数据包功能。此外,该系统还使用聊2MBFlash,16MBSDRAM和512KBSRAM作为存储器。
2.2 FLASH存储器接口电路
FLASH闪存闪存的英文名称是"FlashMemory",一般简称为"Flash",它属于内存器件的一种。不过闪存的物理特性与常见的内存有根本性的差异:目前各类DDR、SDRAM或者RDRAM都属于挥发性内存,只要停止电流供应内存中的数据便无法保持,因此每次电脑开机都需要把数据重新载入内存;闪存则是一种不挥发性(Non-VolaTIle)内存,在没有电流供应的条件下也能够长久地保持数据,其存储特性相当于硬盘,这项特性正是闪存得以成为各类便携型数字设备的存储介质的基础。
本系统中采用的Flash存储器日本富士公司生产的MBM29F016.具有16M位(2M字节)、单一5V供电的闪速存储器。2M字节的数据区被分为32个64k字节的区段,因而具有灵活擦除功能。
Flash在本系统中用来存放uClinux操作系统程序代码。系统上电或复位后从此处获取指令并开始执行。因此S3C4510B的nRCS<0>接至MBM29F016的CE#端。RES#端接系统服务信号。OE#接S3C4510B的nOE,
WE#端接S3C4510B的nWBE<0>.地址总线[a19~A0]与S3C4510B的地址总线[ADDR19~ADDR0]相连。16位数据总线[DQ15~DQ0]与S3C4510B的低16位数据总线[XDATA15~XDATA0].
2.3 SDRAM接口电路
SDRAM:SynchronousDynamicRandomAccessMemory,同步动态随机存储器,同步是指Memory工作需要同步时钟,内部的命令的发送与数据的传输都以它为基准;动态是指存储阵列需要不断的刷新来保证数据不丢失;随机是指数据不是线性依次存储,而是自由指定地址进行数据读写。SDRAM从发展到现在已经经历了四代,分别是:第一代SDRSDRAM,第二代DDRSDRAM,第三代DDR2SDRAM,第四代DDR3SDRAM.(显卡上的DDR已经发展到DDR5)
与Flash存储器相比较,SDRAM不具有掉电保持数据的特性,但其存取速度大大高于Flash存储器,且具有读/写的属性。因此,SDRAM在系统中主要用作程序的运行空间、数据及堆栈区。当系统启动时,CPU首先从复位地址0x0处读取启动代码,在完成系统的初始化后,程序代码一般应调入SDRAM中运行,以提供系统的运行速度。同时,系统及用户堆栈、运行数据也都存放在SDRAM中。与Flash存储器相比,SDRAM的控制信号较多,其连接电路也相对复杂。
本系统采用两片HY57V641620并联构成32位的SDRAM存储系统,其中一片为高16位,另一片为低16位。两片HY57V641620的CLK端接的SDCLK端。两片HY57V641620的CLE端接S3C4510B CLE端。两片HY57V641620的A11~A0接S3C4510B ADDR<11>~ADDR<0>;高16位片的DQ15~DQ0接S3C4510B 的数据总线的高16位XDATA<31>~XDATA<16>;低16位片的DQ15~DQ0接S3C4510B的数据总线的低16位XDATA<15>~XDATA<0>.
2.4 RTL8201接口电路
RTL8201是Realtek公司生产的一种全双工以太网控制器,由于其优良的性能、廉价的价格,使其在市场上10MbpsiISA总线网卡中占有相当的比例。按数据链路的不同,可以将RTL8201内部划分为远程DMA(remote,DMA)通道和本地DMA(local DMA)通道两部分。本地DMA完成控制器与网线的数据交换,主处理器收发数据只需对远程DMA操作。当主处理器要向网上发送数据时,先将一帧数据通过远程DMA通道送到RTL8201中的发送缓存区,然后发出传送数据命令。RTL8201在完成了上一帧的发送后,再完成此帧的发送。RTL8201接收到的数据通过MAC比较,CRC校验后,由FIFO存到接收缓冲区,收满一帧后,以中断的方式通知主处理器。
由于S3C4510B片内已有带MII接口的MAC控制器,而RTL8201也提供了MII接口,各种信号的定义也很明确,因此RTL8201与S3C4510B的连接也比较简单。直接将两者的同名端连接即可。
2.5 Max232接口电路
Max232产品是由德州仪器公司(TI)推出的一款兼容RS232标准的芯片。该器件包含2驱动器、2接收器和一个电压发生器电路提供TIA/EIA-232-F电平。该器件符合TIA/EIA-232-F标准,每一个接收器将TIA/EIA-232-F电平转换成5-VTTL/CMOS电平。每一个发送器将TTL/CMOS电平转换成TIA/EIA-232-F电平。
MAX232芯片时MAXIM公司生产的低功耗、单电源双RS232发送/接收器。适用于各种EIA-232E和V.28/V.24的通信接口。MAX232芯片内部有一个电源电压变换器,可以把输入的+5V电源变换城RS-232C输出电平所需10V电压,所以采用此芯片接口的串行通信系统只要单一的+5V电源就可以。
现选用其中一路发送/接受。T1I接S3C4510B的TXD0端,R1O接S3C4510B的RXD0端。因为MAX232具有驱动能力,所以不需要外加驱动电路。
3 软件设计
本系统采用uClinux作为操作系统。与一般全靠硬件实现的串口服务器比较起来,配置要复杂,需要用户具有一定的技术背景,不过因为带有操作系统,其灵活性也是硬件串口服务器所不能比拟的。用户可以通过编写应用程序,来随意扩展所需的功能。
uCLinux是一种优秀的嵌入式Linux版本,是micro-Conrol-Linux的缩写。它秉承了标准Linux的优良特性,经过各方面的小型化改造,形成了一个高度优化的、代码紧凑的嵌入式Linux.虽然它的体积很小,却仍然保留了Linux的大多数的优点:稳定、良好的移植性、优秀的网络功能、对各种文件系统完备的支持和标准丰富的API.它专为嵌入式系统做了许多小型化的工作,目前已支持多款CPU.其编译后目标文件可控制在几百KB数量级,并已经被成功地移植到很多平台上。具有以下优点:
(1) Linux是开放源代码的,不存在黑箱技术,遍布全球的众多Linux爱好者都是Linux开发者的强大技术支持者。
(2) Linux源代码随处可见,注释丰富,文档齐全,易于解决各种问题。
(3) Linux的内核小,效率高。
(4) Linux内核的结构在网络方面是非常完整的,它提供了对包括十兆位、百兆位及千兆位的以太网络,还有无线网络,以及光纤等的支持。
(5) Linux在内核结构的设计中考虑适应系统的可裁减性的要求。可将无用的代码去除掉,近一步减少内核规模。
3.1 串口程序的设计
Linux对所有各类设备文件的输入输出擦作看上去就像对普通文件的输入输出一样。所以Linux对串口的操作,也是通过设备文件访问的。为了访问串口,只需打开相应的设备文件即可。在Linux下,默认串行口COM1和COM2对应的设备分别为/dev/ttyS0 和/dev/ttyS1.
(1) 打开串口是通过使用标准的文件打开函数操作:
int fd;
/*以读写方式打开串口*/
fd = open( "/dev/ttyS0", O_RDWR);
if (-1 == fd){
/* 不能打开串口一*/
perror(" 提示错误!");
}
(2) 设置串口
最基本的设置串口包括波特率设置,效验位和停止位设置。串口的设置主要是设置 struct termios 结构体的各成员值。
struct termio
{ unsigned short c_iflag; /* 输入模式标志 */
unsigned short c_oflag; /* 输出模式标志 */
unsigned short c_cflag; /* 控制模式标志*/
unsigned short c_lflag; /* local mode flags */
unsigned char c_line; /* line discipline */
unsigned char c_cc[NCC]; /* control characters */
};
(3) 发送数据
char buffer[1024];int Length;int nByte;nByte = write(fd, buffer ,Length)
(4) 读取串口数据
使用文件操作read函数读取,如果设置为原始模式(Raw Mode)传输数据,那么read函数返回的字符数是实际串口收到的字符数。可以使用操作文件的函数来实现异步读取,如fcntl,或者select等来操作。
char buff[1024];int Len;int readByte = read(fd,buff,Len);
3.2 网络程序的设计
Linux系统是通过提供套接字(socket)来进行网络编程的。网络程序通过socket和其它几个函数的调用,会返回一个 通讯的文件描述符,我们可以将这个描述符看成普通的文件的描述符来操作,这就是linux的设备无关性的 好处。我们可以通过向描述符读写操作实现网络之间的数据交流。以下介绍一下程序设计时常用的函数。
(1) socket
int socket(int domain, int type,int protocol)
domain:说明我们网络程序所在的主机采用的通讯协族(AF_UNIX和AF_INET等)。
type:我们网络程序所采用的通讯协议。
protocol:由于我们指定了type,所以这个地方我们一般只要用0来代替就可以了。
(2) bind
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
sockfd:是由socket调用返回的文件描述符。
addrlen:是sockaddr结构的长度。
my_addr:是一个指向sockaddr的指针。
(3) listen
int listen(int sockfd,int backlog)
sockfd:是bind后的文件描述符。
backlog:设置请求排队的最大长度。当有多个客户端程序和服务端相连时, 使用这个表示可以介绍的排队长度。 listen函数将bind的文件描述符变为监听套接字。返回的情况和bind一样。
(4) accept
int accept(int sockfd, struct sockaddr *addr,int *addrlen)
sockfd:是listen后的文件描述符。
(5)connect
int connect(int sockfd, struct sockaddr * serv_addr,int addrlen)。
sockfd:socket返回的文件描述符。
serv_addr:储存了服务器端的连接信息。其中sin_add是服务端的地址。
addrlen:serv_addr的长度。
connect函数是客户端用来同服务端连接的。
总的来说网络程序是由两个部分组成的--客户端和服务器端。它们的建立步骤一般是: 服务器端 socket-->bind-->listen-->accept.客户端 socket-->connect.
4 结语
经过几个月的运行,证明稳定可靠。由于ARM系列微处理器的优异性能,本系统上完全可以再加上1/2/4/8个RS-485/422/232串口,轻松连接网络并管理数量众多且分散在不同位置的串行设备。