|
Most embedded systems do not have traditional user interfaces. Embedded computers only rarely come equipped with display, keyboard,
and mouse. Although these devices may not require such interfaces on a day-to-day basis, there are times when having them would be extremely useful. This is particularly true for actions involving system configuration, monitoring, and control. Moreover, if the system is essentially a sensor (a water or electric meter, for example), a user interface may be useful for data collection as well.
The technology of the World Wide Web provides a simple way to perform all of these actions and more while
sitting in front of any remote computer with a web browser. The web browser window becomes, in effect, the embedded computer's display, and the remote computer's keyboard and mouse become its input devices. By using a remote computer with web browser as the human interface, the embedded system can support functionality that would be difficult or expensive to accomplish in more proprietary ways.
Embedding the Web
Most web server software will not work well in embedded systems. A web server that is designed to run on a workstation faces a different set of requirements than one designed to run in an embedded system. For example, most non-embedded web servers include features such as:
- Multiple log files
- Virtual servers
- SNMP
- Secure Sockets Layer (SSL)
- Integrated certificate server
- Remote maintenance
- Search engine
These features are vital for high-volume,
server-based web servers but are of far less value in a web server used to power Internet appliances. The implementers of embedded web server software must be concerned with reducing the memory footprint, increasing efficiency and reliability, providing mechanisms for generating dynamic data, and source code portability.
Some may argue that because a few of the server-based web servers come with source code and are essentially free-Apache (www.apache.org), for example-they can be adapted to suit
the demands of embedded developers. However, the large memory footprint and resource expectations of these web servers make them difficult to port to resource-constrained embedded systems. While server-based web servers focus on being feature-rich, the needs of the embedded community definitely do not include such expansive feature sets.
Internet appliances (and embedded systems, in general) require web servers that enhance their existing functionality without impinging on vital device resources or
requiring a redesign. Because many of these systems are cost constrained, memory and CPU resources are usually at a premium. It is vital that embedded web servers have minimal memory requirements and be efficient. The requirements for an embedded web server include:
Memory usage.
A small memory footprint is one of the most important requirements for an embedded web server. Not only must the web server use very little memory (code, stack, and heap), it must not fragment memory. Many embedded
devices employ simple memory allocators that cannot coalesce fragmented memory effectively. This can be a real problem since web servers often have to respond to requests to serve pages as rapidly as possible. Once the memory used to serve a page is freed, it may be useless, as it cannot be merged with adjacent memory blocks on the heap. To solve this problem, embedded web servers should use only statically allocated or pre-allocated memory blocks.
Support for dynamic page generation.
Unlike the majority of the pages you surf on the Web, most of the HTML pages served up by Internet appliances are generated on the fly. Whereas a Web site on the Internet usually has vast numbers of static pages on a local disk, an embedded device will have only a small number of pages in memory and will often generate part or all of their content on the fly. These pages will display ever-changing information about device status, the values read by sensors, and other data that is available to the device.
Software integration.
It's important for embedded web servers to integrate easily. Integrating a web server into an embedded system involves two steps. First, the web server software must be ported to the operating system. Second, device-specific access functions must be written and interfaced to the web server software.
Porting a web server to a new operating system is most easily accomplished when its source code is available. Embedded applications often require that the web server
be integrated into an existing application framework or that the event loop of the web server be accessible. If the web server is supplied only in binary form, or is costly to acquire in source form, such integration may be difficult or impossible.
Integrating device access functions into a web server requires easy binding of existing device APIs to URLs. This can be accomplished in many ways, but usually some proprietary device-specific method is dictated by the web server vendor. What would be
preferable is an industry-standard method of linking devices to the web. For example, Active Server Pages (ASP) and JavaScript are standards that enable dynamic data returned by device-specific access functions to be linked to web pages for execution whenever the page is loaded.
ROMable web pages.
Many embedded systems do not have disk drives but still wish to be accessed and controlled via the web. In such cases, some method of storing web pages in ROM is required. Embedded web servers
should be able to access HTML and other web content that has been linked into the executable as data or stored in a separate area of ROM or flash. Server-based web servers lack this feature.
Portability.
As engineers and software often move from one hardware project to another, it's important that the embedded web server be highly portable. Experience with a particular piece of software should be easily transferable from one project to another. Source code that has been ported and tested on a
wide range of different processor architectures is a good thing.
Dynamic data
Embedded systems don't typically serve up a whole bunch of static web pages. Most often, an embedded web server is in the system to provide real-time access to data or to allow certain system configuration parameters to be modified on the fly. These types of behaviors require the content of most web pages to be generated dynamically.
Two primary ways exist to create a dynamic web page:
- Generate the HTML tags programmatically
- Create the web page in advance and insert dynamic data via expansion tags
Generating HTML tags programmatically-from a C program, for example-requires no special handling by the web server and sounds, at first, like an attractive approach. After all, the program will have direct access to the variables and data of interest. However, it doesn't take too many "edit,
compile, display" cycles before this becomes extremely tedious. HTML pages are difficult to create if you can't view the results as you are working. Generating the HTML tags programmatically prevents visualization until the page is actually generated in the device.
The second approach allows much faster development cycles. Leading-edge HTML design tools can be used to create web pages in a WYSIWYG manner. All that remains to be done is insert the dynamic data when the page is loaded.
Most commercial
embedded web servers employ some proprietary scheme for displaying dynamic data. Some use proprietary tags that are expanded by the server before sending pure HTML to the browser. Others create new languages containing mini-tags that are expanded into real tags with the dynamic data. All these schemes are adequate and certainly do the job. However, if a more standards-based approach exists that can be employed, it should be examined seriously.
ASP is a Microsoft-developed approach to allow the easy
creation of dynamic web pages. Originally shipped in Microsoft IIS, it now has been ported to a wide variety of platforms and is available from many vendors in commercial products. Many books about ASP are available, and there are numerous ASP-experienced designers.
ASP permits the scripting of dynamic data using JavaScript or any other supported scripting language. The web server evaluates the ASP script and the results are substituted into the page replacing the original script. This should be
done in a one-pass operation for maximum efficiency. By using such server-side scripting, the dynamic data to be displayed is easily modified without recompiling the web server. This results in very rapid development cycles.
Web pages using ASP normally have an ".asp" extension to distinguish them from normal HTML pages. To insert ASP scripts in a web page, the scripting code is encapsulated using the special tags
<
% and %>. For example:
<H2>Today is <% write(Date.
tostring()); %></H2>
Various scripting languages may be selected at run time by specifying the desired language:
<% language=javascript write ("hello world"); %>
However, the support for multiple scripting languages that may be common in server-based web servers is rare for embedded web servers.
Embedded JavaScript
JavaScript has gained widespread attention as the leading scripting language for web pages. Unfortunately, though, its large memory footprint (200K+) has prevented its use in embedded applications. However, a compromise solution has proven effective: implement a strict subset of JavaScript. When used for browser-side scripting, complete access to the browser Document Object Model is highly desirable and many of the features of JavaScript have evolved to service this need. However, on the
server-side, support for the complete JavaScript feature set is not required. Basic control flow, variable evaluation, and testing constructs are all that's really needed on the server. For example, the open source GoAhead WebServer (www.goahead.com/
Webserver/) implements the following subset of JavaScript:
- Variables and variable declarations
(var)
- Global functions with support for local JavaScript variables
-
if, then, else
-
for
loops
- Expressions
including:
+ - / * % ++ - | & || && << >> < <= == > >=
- Statements: return, braces, comma, semicolon
- Comments
Absent from this implementation are arrays, objects, regular expressions, and object methods. Such an implementation of a JavaScript subset can be as small as a 15K embeddable JavaScript interpreter.
JavaScript and ASP can be implemented efficiently and can execute quickly. A tight, recursive-descent JavaScript parser and a hashed symbol
table lookup for the variable store enable high performance with minimal CPU requirements.
This feature set permits powerful server-side scripting to create dynamic web pages. The following is an ASP/JavaScript example that loops over a set of sensors and outputs their values within a single page:
<H1>Sensor Values</H1>
<% for (x = 0; x < 10; x++)
write("<H2> Sensor " + x + " is
"+ getSensor(x) +
"</H2>");
%>
JavaScript is an untyped language and simply assigning a value to a variable will declare it. For good practice, the var statement can be used to declare variables. This lack of typing should not be a quality issue if the size of the scripts is kept small. JavaScript is not a replacement for C and does not scale well to implement large projects. It does however, excel at localized scripting to create dynamic content.
To ensure that the embedded web server can be easily
extended and to provide easy binding of C code to JavaScript, a method of publishing C functions should be possible. The JavaScript standard includes both object methods and global functions. However, in a subset of JavaScript, it is the global functions that are both easiest to implement and most useful. Global functions can provide direct linkage from JavaScript to C functions. For example:
<% write(myJavaFunction(arg1,
arg2)); %>
To publish the C function that implements this global JavaScript function, code similar to the following would be used first:
ejSetGlobalFunction(handle,
"myJavaFunction", cFunction);
When myJavaFunction() is called via the ASP script interpreter, the JavaScript interpreter looks up "myJavaFunction" and locates the function entry point. The C function is then invoked and may return a result by calling:
ejSetResult(handle, "any return
data");
By designing appropriate JavaScript global functions, a single JavaScript call can be used to output an entire table, return device, or database information.
URL handlers
The URL name space manages to encode the entire World Wide Web of information into a single globally unique addressing scheme. Often this becomes quite convoluted, as any query to a major search engine will
demonstrate:
http://www.altavista.com/cgibin/query?pg=q&kl=XX&q=
embedded+AND+Web+AND+servers
It is possible to leverage the URL name space to provide a better, more intuitive naming convention for embedded systems. This is achieved by binding a URL prefix to a processing function that can handle the request. For example:
http://device.network.com/thermostat/setTemp/72
This would invoke the thermostat handler within the device that would parse the rest of the
URL and set the temperature to 72 degrees. Perhaps the web page that's at that location would simply show the results of the command and the current temperature.
WWWrapping up
The usefulness of web servers in embedded systems often comes as a surprise to design engineers. Clearly, such applications are a class of uses that were not really intended by the creators of the HTTP, HTML, JavaScript, and ASP standards.
But although the technology is generally useful in embedded applications, most of the commercial server-based web servers are not. If you're going to use an embedded web server, you can either write your own, try one of the commercial embedded web servers, or start with an open source product and do the porting and integration yourself. Whatever you decide, be sure to pay attention to details like memory usage, efficiency, the ROMability of the HTML pages, and the ease with which dynamic content can be
created.
Michael O'Brien is president and CEO of GoAhead Software. Prior to that, he helped found Stallion Technologies. He holds a BA in computer science from the University of Queensland and owns several U.S. patents relating to embedded design and Internet connectivity. He can be reached via e-mail at
michaelo@goahead.com.
|