基于S7600A的嵌入式系统Internet接入方案
2009-03-03
作者:李燕青 于振生
摘 要: TCP/IP协议栈大规模集成电路S7600A的结构、功能、硬件接口和应用程序接口;介绍一个基于实时多任务操作系统μC/OS的S7600A应用方案,此方案实现了嵌入式系统的Internet接入。
关键词: TCP/IP API 实时操作系统(RTOS) 多任务嵌入式系统
随着电子设备智能化要求的提高和各种功能强大的微处理器的推出,嵌入式系统逐渐成为许多电子设备不可缺少的一部分,并处在前所未有的发展期;而互联网概念的深入人心更为嵌入式系统与互联网的结合提出了要求。嵌入式系统接入Internet以后,不仅实现了设备的远程控制、维护和升级,而且从另外一层意义上讲,接入Internet的设备已经成为网络共享资源的一部分。可以说这是自电子设备智能化以来设计思想的又一次飞跃。
嵌入式系统接入Internet的关键是满足TCP/IP协议。TCP/IP协议是建立在数据链路层、网络层、传输层和应用层上的协议族,是Internet的基础。各种型号计算机运行在不同操作系统之上,TCP/IP协议族允许它们互相通信。通常,一个嵌入式系统接入Internet,可选择一个提供TCP/IP协议的嵌入式操作系统,或是在现有操作系统之上加入TCP/IP软件协议栈,实现TCP/IP连接。对于嵌入式系统,TCP/IP软件协议栈也构成了系统成本的一部分,而这部分投入占有不小的比例。同时,软件协议栈的引入无疑要占用更多的系统资源,对于嵌入式系统来说是很可观的。S7600A TCP/IP硬件协议栈芯片很好地解决了资源和成本有限的嵌入式系统的Internet接入问题。
1 S7600A的内部结构
S7600A内部结构如图1所示,它由网络栈、物理层接口、微控制器接口、SRAM接口和片内SRAM组成。(1)网络栈是该芯片的核心。它建立在物理层上,包含有实现TCP/IP协议的特殊的层次化的数据结构,并完成数据的包装或剥离。其内部又可以分为PPP(点对点协议)、IP(网际协议)、TCP(传输控制协议)/UDP(用户数据报协议)几个层次。(2)物理层接口是实现协议的最底层接口。在这里以UART的形式提供对外连接,可以通过外接Modem实现Intenet接入。(3)微控制器接口提供了与68k/x86(Motorola/Intel)MPU的标准并行接口和非标准的串行接口(串/并模式由PSX来选择)。在x86/68k并行模式下,由C86来选择x86或68k。SD[7:0]为地址/数据复用总线,CS为片选输入,READX和WRITEX为读写信号,RS为寄存器选择输入,用来指示地址和数据。在串行模式下,SD7为串行数据输入,SD6为串行时钟输入,SD5为串行数据输出,WRITEX用来切换读和写。另外芯片提供了中断输出,用来给MPU发特定请求。BUSYX用做忙指示。
2 S7600A内部寄存器和数据传输实例
S7600A有36个内部寄存器,有单字节、多字节,也有变长的(如PPP_String寄存器,用来存放PAP用户名和指令,其长度与用户名和口令的实际长度相关)。对内部寄存器的读写可以实现对S7600A的各种操作,其中若干寄存器用来做TCP/IP的协议接口。由于寄存器数量较多,这里不一一介绍,仅举一个TCP数据的传输实例来说明对该芯片的操作。
一个IP地址和一个端口号可以称为一个插口(Socket)。而一个插口对可以唯一地确定互联网络里的一个TCP连接。在进行以下操作之前事先要建立一个TCP连接。
首先,将Serial_Port_Config寄存器(08H)里的SCTL标志位置1,把对串口的控制权交给硬件(S7600A),把要传输的数据写到Socket_Data寄存器(2EH)里,S7600A就会把数据通过该寄存器放到输出缓冲区(1K字节长度)。注意输出缓冲区地址在Buffer_Out_Length寄存器(30H-31H)里。当输出缓冲区为全空时,该寄存器里的值是3FFH,用户每向Socket_Data寄存器里写一个字节的数据,Buffer_Out_Length寄存器的值就会自动减一。
当用户要发送TCP数据时,只要向Data_Send寄存器(30H)里写任意一个字节的数据,S7600A就会对输出缓冲区里的数据进行TCP数据处理(自动加入TCP首部,形成TCP段;再加入IP首部,形成IP数据报;最后在串行链路上封装IP数据报,形成PPP数据帧,如图2所示。),然后通过UART接口发送出去。同时Buffer_Out_Length寄存器的值会复原到3FFH。注意输出缓冲区最大1K字节,超过该值是不允许的。
3 基于S7600A的接入方案
3.1 系统构成
基于S7600A的接入方案如图3所示,系统采用通用单片机AT89C51为控制核心。单片机既可以通过并行总线又可以通过串行总线与S7600A相连(在串行时用I/O口实现串行时序),通过对S7600A的操作实现TCP/IP协议。S7600A经UART接口与嵌入式Modem相接,经电话线接入Internet。应用程序与远程服务器或客户机建立TCP或UDP连接,在此基础上实现多种应用,如FTP、SMTP、POP3、Telnet、IP电话服务等。从网上获取的信息可以经系统总线传给嵌入系统的其他部分或者直接显示在LCD上,同样系统产生的信息也可以发送到网络上。
3.2 系统的软件设计
(1) 嵌入式实时多任务操作系统
在这个系统里,引入了实时操作系统(RTOS)。通常对单片机的开发是在硬件的基础上直接进行编程,这种方法一般用于规模较小、较简单的系统,对于规模较大、较为复杂的系统会产生一定的隐患,属于较低层次的开发。近年来,在嵌入式应用中使用实时多任务操作系统已经成为一个热点、一种时尚,从本质意义上讲,是系统开发层次的一种提高。在实时多任务操作系统的支持下,多个任务可以按照一定关系并行工作,CPU资源得到充分利用,系统可靠性得到很好的保证,同时方便组织开发任务。
当前出现了很多商业的RTOS,但一般价格比较昂贵,代码不公开。本系统使用开放源代码的RTOS μC/OS,这个RTOS已经在很多系统上进行了成功的应用,同时已经被移植到8051上。
(2) S7600A应用程序接口(API)
S7600A以硬件的形式提供了TCP/IP协议的简单端口。即便如此,对其内部众多寄存器进行寻址操作也并不容易,建立TCP/IP连接仍然是比较复杂的过程。幸运的是,厂商为其提供了API函数集,通过调用该函数集,可以实现S7600A的所有功能。这个函数集是建立在RTOS上的。但是这套API又具有硬件和平台的独立性,非常有利于在各种系统上移植,这种特性为实际开发项目的层次化组织创造了非常有利的条件。其硬件独立性是通过API里的两个文件iHwIFace.h和iHwIFace.c实现的,用户在重写这两个文件后,可以使API用在不同的CPU上,它实际相当于S7600A的底层驱动程序。在这个系统里要根据AT89C51和S7600A的编址连接来确定这两个文件。其平台独立性是通过API里的iSys.h和iSys.c实现的,用户在重写这两个文件后,可以使API运行在不同的操作系统上,在该公司提供的这套API里已经附带了基于μC/OS的这两个文件。
该API包括两个主要部分:iStacApi(实现PPP)和iSockApi(实现Socket连接),对S7600A的功能进行了简单而有效的封装,为应用软件的开发提供了方便。如表1、表2所示。
(3)应用程序
应用程序建立在RTOS和API之上,并可以实现多任务,在编译完毕后和RTOS库以及API库一起连接生成可执行代码,如图4所示。
在系统需要接入Internet传输数据的时候,首先要通过Modem拨号,建立PPP连接,然后再根据数据传输的具体需要决定建立TCP连接还是UDP连接。一般情况下,TCP 建立可靠的连接,可以实现诸如FTP、SMTP等服务;而像IP电话这样强调实时性的场合,需要建立UDP连接。
在需要上网的时候,运行以下程序,可以实现与ISP(网络服务提供商)之间的拨号连接。首先,程序调用IsInitStack(),初始化S7600A的硬件协议栈子系统。如果初始化成功(得到RET_CODE_OK的返值),就开始进行拨号连接。调用IsPPPCheck()检查是否已经连接,如果还没有连接,就调用IsPPPConnect()进行拨号(该函数的参数含有进行拨号连接的要素:pdata.name表示拨号上网的用户名,例如拨169时,用户名就指定为“169”;pdata.passwd表示用户口令,例如拨169时,该口令就指定为“169”;pdata.modemInitStrings存放初始化Modem用的指令,符合Modem AT指令集,“AT”为Modem指令的前缀。例如,“AT+FAE=0”表示关闭data/fax自动应答模式,“ATE0”表示禁止指令回应;pdata.baudRate为波特率;pdata.modemDialString为拨号号码,此处为电话号码169,“DT”表示用双音频拨号);如果已经建立了连接,就调用IsGetOurIP()得到IP地址或者调用IsPPPKeepAlive()保持连接。
#include
#include
#define L_Time 10000
static int do_connect=1, was_connect=0;
static iIPAddr ip;
ppp_task(void)
{
RET_CODE rc; //RET_CODE为API函数执行状态返值的数据类型
iPPPData pdata; //该数据结构包含建立PPP连接的必要数据
static char *initStrings[5];
initStrings[]=“AT+FAE=0n”; //在字符串数组里存放Modem初始化指令
initStrings[]=“ATE0n”;
initStrings[]=0; //设定该字符为NULL
initStrings[]=0;
initStrings[]=0;
pdata.name=“169”; //拨号上网的用户名
pdata.passwd=“169”; //拨号上网的用户口令
pdata.baudRate=28800; //设置波特率
pdata.hwFlowCtrl=1; //启用硬件流控制
pdata.useModem=1;
pdata.modemDialString=“ATDT 169”; //ATDT为双音频拨号指令
pdata.auth=IPPP_AUTH_PAP; //提供PAP验证
pdata.modemInitStrings=initstrings; //Modem初始化的系列指令,必须以NLLL结尾
rc=IsInitStack(); //初始化硬件栈子系统
if{rc==RET_CODE_OK}
{
while(do_connect)
{
rc=IsPPPCheck(); //检查PPP 连接是否激活
if(rc==RET_CODE_OK)
{
if(was_connect==0)
{
rc=IsGetOurIP(&ip); //获取IP地址
was_connect=1;
}
}
else if(was_connect)
{
was_connect=0;
rc=IsPPPKeepAlive(L_TIME)//在连接失效时重新建立连接
}
else
{
rc=IsPPPConnect(&pdata,L_TIME);//拨号并与ISP建立PPP连接
continue;
}
smallSleep(L_TIME);
}
}
}
基于RTOS和S7600A的嵌入式系统Internet接入方案硬件上简洁可靠、成本适中;软件开发上体现了较好的层次思想和较高的技术水准,可维护性好,可扩展性好。
参考文献
1 Seiko Instruments Inc. S7600A Datasheet.2000.
2 Seiko Instruments Inc.S7600A Network Stack Driver APIs.
3 W.Richard Stevens. TCP/IP Illustrated Vol.1 The Protocols
4 Miller Freeman,Inc. μC/OS-II:the Real Time Kernel.