为实现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服务器模式的嵌入式系统进行远程控制及实时监测,且能够将所有相关操作保持在稳定的浏览器窗口中执行。