11.07.2015 Views

Designing an embedded Web server - Embedded Computing Design

Designing an embedded Web server - Embedded Computing Design

Designing an embedded Web server - Embedded Computing Design

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

the HTML pages that make up the contentof the demo with the scripts <strong>an</strong>d specialsoftware that provide the interactivefeatures.HTML interface for demoThe HTML interface to the demo was byfar the simplest part of the application.Figure 3 shows the three frames that werenecessary:Figure 3■ The first frame controls camera settings:contrast, white bal<strong>an</strong>ce, <strong>an</strong>dexposure. The user sets each of theseindividually inside <strong>an</strong> HTML form.Once set, the values are submitted tothe <strong>server</strong>.■ The second frame controls the camera’sorientation using the ISMAP comm<strong>an</strong>dwith a GIF image representing the<strong>an</strong>gular orientation of the camera.■ The final frame is the resulting picturein GIF format.Figure 4 presents the HTML to generatethe three frames. Each frame has a namethat c<strong>an</strong> be referenced as a target for possibleoutput from other <strong>Web</strong> pages <strong>an</strong>d asource HTML file defined by src. TheUSBldpg utility converts each page into Cfiles to be compiled with the rest of theapplication.Servo controlThe servo control mech<strong>an</strong>ism also usesCGI in conjunction with <strong>an</strong> ISMAP insidethe camera position frame. The ISMAPpicture is a GIF image of a camera withrays indicating <strong>an</strong>gular orientation (seeFigure 3). The ISMAP is <strong>embedded</strong> insidea hypertext link that points to theturnserv() CGI function. The HTML forthe camera position image is:When the user clicks on the cam256.gifimage, the ISMAP statement tells thebrowser to send <strong>an</strong> X Y coordinate to theCGI function turnserv(). The functionreads the coordinates from the argv[]parameters <strong>an</strong>d converts them to <strong>an</strong> <strong>an</strong>glerelative to the camera center. This informationis sent to the servo controllerthrough the servo driver over the seriallink. Once the value is received, the servorotates the camera to a new position totake a new picture. Function turnserv()then sends all its output to the frame“Current Picture,” as specified in theTARGET statement, <strong>an</strong>d the cam_ctrl()CGI does the same.Note that we could not take adv<strong>an</strong>tage of aclient-side image map for this functionbecause we were interpreting the positionof the mouse click to actually instruct thesystem running the <strong>server</strong> to move a servoto the specified position. This is differentfrom a more common use of ISMAP inwhich the location of the mouse click isused as <strong>an</strong> indirect indication of the nextpage to be loaded.Camera controlThe camera settings are controlled by <strong>an</strong>HTML form where the user enters new valuesfor the settings in three fields, then clickson the “Submit” button. Original camera settingsare restored when the user clicks on the“Reset” button <strong>an</strong>d then submits the requestfor the image. Figure 3 illustrates the formatUS<strong>Web</strong> Demo PageFigure 4of the form. Figure 5 shows the HTML usedto generate this form.The form comm<strong>an</strong>d action names the CGIfunction to execute when the form is submittedto the <strong>server</strong>. In this example, thename of the function is camcntrl(). Thisform uses the GET method of tr<strong>an</strong>sferringdata, me<strong>an</strong>ing the data is sent as part of theURL portion of the request <strong>an</strong>d will befound in the QUERY_STRING <strong>server</strong>environment variable. The name <strong>an</strong>d valuespecify the format of the data inQUERY_STRING, so QUERY_STRINGwill be “Request=Color” for the radio buttoncontrol. The GET method is useful forsmall amounts of data or for largeramounts of data. The POST method c<strong>an</strong>be used to send the data in the messagebody of the request.The <strong>server</strong> executes the camctrl() functionwhen it receives the browser’s request. TheCGI routine parses the information inQUERY_STRING <strong>an</strong>d responds to the databy sending information back to the browser.In the case of camctrl(), if the CGI retrievesa fresh camera frame using the submittedparameters, the function would look similarto the code in Figure 6 on page 26 <strong>an</strong>d 27.In this example, the CGI assumes the<strong>server</strong> has some sort of structure asso-Winter 2000 / Applied <strong>Computing</strong> TechnologiesCopyright ©2000 Applied <strong>Computing</strong> Technologies. All rights reserved.


