微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 一种实用的嵌入式Web服务器设计

一种实用的嵌入式Web服务器设计

时间:01-15 来源:单片机与嵌入式系统应用 点击:

引言

  数字化变电站是建立在网络通信技术和电子技术基础上的一种新型变电站自动化系统,其中一个重要特征就是二次设备的网络化[1]。目前在国内的数字化变电站试点中,已经出现了大批支持以太网和TCP/IP协议的嵌入式IED[23],在具体开发和应用中发现,由于现场环境的复杂多变以及客户需求的多样性,经常需要对这些IED进行参数的配置和修改。但厂家多采用专门的配置软件来进行,操作界面不够统一,给现场操作带来诸多不便。而采用Web服务器技术,则只需要浏览器便可实现对IED参数的在线修改与配置,从而极大地方便了对设备的维护和管理。目前,Web服务器功能在数字化变电站中,多用于调度与监控端设计[4],单纯在IED上实现Web服务器功能的报道尚不多见。本文通过对Linux平台上运行的BOA Web服务器和CGIC的研究,将原本两个独立运行的程序整合为多任务系统中的一个任务实体,并对其进行相应的精简和修改;设计并实现了一种可在一般嵌入式系统上运行的,既相对简单又响应快速的嵌入式Web服务器。目前已在相关装置上得到应用,取得了较好的使用效果。

  BOA和CGIC是两个基于Linux的开源软件,代码采用C语言实现,程序小巧灵活、执行高效,非常适合于嵌入式系统的应用环境。但目前多用于Linux或μClinux的系统平台上[57]。鲜见有用于其他系统的相关报道。

  其中BOA是一个单任务的HTTP服务器,它的设计目标主要是速度和安全。因此,它不像传统的Web服务器,为每个访问连接单独开启一个进程,也不会为处理多个连接而开启多个自身的拷贝。BOA对所有活动的HTTP在内部进行连接处理,只为每个CGI连接启动新的进程,在同等硬件下相比其他服务器具有更快的访问速度。而CGIC是一个为支持通用网关接口CGI(Common Gateway Interface)而开发的C语言库,通常和BOA联合使用,它可接收由浏览器通过GET或POST方法传输过来的表单及文件数据,并提供了对这些数据进行解析的方法,使用非常方便,且源码也易通过因特网获得。

  基于以上原因,本文主要基于这两种技术来实现IED装置内部的嵌入式Web服务器功能。

1 系统概述

  嵌入式Web服务器EWS(Embedded Web Server)是指将Web服务器引入到现场测试和控制设备中,在相应的硬件平台和软件系统的支持下,使传统的测试和控制设备转变为具备了以TCP/IP为底层通信协议,Web技术为核心的基于互联网的网络测试和控制设备[8]。其中,Web浏览器和EWS的交互过程如图1所示。

图1 Web浏览器和EWS的交互过程

  首先由Web浏览器发出HTTP请求报文,并建立TCP连接,然后由EWS根据其请求报文来提供相应的状态和页面信息,若只是请求静态页面,则无需通过CGI,直接返回该对应页面即可;反之则需要通过CGI来进行相关报文数据的解析,并根据解析结果来生成动态页面以返回给客户端浏览器。这样,完成一次交互过程后,即可释放该TCP连接[9]。

  本文的设计目标是将Web服务器的功能仅作为DSP/BIOS中的一个任务,只在监听到HTTP协议对应端口(通常为80)上的TCP连接请求时,才运行该任务。但是传统的BOA并没有对用户访问权限的控制对页面的管理也依赖于Linux系统,因此,结合变电站运行的特殊性,本文所设计的EWS系统结构框图如图2所示。

图2 EWS系统结构框图

  系统运行时,由HTTP连接管理模块负责对网络端口进行监听,当监听到有连接请求到达后,即进入HTTP报文解析模块进行处理,如果解析错误,则直接返回HTTP连接管理模块,发出相应的响应报文并关闭该连接;否则,则根据对报文解析的结果,提取出本次要访问的URL,并将其交给访问权限管理模块,以查看该客户端是否具有足够的权限;然后再转由页面文档管理模块进行处理,根据对报文的初步解析以及对访问权限的判断,由页面文档管理模块来决定是否调用CGI,以实现文件的下载上传及响应文档的生成,从而将正确的响应报文及页面文档转交给HTTP连接管理模块进行网络数据的应答回送。

