| ||
[Back to Index] | ||
It is possible to use the Tynamo™ server as the main user application in flash, replacing Slush. This is one of several ways of increasing the reliability of your TINI server. This guide discusses the procedures for placing the Tynamo™ server into flash, but does not discuss techniques for including additional material, such as web pages, images, or other files. Please contact us if you would like more information on this subject. It is emphasized that this guide discusses only one of many ways flash can be utilized for your application. For example, Slush can still be included in addition to your own program code. There are many alternative possibilities. Limitation of this GuideBecause this guide does not discuss how to include static files, the steps presented here require that your server relies only on servlets for its content. There are four sections: And one appendix:
Application Entry PointFirst, your server will need a class that serves as the main entry point to the application since Slush is no longer present. Appendix A lists source code for a sample main class that can be used as a starting point for your own custom setup. Save this in your source path as Startup.java. For example, if you keep your source in a directory named src/ in your project directory, then save this file as src/Startup.java. [Top] Build Configuration
Add Startup.java to your
Next, make these changes to build.xml:
– If you are running a '390-based TINI system and if you have enough flash to hold the generated TBIN file, then change tini.useTargetAddress to "0x70100" as well. You may wish to copy the build.xml file to your project directory before making any changes, as outlined in step three of the Decoupling Your Project guide. Build the server as usual, and a webserver.tbin file that is suitable for uploading to your TINI instead of Slush will be created in the current directory. This is the only file needed for the webserver. [Top] DiscussionThis section explains some of the ideas presented here in more detail. Other SolutionsIt was mentioned briefly at the beginning of this document that this guide discusses only one of many ways to utilize flash for your application. For instance, the "main" code presented here performs some simple system initialization, stores a few important configuration files, and then starts the server. The system initialization could be skipped, and Slush could be started after the server is started. Then, the benefits of Slush can be utilized. The important thing to note is that you are not restricted by the approach presented here. In other words, "Decide what you need, and then put it there." There is a range of options. Source CodeThe Startup.java code deserves some explanation. It is divided into three parts that:
The system initialization code first sets the default streams to the serial port in order for you to see what happens when the system starts. For example, when JavaKit is used, you will be able to see startup messages. The same thing is done at startup in Slush: if (TINIOS.isConsoleOutputEnabled()) { com.dalsemi.system.Debug.setDefaultStreams("serial0", 115200); } Then, the filesystem is set so that each reboot will cause everything to start from a clean slate. This can improve performance at runtime since the system doesn't have to perform certain consistency checks: TINIOS.disablePowerFailRecovery(); TINIOS.blastHeapOnReboot(TINIOS.BLAST_ALL); Finally, the network parameters are set. Be sure to set these to your own values.
After this, files needed by the webserver are stored in the filesystem
with the call to
The webserver is then started by setting up the mail handler (whose
most likely use is for mailing the log files), then reading the
configuration file, and finally starting the webserver thread. Some
comments are included that explain how to shut down the server with a
call to The Build Script
There are a few modifications to be made inside the build.xml
script. These tell the build process to write out a file suitable for
uploading with JavaKit, and to use the new Because we are replacing slush, some of the work done to initialize the system has to be done ourselves. Replacing the webserver.mainClass property tells the TINIConvertor program to set this as the main entry point when the system is started. [Top] Additional SuggestionsThis section presents some additional ideas on how to store files in an alternative way, such that they are available at startup. Store Files as StringsIt is possible to store all files as string data in fields in a class. The plain text files could stay as they are, and the binary files could be Base64 encoded. The disadvantages to this approach include a slightly longer startup time, and classfile size limitations. The startup time would be affected because each string would have to be extracted and written to a file. The size limitations in TINI are currently 32k for converted classfiles and 64k for arrays. This would limit the data that can be stored per class, although this limitation could probably be worked around with a more elaborate file extraction mechanism. Store Files in FlashIt is possible to store arbitrary data in flash using either a native TLIB library or a raw TBIN file. Both of these approaches require you to devise a storage scheme for the files and a way to access the flash memory. The TLIB format, however, is also limited to 64k by the TINI firmware. Retrive Files from the InternetAt server startup, either inside the main entry point, or in the initialization code of a servlet, a connection could be made to a host somewhere on the Internet that contains the latest version of your files. Protocols such as FTP or HTTP allow you to retrieve these files in a straightforward way. [Top] Appendix A — Startup.java Sourceimport com.dalsemi.system.TINIOS; import com.dalsemi.tininet.TININet; import java.io.*; import java.net.URL; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; import java.util.Properties; /** * Demonstrates how to start the server from flash. * * @author Shawn Silverman */ public class Startup { /** * Application entry point. */ public static void main(String[] args) throws IOException { // Set the System streams to serial0 if (TINIOS.isConsoleOutputEnabled()) { com.dalsemi.system.Debug.setDefaultStreams("serial0", 115200); } System.out.println(); System.out.println(" --= System starting =--"); System.out.print("Disabling power fail recovery......"); // Doing this will speed up the program since it's running from flash // It is okay to call this because we are also blasting the heap TINIOS.disablePowerFailRecovery(); // Blast the memory on reboot TINIOS.blastHeapOnReboot(TINIOS.BLAST_ALL); System.out.println("[DONE]"); // Set up the network // You can configure other things here such as the mailhost System.out.print("Configuring network................"); TININet.setIPAddress("eth0", "192.168.0.7"); TININet.setSubnetMask("eth0", "255.255.255.0"); TININet.setGatewayIP("eth0", "192.168.0.1"); TININet.setPrimaryDNS("192.168.0.1"); System.out.println("[DONE]"); System.out.print("Storing files......................"); storeFiles(); System.out.println("[DONE]"); System.out.println(); // Load the properties file System.out.print("Loading web server properties..."); Properties props = new Properties(); String propsFile = "/web/bin/webserver.props"; try { FileInputStream in = new FileInputStream(propsFile); props.load(in); try { in.close(); } catch (IOException ex) { } } catch (FileNotFoundException ex) { System.err.println("File '" + propsFile + "' not found."); System.exit(1); } System.out.println("done."); // Set up our "mailto" handler, if needed // The ability to mail the logs depends on this, for example URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() { public URLStreamHandler createURLStreamHandler(String protocol) { if ("mailto".equalsIgnoreCase(protocol)) { return com.qindesign.protocol.mailto.Handler.instance; } return null; } }); // Start the webserver System.out.println("Starting web server..."); com.qindesign.tini.http.HttpServer server = new com.qindesign.tini.http.ServletHttpServer(props); new Thread(server).start(); // Now other tasks can be performed here // The server can be shut down with "server.shutdown()" } /** * Store the data for the configuration files. */ private static void storeFiles() throws IOException { // Create the necessary parent directories if (!new File("/web").mkdir() || !new File("/web/bin").mkdir() || !new File("/web/logs").mkdir() || !new File("/web/http-root").mkdir()) { throw new IOException("Error creating directories"); } // Store /web/bin/webserver.props FileOutputStream out = new FileOutputStream("/web/bin/webserver.props"); out.write(("server.port=80\n" + "server.bufferSize=1024\n" + "server.mimeTypesFile=/web/bin/mimeTypes.props\n" + "server.rootDir=/web/http-root\n" + "server.sendServerHeader=true\n" + "server.shutdownEnabled=true\n" + "server.shutdownPasswordFile=/web/logs/shutdown.pwd\n" + "servlet.propsFile=/web/bin/servlets.props\n" + "servlet.reloadingEnabled=true\n" + "server.log.logFile=/web/logs/webserver.log\n" + "server.log.transferLogFile=/web/logs/transfer.log\n" + "server.log.stackTraceEnabled=true\n") .getBytes()); out.flush(); out.close(); // Store /web/bin/servlets.props out = new FileOutputStream("/web/bin/servlets.props"); out.write(("default.mapping=/\n" + "default.class=com.qindesign.servlet.DefaultServlet\n" + "default.initParams=canBrowseDirs=true\n" + "default.loadOnStartup=true\n" + "RequestInfo.mapping=/servlet/RequestInfo/*\n" + "RequestInfo.class=com.qindesign.servlet.example.RequestInfoServlet\n" + "AuthExample.mapping=/servlet/AuthExample\n" + "AuthExample.class=com.qindesign.servlet.example.AuthExampleServlet\n" + "TiniInfo.mapping=/servlet/TiniInfo\n" + "TiniInfo.class=com.qindesign.servlet.example.TiniInfoServlet\n" + "LogViewer.mapping=/servlet/LogViewer\n" + "LogViewer.class=com.qindesign.servlet.example.LogViewerServlet\n" + "OneWireServlet.mapping=/servlet/OneWireServlet\n" + "OneWireServlet.class=com.qindesign.servlet.example.OneWireServlet\n" + "OneWireServlet.initParams=" + "familyCode10=TemperatureInclude," + "familyCode21=TemperatureInclude," + "familyCode05=SwitchInclude," + "familyCode12=SwitchInclude," + "familyCode1f=SwitchInclude," + "familyCode29=SwitchInclude," + "familyCode20=FamilyCode20Include\n" + "OneWireServlet.loadOnStartup=true\n" + "TemperatureInclude.mapping=\n" + "TemperatureInclude.class=" + com.qindesign.servlet.example.TemperatureInclude\n" + "SwitchInclude.mapping=\n" + "SwitchInclude.class=com.qindesign.servlet.example.SwitchInclude\n" + "FamilyCode20Include.mapping=\n" + "FamilyCode20Include.class=" + com.qindesign.servlet.example.FamilyCode20Include\n") .getBytes()); out.flush(); out.close(); // Store /web/bin/mimeTypes.props out = new FileOutputStream("/web/bin/mimeTypes.props"); out.write((".class=application/java-class\n" + ".css=text/css\n" + ".gif=image/gif\n" + ".htm=text/html\n" + ".html=text/html\n" + ".ico=image/x-icon\n" + ".jar=application/java-archive\n" + ".java=text/x-java-source\n" + ".jpeg=image/jpeg\n" + ".jpg=image/jpeg\n" + ".jnlp=application/x-java-jnlp-file\n" + ".js=application/x-javascript\n" + ".pdf=application/pdf\n" + ".png=image/png\n" + ".ser=application/x-java-serialized-object\n" + ".txt=text/plain\n" + ".xml=text/xml\n" + ".zip=application/zip\n") .getBytes()); out.flush(); out.close(); } } [Top] | ||
Tynamo™-TINI/1.0.4 Email: shawn@pobox.com © 2002-2006 Shawn Silverman |