Camera ControlCamera Controls Contrast White Bal<strong>an</strong>ce Exposure Color Gray Red Green Blue Figure 5ciated with the incoming request,request_ptr. This pointer is used whenresponding to a browser’s request. Basedon the construction of the form, the CGIis expecting a string of the form“Request=x,” where x is the value specifiedfor each radio button. Once the valueis found, the CGI responds by calling theappropriate function. The output is st<strong>an</strong>dardHTML sent back to the browser viathe PRINTF() function written for usewithin the <strong>embedded</strong> <strong>server</strong>. This specialversion of PRINTF() directs the output toa buffer that will be read by the <strong>Web</strong><strong>server</strong>. Other implementations may havedifferent conventions.The camera setting form uses the GETmethod because there is relatively littledata. When the user clicks on the submitbutton, this sends a request to the<strong>server</strong> to initiate the CGI functioncam_ctrl(), which reads the data from theQUERY_STRING environment variable,then sends the new settings to the cameravia the camera driver. Once the camerareceives the new settings, it takes a newpicture, which is stored on the board. TheCGI then sends the file “picture.html” tothe Current Picture frame, which displaysthe new image.PictureBoth CGIs, cam_ctrl(), <strong>an</strong>d turnserv(),generate a picture after setting the newcamera settings or rotating the servo bycalling the take_picture() function. Thefunction take_picture() sends <strong>an</strong> instructionto the camera to snap a picture. Thecamera responds by sending a bitmap ofthe current picture in sixteen shades ofgray. At this point, the <strong>server</strong> converts thebitmap to a GIF by using the graphics utility.The new image replaces the old imagein <strong>server</strong> memory <strong>an</strong>d is sent to thebrowser for display. The <strong>server</strong> h<strong>an</strong>dles allcomputation.When the interface pages were generatedfor the demo, a placeholder picture wasused for the image to reserve memorybecause the image varies in size fromsnapshot to snapshot. The file specifiedfor the image was defined to have a maximumsize of 20 Kbytes. When USBldpgwas run to configure the <strong>server</strong>, it set asidethe 20 Kbytes of memory. The <strong>server</strong>overwrites this memory every time a newpicture is taken. Since the image neverexceeds 14 Kbytes, there is no d<strong>an</strong>ger ofoverwriting other parts of memory when <strong>an</strong>ew image is stored.Problems encounteredInitially, a PC developed the demo. Oncewe ported it to the Net186, we met severalproblems almost immediately. The problemsencountered were normal fare whenCopyright ©2000 Applied <strong>Computing</strong> Technologies. All rights reserved. Applied <strong>Computing</strong> Technologies / Winter 2000