2 功能实现

2.1 HTTP连接管理的功能实现

  所谓HTTP连接管理,主要是指对连接到服务器端口的socket进行监听、捕获、读写、关闭,以及对HTTP请求报文协议字段的解析和响应报文的生成等操作。其中,BOA可提供完整的HTTP协议数据解析及响应报文生成的功能。因此,对和HTTP连接管理中相关的操作,基本上可直接采用BOA的相关代码,实现起来难度不大。

  BOA中的连接状态切换示意图如图3所示。

图3 BOA中的连接状态切换示意图

  当程序每次监听到新的socket连接访问接入时,首先对空闲队列进行判断,如果为空,则申请一个request结构空间,并将其插入就绪队列的队头,否则可直接将一个结构空间从空闲队列转入;对当前正在处理的就绪队列成员,当网络阻塞时则将其移入阻塞队列的队头,当访问结束断开连接时,则将该成员的空间信息移入空闲队列;而当对阻塞队列进行轮询时,根据其成员所对应的socket上是有读写请求还是该连接已超时,分别将其移入就绪队列或断开连接移入空闲队列。

  以上过程在BOA中主要是通过get_request、fdset_update和process_requests这三个函数来实现的,它们也是实现移植的重点,其他函数则相对简单。在移植过程中,为了适应嵌入式的应用环境,在系统初始化时,给空闲队列分配了足够大的队列空间,并对操作时所涉及的一些动态内存分配的语句和结构进行修改,从而尽量减少连接过程中频繁的内存申请。另外,传统的BOA对每个CGI连接启动新的任务,在此考虑到配置数据的即时生效以及系统资源的节约,仍然在EWS的任务环境中处理该CGI连接。实验证明,这种处理方法简单可行,而且在装置的应用环境中对服务器的性能并无太大影响。

2.2 访问权限管理的功能实现

  为了应用时操作的安全性,本文将访问的页面分成两类:一类为配置操作页面,仅供认证用户访问;另一类为设备状态页面,可供任何用户访问。其控制主要是通过对用户IP的判别及访问页面的分类来实现的。首先对用户访问的URL进行解析,如果访问对象为配置操作页面,则需要进行认证,在此通过一个用户权限控制管理结构来对通过权限认证的用户进行维护,并提供一个时间控制机制,使通过认证的用户在一定时间段内可持续有效的对服务器进行访问。如果当前客户端(访问者IP)在用户权限控制结构内,且未超时,则通过认证,由服务器根据本次申请的URL返回相应页面;若超时则需要对本次访问的URL进行重定向,返回密码校验页面,给用户提供密码输入的接口。如果访问页面为设备状态页面,则无需进行认证,直接由URL返回相应页面即可。访问权限认证程序流程如图4所示。

图4 访问权限认证流程

  通过以上过程的处理,即可实现对访问权限的控制与管理。

2.3 页面文档管理及生成的功能实现

  由于配置环境的需要,设计页面较多,如果将所有页面均存储在Flash上,文件读写的问题将更为突出。为此,本文设计了一个如图5所示的网页页面文件管理结构来对页面文件进行管理。

