- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
XMLHttP对象在嵌入式Web实时系统中的应用
摘要:就Ajax技术中的XMLHttp对象在基于Web的嵌入式远程控制与实时监测系统中的应用开发进行了研究,并基于Microchip TCP/IP协议栈给出了具体的实现方法,有效地解决了客户端Web与嵌入式HTTP服务器的交互问题。
关键词:嵌入式系统;TCP/IP;Web开发;Ajax;XMLHttp;Javascript
引言
传统的Web应用在交互操作过程中频繁出现全页刷新的问题无法避免,即使当前页面中仅有局部信息是需要动态刷新显示的。这不仅影响到界面效果,在实时监测过程中还会明显影响服务器的响应速度。
Ajax技术的出现为解决客户端Web与嵌入式HTTP服务器之间的交互问题提供了重要途径。Ajax是异步Javascript与XML的简称,这一概念由Jesse James Garrett提出,它是一组与Web开发相关的技术,包括基于HTML/XHTML与CSS标准的页面表示、基于DOM的动态显示和交互,以及基于XMLHttpRequest与服务器之间的异步通信。所有上述技术通过Javascript绑定在一起。
嵌入式以太网实时系统开发者可以尝试通过Ajax的核心对象XMLHttp在“后台”与嵌入式HTTP服务器交瓦,对服务器发起远程控制,读取服务器动态返回的监测信息并刷新显示在客户端Web界面中的特定位置,且所有操作均不会导致当前Web界面被全页刷新。
本文以Microchip公司的TCP/IP协议栈为基础,讨论XMLHttp对象在嵌入式Web实时系统中的具体应用方法。所选用的测试电路以PIC18F4 52单片机与以太网接口芯片RTL8019AS为核心,嵌入式HTTP服务器所有Web相关文件保存在系统外部EEPROM存储器中。
1 XMLHttp在客户端Web中的应用
XMLHttp是Ajax技术的核心,由微软公司在IE5.0浏览器中率先推出,后被命名为XMLHttpRequest。
1.1 客户端Javascript函数
1.1.1 创建XMLHttp对象的通用函数
客户端与嵌入式系统HTTP服务器的所有交互都将基于在客户端所创建的XMLHttp对象。该函数在IE中创建XMLHttp对象的语句为:
创建XMLHttp对象后最重要的操作是设置onreaclystatechange属性(非IE中为onload),为其绑定异步回调函数。当XMLHttp对象状态变化时,所指定的回调函数将自动处理服务器回应数据。
1.1.2 客户端发送控制命令的函数
(1)Send_Control_CMD(URL,Html_id)
该函数可由客户端Web中的控制命令按钮点击事件onClick触发调用,它调用CreateXMLHttpObj创建XMLHttp对象,设置回调函数,然后以GET方法对HTTP服务器发起请求。函数的第一个参数URL可以是控制命令串,也可以是CGI、HTML及其他各种Web文件名。如果要求在客户端Web中显示HTTP服务器返回信息,则需要设置第二个参数Html_id。例如,在发送控制命令点亮系统中某个指示灯后,要求将服务器返回的该指示灯的当前状态显示在客户端。所设置的参数Html_id是客户端Web页中的某个容器的ID,返回信息将显示到该容器中。如果不需要服务器回应文本信息,或对回应信息不予处理,可将该参数设为空。函数具体实现如下:
Send_Control_CMD在每次被涮用时首先创建一个通用对象Obj,然后创建XMLHttp对象,并将其保存在自定义的Obj.xmlhttpobj属性中,随后调用XMLHttp对象的open方法与send方法,调用格式为:
oXMLHttpRequest.open(bstrMethod,bstrUrl,varAsync,
bstrUser,bstrPassword);
oXMLHttpRequest.send(varBody);
其中open方法的bstrMethod参数为HTTP请求的方法,例如所选择的“GET”方法,bstrUrl参数为请求的URL地址,在本文讨论的嵌入式Web实时系统中,它用来表示控制命令串,譬如用来启动外部直流电机的控制命令串“0
1=MOTOR”,varAsync参数用于指定当前请求是否为异步方式,默认为true,最后两个参数提供帐号密码,用于服务器验证。通过open方法初始化XMLHttp对象以后,要用send方法发送请求到HTTP服务器并等待回应。由于XMLHttp对象被设为异步模式,send调用将不会被阻塞,XMLHttp对象的回调函数mReadyCallBack将在HTTP服务器回应时异步执行。 [p]
由于Web页中可能有多个不同按钮要发送不同的控制命令,为简化程序设计且便于管理对象,可将每一按钮调用该函数创建的xMLHttp对象统一保存到全局对象数组ObjArray中。对象数组ObjArray由Web页中的Javascript脚本定义,即:
<script language=“Javascript”>
var ObjArray=new Array;……
(2)mReadyCallBack()
它是Send_Control_CMD函数所创建的保存于对象数组ObjArray中的每个XMLHttp对象的异步回调函数,通过该函数可统一异步处理服务器回应数据。函数具体实现如下:
当ObjArray中的任意一个XMLHttp对象的就绪状态变化时,将触发对mReadyCallBack函数的异步调用,该函数将通过for循环扫描对象数组ObjArray,对HTTP服务器当前回应的对象进行处理。通过XMLHttp对象的responseText属性可获取服务器回应信息,通过Web容器的inner HTML属性可将回应信息显示到Web页中。在处理完当前XMLHttp对象以后,mReadyCallBack最终将用delete释放该对象所占用的资源。如果调用Send_control_CMD函数时第2个参数为空,则表示发出控制命令后不需要处理服务器回应文本信息,回调函数仅仅需要释放该对象所占用的资源。
1.1.3 实现客户端实时监测功能的函数
(1)RealTime_Monitoring()
该函数专门用于实时监测动态数据,它由Web页面加载事件onLoad触发调用,通过所创建的xMLHttp对象向服务器请求动态文件Status.cgi,以获取监测数据。
其中xmlhttp定义为全局变量。
(2)aReadyCallBack()
该函数是实时监测系统外设数据函数RealTime_Monitoring所创建的XMLHttp对象的专用回调函数,它在处理HTTP服务器回应时将返回的动态监测数据显示在ID为“txtStatus”的Web容器中,譬如<span id=“txtStatus”>…</span>,所返回的内容将替换其中的“…”。函数具体实现如下:
回调函数aReadyCallBack与回调函数mReadyCallBack的差别在于:它释放已经处理回应的XMLHttp对象(置为null)以后,接着执行了一项重要工作,即调用实时监测函数RealTime_Monitoring()。通过创建新的XMLhttp对象,将动态请求与显示刷新“接力”进行下去,从而使实时监测无限延续。
显然,通过XMLHttp对象所实现的实时监测,其效果远远优于传统的Web请求与响应操作模式下所使用的通过在网页头部加入<meta http-equiv=“refresh”content=“定时长度”>,或者使用Javascript的setTimeout函数设置超时值,使客户端自动按固定时间间隔请求服务器刷新显示动态信息的方法。
1.2 客户端Web与嵌入式HTTP服务器的交互操作
有了上述以XMLHttp对象为中心的函数定义,完成客户端Web与嵌入式HTTP服务器之间的交互操作就很容易了,例如:
①通过Web页按钮启动电机.可有<input type=“button”onClick=“Send_Ctrl_CMD(’0
1=MOTOR’,’)”value=“运行”>。按钮事件触发对Send_Control_CMD的调用,它通过XMLHttp对象在“后台”发送命令串“O
1=MOTOR”,提交给嵌入式系统HTTP服务器处理,控制电机启动,实现远程控制功能。
②实时监测嵌入式系统外设状态,可有<body onLoad=“ReaITime Monitoring();”>。Web页面加载事件onLoad触发对RealTime_Monit oring的函数调用,它同样也通过XMLHttp对象访问嵌入式系统HTTP服务器,不同的是它所请求的是动态文件status.cgi。现假设所访问的动态文件主要内容如下:
<td width=“150”>%02</td>
<td width=“200”>LED1:%00 LED2:%01</td>
<td width=“168”>%10</td>
嵌入式系统HTTP服务器程序将从MPFS文件系统读取该动态文件并将其发往客户端。在发送过程中,HTTP服务器将对所遇到的形如“%xx”的变量码进行解析处理。例如“%02”被定义为测试电路中AN0通道的A/D值,“%00”“%01”被定义为两个外接LED的开关状态,“%10”被定义为所控制的直流电机的启/停状态。经过HTTP服务器处理后的变量值将被系统当前实际的外设状态值所替换并返回到客户端。
由于RealTime_Monitoring函数与aReadyCallBack函数配合实现了XMLHttp对象的创建、请求、异步响应、释放,再创建、再请求、再异步响应、再释放等,从而借助XMLHttp对象在“后台”实现了理想的实时监测功能。由于监测结果实时刷新显示在Web中的特定容器位置,不会导致全页刷新问题,这也为用户操作带来了良好体验。
解决了客户端通过XMLHttp埘象在“后台”与HTTP服务器进行交互、发送控制命令及异步处理回应、实现实时监测功能的问题以后,接着要解决的是HTTP服务器端如何处理客户端XMLHttp对象所发送的控制命令,以及如何处理并返回客户端XMLHttp对象所请求的动态文件。 [p]
2 HTTP服务器功能简介
Microchip TCP/IP协议栈是一套服务于标准的、基于TCP/IP的应用程序,可应用于HTTP服务器、FTP服务器等,它遵循了TCP/IP参考模型,协议栈按照模块化方式实现。Microchip整个TCP/IP协议栈的代码全部用C语言编写,每层的实现代码驻留在一个独立的C程序文件中,服务和应用程序编程接口则通过头文件或C程序文件定义,协议栈可使用MCC18或HI—TECH PICC 18编译,图1对比了TCP/IP参考模型与Microchip TCP/IP协议栈。
为实现HTTP服务器功能,协议栈所提供的相关文件主要有TCP.c与HTTP.c,它们分别处理客户端与服务器端的连接及对HTTP请求的处理。在启动嵌入式系统HTTP服务器时,主程序首先调用两个初始化函数:StackInit()与HTTPInit()。前者初始化协议栈,包括MACInit()、ARPInit()、TCPInit();后者初始化HTTP服务器,使所有的HTTP连接处于监听状态,受嵌入式系统资源限制,实际支持的最大连接数默认为3个。
HTTP服务器主程序接下来的主要工作是在while(1)中循环调用HTTPServer()函数,处理客户端对HTTP服务器的请求并作出响应。HTTPSer ver实际执行的任务是循环扫描每个HTTP连接,并在每个连接上调用处理HTTP请求的函数HTTPProcess()。该函数对客户端发送的控制命令串的处理及动态文件的请求处理将分别通过回调函数HTTPExecCmd和HTTPGetVar完成,这两个核心回调函数由主程序具体实现。
3 动态响应XMLHttp对象请求的核心函数
对于客户端Web页内onClick事件与onLoad事件触发的以下两个调用示例,它们都基于XMLHttp对象,前者向嵌入式HTTP服务器发送控制命令,后者请求动态文件:
①Send_Ctrl_CMD(’0
1=MOTOR’,’);
②RealTime_Monitoring();
3.1 HTTPExecCmd函数
HTTPExecCmd函数对客户端发送的命令串解码并执行相应的操作。函数声明为:void HTTPExecCmd(BYTE**argv,BYTE argc)。考察客户端函数调用所发送的控制命令串:“0
1=MOTOR”。HTTP服务器函数HTTPProcess在调用HTTPExecCMD之前已经先通过HTTPParse函数由该命令串解析出“0”、“1”、“MOTOR”这三项内容并赋给函数参数argv,所解析出的三项的具体定义由主程序设置。
3.2 HTTPGetVar函数
每当HTTP服务器当前所处理的CGI动态文件Status.cgi中遇到变量码“%xx”时即调用该函数,处理动态请求。HTTPGetVar函数声明为:WORD HTTPGetVar(BYTE var,WORD ref,BYTE*val)。该函数的val参数是待解析处理的动态文件内的某个变量的标识符,参数ref用于跟踪返回值的状况,参数val用于逐个返回数据字节。
以调用RealTime_Monitoring函数为例,它通过XMLHttp对象请求动态文件Status.cgi,当HTTP服务器接收到该请求时,将从保存于EEPR OM的MPFS文件系统读取Status.cgi文件,然后由HTTP.c的SendFile函数向客户端XMLHttp对象回传所请求的动态文件。在回传过程中,所遇到的动态文件内的变量将由主程序所实现的HTTPGetVar函数逐一进行处理。动态文件中的各种变量同样将由HTTP服务器主程序进行定义。以Status.cgi文件中表示AN0通道A/D转换值的变量“%02”为例,由于主程序不仅循环调用HTTPServer函数响应客户请求并处理回应,在循环中还会分时处理外设操作,包括所需要执行的AN0通道的A/D转换操作。通常所有这些相关操作被集中放在处理I/O的函数ProccessIO()中实现。现假定RA0引脚外接可变电阻器RV1,则AN0通道的A/D转换具体实现如下:
ADCON0=0B10000001;
ADCON1=0B10001110;
ADCON0bits.GO=1;
while(ADCON0bits.GO);
itoa(*((WORD*)(&ADRESL)),ANOString);
每一次的A/D转换值都被刷新保存在ANOString字符串中,以便发往客户端显示。当HTTP服务器的HTTPProcess函数所调用的SendFile函数当前遇到了变量“%02”,它会将其交由HTTPGetVar函数处理。所输入的第1个参数var为2,它由变量“%02”转换为BYTE类型得到,用于标识当前变量要获取的是AN0通道的A/D转换值。
现假设AN0String当前获取的A/D值为“709”,HTTPGetVar函数可通过以下关键语句返回A/D值:
其中ref初始时默认为0。显然,该函数将被连续调用3次,每次调用时ref递增,直到通过*val返回最后一个字节以后,通过返回HTTP_ END_OF_VAR告知SendFile函数当前变量处理结束。对于待返回到客户端的数据字节,HTTP将通过调用TCP层提供的函数TCPPut及TCPFlush,通过指定的Socket套接字将数据字节发往客户端,由客户端XMLHttp对象的异步回调函数通过responseText属性读取并刷新显示在Web中的特定位置。
结语
通过仿真及实物电路测试表明,使用Ajax的XMLHttp对象及Microchip TCP/IP协议栈,可以很好地解决以太网环境下Web操作界面与嵌入式控制系统的交互问题,实现对基于HTTP服务器模式的嵌入式系统进行远程控制及实时监测,且能够将所有相关操作保持在稳定的浏览器窗口中执行。
射频工程师养成培训教程套装,助您快速成为一名优秀射频工程师...
天线设计工程师培训课程套装,资深专家授课,让天线设计不再难...
上一篇:超宽带技术在电子内窥镜中的应用
下一篇:基于双空间矢量调制方法分析矩阵变换器