converting from a st<strong>an</strong>dard application to<strong>an</strong> <strong>embedded</strong> application. We knew thiswhen designing the demo, so each part ofthe demo that had to communicate withthe board was modularized. This allowedus to rebuild just the board dependentparts without making modifications to theoverall demo.Hardware interfaceThe camera was designed to run from aPC parallel port, not <strong>an</strong> <strong>embedded</strong> board.Thus, the most signific<strong>an</strong>t problem was todevelop the low-level interface to thehardware. To ensure that the board couldreceive picture data, we wrote a high-leveldriver on a PC to control the camera. Thisdriver interfaced with a low-level hardwaredriver that actually communicatedwith the camera through the parallel port.Once the camera software r<strong>an</strong> on a PC, wedeveloped a new low-level driver to turnthe thirty-one programmable pins on theNet186 into a parallel-port-like interface.Another driver was developed in a similarfashion for the serial port on the Net186.This driver provided the low-level communicationto the servo controller.Memory m<strong>an</strong>agement<strong>an</strong>d image sizesMemory <strong>an</strong>d memory m<strong>an</strong>agement alsobecame <strong>an</strong> import<strong>an</strong>t issue when the softwarewas moved from the developmentPC to the <strong>embedded</strong> board. The picturegenerated by the camera is a 320 x 240pixel bitmap, which could easily consumeover 75 Kbytes of data space. Tosolve this minor problem, the picture wasgenerated using sixteen shades of gray soeach pixel required only four bits, <strong>an</strong>dtwo pixels could be stored in a singlebyte. In addition, the picture was compressedinto a PNG using a free graphicslibrary available on the <strong>Web</strong>. Thisreduced the size of the stored image toapproximately 14 Kbytes. The graphicslibrary makes heavy use of malloc() <strong>an</strong>dfile I/O functions. Therefore, we wrote<strong>embedded</strong> versions of these functions forthe Net186. These functions could beeasily replaced by using <strong>an</strong> <strong>embedded</strong>file system such as US Software’sUSFiles ® , which provides <strong>an</strong> interfacethrough the traditional file system functioncalls for a file system that is implementedusing a RAMDISK.ConclusionOnce all the pieces are integrated with eachother, the application becomes a functioning<strong>Web</strong> <strong>server</strong> that c<strong>an</strong> be accessed via serialor Ethernet connection. Each part of thecontrol interface has <strong>an</strong> associated CGIfunction capable of m<strong>an</strong>ipulating the cameraor servo hardware. In this particular<strong>embedded</strong> <strong>server</strong>, the CGI functions are thecore of the application. Several minor problemswere overcome to generate the demo.Replacement functions for malloc() <strong>an</strong>dfile I/O were generated to replace the functionsused in the graphics utility. New driverswere also developed to interface theNet186 board to the parallel port cable ofthe camera <strong>an</strong>d to the serial port of theservo control.<strong>Embedded</strong> developers who use this technologyin their projects c<strong>an</strong> be assured ofsaving time while providing <strong>an</strong> industryst<strong>an</strong>dardformat to their users.Nicholas Witcheyreceived his Ph.D. inHigh Energy Physicsfrom Ohio StateUniversity. He currentlyworks as <strong>an</strong> EngineeringM<strong>an</strong>ager at U SSoftware, applying his experience in software-hardwareintegration to developing<strong>an</strong>d enh<strong>an</strong>cing product technologies.Witchey’s interests include networking<strong>an</strong>d product research <strong>an</strong>d development.His e-mail address is nick@ussw.com.ReferencesThe following references provide valuableinsight <strong>an</strong>d techniques in generating <strong>Web</strong>interfaces. They are intended for disk-based<strong>Web</strong> <strong>server</strong>s. However, most of the informationis also directly applicable to <strong>embedded</strong><strong>Web</strong> <strong>server</strong>s.■ Foundations of WWW programmingwith HTML <strong>an</strong>d CGI. Ed Tittel, MarkGaither, Sebasti<strong>an</strong> Hassinger & MikeErwin. IDG Books, ISBN 1-56884-703-3.■ Kim, Eugene Eric. CGI DevelopersGuide. Sams Net, ISBN 1-57521-087-8.■ Boutell, Thomas. CGI Programmingin C <strong>an</strong>d Perl. Addison Wesley, ISBN0-0201-42219-0.■ Graham, I<strong>an</strong> S. HTML 4.0Sourcebook. John Wiley & Sons,ISBN 0-471-14242-5.Key issues in implementing<strong>an</strong> <strong>embedded</strong> web <strong>server</strong>■ What kind of throughput will theprocessor have to h<strong>an</strong>dle?Any selected processor must beable to h<strong>an</strong>dle the maximumexpected number of user requests<strong>an</strong>d expected data throughput.Also, the application’s designmust take the user load intoconsideration. For inst<strong>an</strong>ce, iflarge data samples will bedownloaded, the CPU must beable to h<strong>an</strong>dle the outgoing datastream while being able to h<strong>an</strong>dlenew incoming requests. Thisimplies the application should beIO bound, thus allowing sufficientCPU cycles to h<strong>an</strong>dle <strong>an</strong>y otheractivities. For infrequent requestsfrom the <strong>server</strong>, that is, onerequest at a time by one user at atime, a smaller CPU c<strong>an</strong> be usedbecause large throughput <strong>an</strong>d datarates are not <strong>an</strong> issue.■ How m<strong>an</strong>y users will use theapplication?The application will have tom<strong>an</strong>age the resources available tousers in order to resolve potentialaccess conflicts. This process c<strong>an</strong>be achieved through use ofsemaphores or mutual exclusionmech<strong>an</strong>isms found in most realtime operating systems.■ How m<strong>an</strong>y resources does theapplication need?If pages or images are builtdynamically, sufficient memorymust be available for storage <strong>an</strong>dm<strong>an</strong>ipulation. Images require alarge amount of space. Forexample, a bitmap image of 320 x240 pixels with 256 colors c<strong>an</strong>require over 75K of data space.This requirement c<strong>an</strong> be reducedif the image is compressed usingGIF or JPG file formats. However,adequate resources must beallocated to cover the greatestneeds of the application.■ How will the application interfacewith the <strong>server</strong>?The application c<strong>an</strong> interfacedirectly with the <strong>server</strong> throughthe use of CGI functions in asingle threaded system. In a multithreadedsystem, the <strong>server</strong> c<strong>an</strong>exist as a separate task. The rest ofthe application c<strong>an</strong> update <strong>an</strong>y ofthe pages, images, or other data inglobal data space, while the <strong>server</strong>task’s only function is to send thedata to the browser.Winter 2000 / Applied <strong>Computing</strong> TechnologiesCopyright ©2000 Applied <strong>Computing</strong> Technologies. All rights reserved.


