基于嵌入式系统的串口网络服务器的设计
扫描二维码
随时随地手机看文章
1 引言
在后PC嵌入式系统时代,所有的设备都要网络化,是未来科技发展的趋势。而在自动化领域有成千上万的传感器,控制器及其他设备。而他们之间最常用的通信接口就是RS-232串口。而随着通信技术的进步,这种简单的通信方法越来越不能适应需要。而高度成熟的网络技术为这一问题的解决提供了一种思路。在实际工作中,笔者为了通过Internet读取只有RS-232串口的传感器中数据,基于S3C4510B设计了一个串口网络服务器的最小系统。
2 硬件设计
本系统微处理器采用三星公司的硬件S3C4510B,网口控制芯片采用Realtek公司的RTL8201,串口控制芯片采用常见的MAX232。主要芯片都是高度集成,接线简洁,原理清晰。体系结构如图1所示。
2.1 S3C4510B简介
本系统CPU选用Samsung公司的S3C4510B。S3C4510B是基于以太网应用系统的高性价比16/32位RISC微控制器,内含一个有ARM公司设计的16/32位ARM7TDMI RISC处理器,ARM7TDMI为低功耗高性能的16/32核。最适合用于对价格及功耗敏感的应用场合。
2.2 Flash存储器接口电路
Flash存储器实在EPROM和EEPROM的制造基础上产生的一种非易失存储器。该存储器集成度高,制造成本低于DRAM,即具有SRAM读写的灵活行和较快的访问速 度又具有ROM在断电之后不丢失信息的特点所以发展迅速。Flash在系统中通常用于存放程序代码,常量表以及一些在系统掉电后需要保存的用户数据。
本系统中采用的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]。[!--empirenews.page--]
2.3 SDRAM接口电路
SDRAM是高速的动态随机存取存储器,它的同步接口和完全流水线的内部结构使其拥有极大的数据速率。目前SDRAM时钟频率已达100MHz以上。另外他们的行、列地址线共用。由行地址选通(CAS)、列地址选通(RAS)信号分时控制。SDRAM内部以bank位组织,可由行、列地址寻址。另外为了保持内部数据还必须进行刷新。
与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芯片时MAXIM公司生产的低功耗、单电源双RS232发送/接收器。适用于各种EIA-232E和V.28/V.24的通信接口。MAX232芯片内部有一个电源电压变换器,可以把输入的+5V电源变换城RS-232C输出电平所需10V电压,所以采用此芯片接口的串行通信系统只要单一的+5V电源就可以。
现选用其中一路发送/接受。T1I接S3C4510B的TXD0端,R1O接S3C4510B的RXD0端。因为MAX232具有驱动能力,所以不需要外加驱动电路。
3 软件设计
本系统采用uClinux作为操作系统。与一般全靠硬件实现的串口服务器比较起来,配置要复杂,需要用户具有一定的技术背景,不过因为带有操作系统,其灵活性也是硬件串口服务器所不能比拟的。用户可以通过编写应用程序,来随意扩展所需的功能。
Uclinux是一个完全符合GNU/GPL公约的操作系统,完全开发代码,并且免费。Uclinux即“微控制领域中的Linux系统”,具有以下优点:
(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等来操作。 [!--empirenews.page--]
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 结语
本串口服务器,采用三星公司的S3C4510B ARM7系列微处理器及uClinux操作系统,通过编程实现了串口数据到以太网口或以太网口到串口的数据转换。经过几个月的运行,证明稳定可靠。由于ARM系列微处理器的优异性能,本系统上完全可以再加上1/2/4/8个RS-485/422/232串口,轻松连接网络并管理数量众多且分散在不同位置的串行设备。