图5 网页页面文件管理结构

  下面介绍具体处理过程。

  首先,对所有页面无论是静态还是动态页面,均建立一个对应的模板文件,并将该模板文件的内容以全局静态字符串的形式直接写在程序中。在系统初始化时对各模板内容的大小进行统计,并按下式对各文件的最大容量进行粗略的估算:

  mS=sizeof(pT)×1.2

  其中:mS为估算的页面内容最大尺寸,sizeof(pT)则为该页面对应模板的实际大小(以上两者均以字节为单位)。

  按上式估算出页面的最大尺寸后,为保证对页面分配内存时空间的连续性,根据所有页面的最大尺寸和,一次性分配一个较大的内存空间,并将该空间按各个页面所对应的最大尺寸依次与该页面对应的管理结构内的文件内容指针相关联。这样,每次因配置的修改导致页面内容发生变化时,仅需对该指针所指向的空间内容进行修改即可,而仅在保存配置数据时,通过配置文件更新函数将其存储在Flash中。这样既避免了为修改页面文件内容而申请内存的操作,又避免了为存储页面内容而频繁进行的Flash读写操作,从而提高了该EWS的效率。

  对于EWS中动态页面的生成则要经过动态数据解析以及解析数据的模板页面回填这两个过程。在通常的Web交互中,大量动态数据是通过表单的形式体现在html页面设计之中的。而一般上送的表单数据(文件上传除外)在GET和POST两种方法下,除了在HTTP请求报文中出现位置的不同外(GET方法下位于请求行,POST方法下位于实体主体部分),其组织形式并无差别,如下所示:

  e_1-v_1&e_2=v_2...&e_N=v_N

  其中e_N代表表单数据中的元素名,v_N代表该元素的取值。

  因此,当连接管理模块从请求报文中提取出表单数据后,即可对这两种方法下的提交数据采用相同的解析方法。CGIC采用以下方法来实现其解析过程。

  首先,通过对表单数据字符串的节点分析,用一个单向链表来对表单数据中的每个元素进行维护,在链表成员中包括了对元素名及其值的管理,并针对不同的元素类型提供了一系列接口。解析步骤如下:

① 用于获取列表框取值的函数接口cgiFormSelectSingle。
② 用于获取文本框取值的函数接口cgiFormString。
③ 用于获取复选框取值的函数接口cgiFormCheckboxMultiple。

  在需要访问元素时,只需提供相应的元素名,就可方便地使用这些接口对管理链表遍历来获得相应元素的取值。

  当CGIC移植时,只需对相应元素解析对应的函数进行所选系统的修改即可。需要注意的是,对列表和复选框等非字符取值的获取,还需按照用户定义的取值设置,对相应的接口进行一定的修改,以适应用户对元素取值范围的灵活要求。

  所谓解析数据的模板页面回填,是指在动态页面设计中,按照模板中的页面显示格式,将页面中各元素的取值写入html模板文件中的对应位置。html标签代码如下:
  <input name="devName" type="text"
  value="***"size="15"/>

  它在页面上表示一元素名为"devName",取值为"***"的文本框,在数据回填到模板页面时,需要根据具体的取值如"dev1"写到原"***"的对应位置上去。结果如下:
  <input name="devName" type="text"
  value="dev1" size="15" />

  本文采用以下方法来实现这一处理过程。首先,设计页面模板时在每个需要进行动态修改的页面元素前加上不同的注释语句,对以上html标签,可加的注释语句如下(单独一行):
  <! devName_id>

  在每次解析完表单数据并且需要对动态页面进行重新生成时,就可以通过对模板文件的逐行读取,来查找相应的注释语句,从而确定数据更新的位置。然后再根据具体的元素取值生成新的html标签字符串,用来对注释语句后的标签字符串进行替换。通过以上过程,即可方便地实现解析数据的模板页面回填,从而生成相应的动态页面。

2.4 文件下载和上传的功能实现

  文件下载和上传是服务器经常具有的一项功能,相对来说文件下载较为简单,只需将下载时访问的URL定位于目标文件,然后再由服务器将该文件的内容直接上送给浏览器。而文件上传功能的实现则相对复杂,下面对其设计过程进行详细的说明。

  首先,要实现文件的上传,在其页面设计时必须采用POST方法来对表单数据进行提交,并且需要在页面中将其编码方式修改为"multipart/formdata",否则将无法在浏览器端进行文件上传。然后,通过html表单中的文件元素来进行上传文件的选择。

  通过以上设置,上传给服务器的http报文数据将以multipart的编码形式出现。其特点是,在每个表单元素项的前后均加有一行分界字符串。以文件元素为例,其格式如下:

  7db01d60ffc
  ContentDisposition: formdata; name="file"; filename="1.TXT" ContentType: text/plain
  This is a txt file.
  7db01d60ffc

  其中,"7db01d60ffc"为分界字符串。CGIC也提供了对该格式的解析支持。它首先提取出分界字符串,然后再通过cgiParsePostMultipartInput函数的操作来实现报文中各表单元素数据以及文件数据的解析。提取出文件数据后,即可将文件内容按指定的路径保存在相应的Flash存储区中。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top