#include #include #if !defined(pyr) && !defined(NO_STDLIB_H)#include #else#include #include char *getenv();#include #endif#include #include #include #include #include #include #define MAXLINE 500#define MAXVERTS 100#define X 0#define Y 1//#define LF 10 /* Line Feed *///#define CR 13 /* Carriage Return */#define SERVPORT 1 /* Com port attached to servo controller */#define SERVBORD 1 /* Servo controller board number */#define SERVNUMB 1 /* Servo number on board *//*** Global picture paramters to be replaced by calls to** get_var() <strong>an</strong>d set_var()*//*int CONtrast,WHItebal,EXPosure;char Color_MASK;*/#define TO255 256 / M_PIstatic void <strong>server</strong>err(char *msg);static void html_print(char *msg);int takepicture(struct request_rec *reqp );int parse_parameters(struct request_rec *reqp, char *param_string);int loadnick(int argc, char **argv,struct request_rec *reqp){int rslt, rest, len;char *ptr;ENTRY *ep, *tep = reqp->fileinfo;ep=GetEntry(reqp,”nick.gif”,0);if(ep){rest = ep->ulen;ptr = ep->offset;rslt = Bwrite(reqp,ptr,rest);}}int camcontrol(int argc, char **argv,struct request_rec *reqp){char input[MAXLINE], *mapname, def[MAXLINE], conf[MAXLINE],errstr[MAXLINE];double testpoint[2];int i, x,y;double dist;char *t;ENTRY *ep;char *pParams;pParams = Ngetenv(reqp,”QUERY_STRING”);/*** Set camera settings based on QUERY_STRING setttings*/parse_parameters(reqp, pParams);/*** Take Picture*//*** html file specified by browser when clicked*/YIELD();takepicture(reqp);/* Figure 6Copyright ©2000 Applied <strong>Computing</strong> Technologies. All rights reserved. Applied <strong>Computing</strong> Technologies / Winter 2000


}** html file specified by browser when clicked*/pictureframe(1,&”pictureframe”,reqp);return 0;static void <strong>server</strong>err(char *msg){printf(“Content-type: text/html%c%c”,10,10);printf(“Camera Control Setting Message”);printf(“Bad Camera Control Setting”);printf(“One or more settings for the camera are bad:”);printf(“%s”, msg);exit(-1);}typedef struct {char name[32];char val[16];} entry;extern int CONtrast;extern int WHItebal;extern int EXPosure;extern char Color_MASK;int parse_parameters(struct request_rec *reqp,char *parstr){int m,x, i=0, iscolor;entry entries[6];char *tmpstr;int icntrst;int iwhtbal;int iexpsr;char shades[2]; /* color shade */tmpstr = GETENV(“QUERY_STRING”);if(tmpstr == NULL) {PRINTF(reqp,”No query information to decode.\n”);EXIT(1);}for(x=0;tmpstr[0] != ‘\0’;x++) {m=x;getword(entries[x].val,tmpstr,’&’);plustospace(entries[x].val);unescape_url(entries[x].val);getword(entries[x].name,entries[x].val,’=’);}/* 0= contrast, 1=whtbal, 2=exposure, 3=color *//*** Work on finding the contrast first. We should always** have a contrast.*/icntrst = atoi( entries[0].val );if( icntrst < 1 || icntrst > 254 ){<strong>server</strong>err(“ Bad Contrast Setting. Must be 1 to 254 “);return -1;}elseCONtrast = icntrst;/*** Next find the white bal<strong>an</strong>ce.*/iwhtbal = atoi( entries[1].val );if( iwhtbal < 1 || iwhtbal > 254 ){<strong>server</strong>err(“ Bad White Bal<strong>an</strong>ce Setting. Must be 1 to 254 “);return -1;}elseWHItebal = iwhtbal;/*** Now find the exposure*/iexpsr = atoi( entries[2].val );}if( iexpsr < 1 || iexpsr > 254 ){<strong>server</strong>err(“ Bad Exposure Setting. Must be 1 to 254 “);return -1;}elseEXPosure = iexpsr;/*** Now check to see if a color has been specified. This one** is different th<strong>an</strong> the others because it’s at the end of** the query string. If they user forget to hit a radio button** nothing appears at the end of the string.*/shades[0] = *entries[3].val;shades[1] = ‘\0’;Color_MASK = shades[0];/* html_print((char *)&shades); *///<strong>server</strong>err(“ Bad Color Setting. Must be Gray, Red, Green, or Blue “);Figure 6 (Continued)Winter 2000 / Applied <strong>Computing</strong> TechnologiesCopyright ©2000 Applied <strong>Computing</strong> Technologies. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!