Channels ▼
RSS

JVM Languages

The TINI Internet Interface

Source Code Accompanies This Article. Download It Now.


Oct00: The TINI Internet Interface

Al is an author and consultant who lives near Houston, Texas. He is the author of Microcontroller Projects with Basic Stamps (R&D Books, 1999) as well as numerous books on Windows programming. Look for Al at http://www.al-williams.com/.


It doesn't take much imagination to see that soon nearly every digital device and appliance will be able to connect to the Internet. Just about everything has a microprocessor these days, so the only trick is adding Internet connectivity. Embedded microprocessor manufacturers know this is the case, and they are scrambling to provide Internet-enabled solutions for embedded developers.

One of the more interesting ideas I've run across is a board from Dallas Semiconductor (http://www.dalsemi.com/) called the "Tiny InterNet Interface" (TINI). This 1.25X4.05-inch printed-circuit board (see Figure 1) looks like a standard memory SIMM. However, on this diminutive board is a Java-capable microprocessor, at least 512 K of nonvolatile memory, and an Ethernet transceiver. In addition, there are a variety of interfaces to connect to external devices (I2C, CAN, RS232, and 1-wire) and a full bus-oriented interface on the SIMM's edge connector. For details on the TINI board, go to http://www.ibutton .com/TINI/index.html.

What Can It Do?

The TINI's biggest strength is that it has Java built in -- well, almost. The TINI's firmware (which you can load using a special tool) has a specially adapted Java Virtual Machine (JVM) that runs with the limited hardware and memory that the TINI has available. This JVM does not run standard class files, and doesn't support everything that a normal workstation's JVM supports. Still, it is surprising how much the JVM does support.

For example, the TINI can operate as a web, FTP, and Telnet server -- all at the same time. The web server even supports servlets. In fact, the most common way to load programs into the TINI is to use FTP. Dallas Semiconductor supplies custom classes to operate the special hardware and the standard javax.comm package for serial port. The java.lang, java.net, java.io, and java.util packages are a semipermanent part of the firmware. You can selectively load other packages as needed into RAM.

What isn't included? That depends. As of beta 2, java.io is missing object-serialization functions; java.lang doesn't support reflection, the FloatingDecimal class, and transcendental functions; and java.util doesn't contain the Calendar, Date, and related classes. Dallas Semiconductor documents what isn't in the JVM, but you won't often need what is missing for embedded development.

Getting Started

The easiest way to get up and running with the TINI is to buy the TINI Sockets board from Dallas Semiconductor. This is simply a board with a SIMM socket for the TINI, a power supply, and connectors for RS232 and 10base-T Ethernet. This makes it simple to power up the TINI and connect things to it. Of course, for production, you'd probably use the TINI board separately (or perhaps even the chipset, which Dallas will sell separately). However, for development, the Sockets board is the way to go.

Once you get the TINI powered up, you'll need to be running a computer with an RS232 port tied to the TINI's main serial port (SERIAL0). The connection only requires a 3-wire cable. By default, however, the board uses the DTR signal from the computer to reset the TINI. The Dallas Semiconductor software contains JavaKit, a special program that is written in Java. Therefore, it should run on any computer that supports Java -- including the javax.comm API for accessing serial ports. I've run the program on a PC (which is what the instructions assume) and others running JavaKit under Linux (see http://www.apms.com.au/tini/javakit.html).

The purpose of JavaKit is to load basic software into the TINI. You can follow the directions provided with the board to load the basic JVM and other necessary firmware. After everything is set, you will also want to load a default program. Before deploying the TINI, you might want to place your own software here. However, for development, you'll probably just load SLUSH, a command shell similar to a stripped-down UNIX command shell. SLUSH lets you manage what is in the TINI's memory, check its status, set up its Ethernet interface, and run programs. This is the program that responds to requests over the serial port and Telnet, by default.

If you are comfortable with UNIX, SLUSH isn't a problem. You can type "help" to see a list of commands and you can also use help to get specific help on each command. You can log into the TINI (using the default root or guest account). Probably the first thing you'll do is set up the TINI's Ethernet interface. You can issue an ipconfig command to set the IP address, network mask, and gateway address. You can also specify that the TINI should get an IP address from a DHCP server.

Once you have the Ethernet interface running, you'll probably do your interactions with the TINI via Telnet. By default, the TINI constantly listens for logins over the serial port and Telnet. It also listens for FTP requests. You can stop these servers using the downserver command (or restart them with startserver). For example, you might want to release the serial port for other uses, so you could enter downserver -s to stop the serial server from accepting logins.

Of course, you need to connect the TINI board to your network. If you already use 10base-T and you have a spare port on a nearby hub, you can connect a cable from the TINI socket board to the hub. If you are just doing development and don't want a full-blown network, you can use a computer with an appropriate network card and cross-over cable. (These cables are specifically for connecting two -- and only two -- computers together without a hub.)

Building Programs

Once you can log into the TINI, you are ready to go. To write TINI programs, you need a Java development environment such as the Sun JDK (that's what I use) or any standard Java IDE (Borland's JBuilder, for example). You'll need to set the Java compiler's options to use the TINI classes (for the Sun JDK, use the -bootclasspath option with the path name to the tiniclasses.jar file).

Once you have a class file, the next step is to convert it into a format appropriate for the TINI to use. You do this by running the Java program TINIConvertor. Use the -f option to name the class file you want to convert. The -o option names the output file. The -d option specifies a database that corresponds with the loaded TINI firmware. In the absence of other options, the converter sets the file so that the main function in the first class you name will execute. I use the following batch file to automatically run TINIConvertor:

java TINIConvertor -f %1.class -o %1.tini -d

e:\tini\TINIBeta2\firmware\tini.db

You supply the name of the class as an argument, and the result is a .tini file suitable for execution on the board.

Assuming you don't get any compile errors (or errors while converting the file) you are ready to send the output file to the TINI. The easiest way to do this is with FTP. Once the file is in place, you can issue a SLUSH command to start it. If your file is test.tini, you start it with java test.tini. You can add command-line parameters if you like. An & character at the end of the line starts the program and returns you to the SLUSH prompt immediately.

If you want to automatically start a program, use the /etc/.startup file, which provides SLUSH a set of commands to execute at startup. However, for production use, you'd probably want to replace SLUSH with your own program. To do this, you have to run another conversion step. For example,

java com.dalsemi.tiniconvertor.BinToHex -input

Filename.tini -output Filename -startBank 7 -hex386

produces an image file you can load with JavaKit instead of SLUSH.

A Simple Project

The TINI has lots of potential. With its multitude of interfaces, you can use it as an intelligent bridge between practically any device and any network -- including the Internet. Suppose you want to measure several process variables in a manufacturing plant. Since there is a web server that supports servlets available, you could simply collect the data using the TINI and make the parameters available as part of a web page. Anyone on the network could monitor the plant's operation using an ordinary web browser. The Java code could perform engineering unit conversion, averaging, or store historical data.

Of course, you might want another program to read the data instead of a web browser. That's even easier, because Java makes working with sockets a snap. The test program I present here reads input from the RS232 port and sends it to a socket on a remote computer. A companion Java program running on the remote computer simply displays the data. In real life, it might display the results graphically, or save the values in a file.

RS232 Woes

Technically, the TINI supports four serial ports. However, one of them is a TTL serial port and doesn't have full support in the current release of the firmware. Two other ports require external UARTs. That leaves the main serial port as the only functional, true RS232 port on the board without adding more hardware.

Unfortunately, SLUSH and the system console use this serial port. Consequently, you must shut down SLUSH's serial server (using downserver -s -d) if you want to use the serial port from your own program. You can also modify the /etc/.startup file to prevent the serial server from loading. If you replace SLUSH with your own program you can use the serial port freely.

Dallas Semiconductor supplies a custom object that lets you use the serial port (the source code for SLUSH is a good example of how to use it). However, recent versions support the standard javax.comm package, so the custom routines are now deprecated.

With some experimentation, you'll find that the serial port doesn't support all possible baud rates, nor does it support flow control. I couldn't find a single place where the capabilities were documented, but your program will throw an exception when you try to use something that isn't there.

Inside the Project

Currently, I have a custom piece of hardware that uses a Motorola 68HC11 CPU to convert four voltages into digital values, then sends them to a PC using 9600-baud RS232. The data is formatted as four hex numbers, separated by spaces, and ending in a carriage return. The RS232 cable limits the distance the instrument can be from the PC. If the PC is on the LAN, that's fine, but it seems silly to dedicate a PC simply to use as a network gateway for this device.

Listing One is the SerialSender class, a Java program that requires two arguments. The first argument is the IP (or host name) of the computer that should receive the data. The second argument is the port number that the computer is using. Most of the action occurs in the go subroutine.

First, the program opens a socket -- remember, this is on a tiny embedded computer that costs about $50.00. Still, the code is identical to how you'd open a socket on a PC or any other Java platform, for that matter. The program then writes the string "Start" to the socket as a debugging aid. The code flushes the socket. This way if the RS232 code goes astray, you'll still see the debugging message. Without the flush, the string could be waiting in limbo after the code hangs. This gives you the incorrect impression that the socket code did not work, when in fact it is the RS232 code that is the culprit.

The javax.comm package provides a standard way to use communication ports under Java. The basic sequence of steps that you'll use to open an input stream on a serial port is:

1. Create a CommPortIdentifier object that names the serial port (for the TINI this is serial0) by calling the static method CommPortIdentifier.getPortIdentifier.

2. Use the object's open method to create a SerialPort object.

3. Use setSerialPortParams to set the SerialPort's baud rate and other parameters.

4. Call getInputStream to return an InputStream object that refers to the port.

This InputStream object is like any other. In fact, for debugging purposes, you might want to replace the serial port code with is=System.in; which lets you use the standard input stream as a source for input (so you can enter characters from the SLUSH terminal or a Telnet session).

After both the port and the socket are ready, a while loop reads characters from the port and sends them to the socket. On receipt of an end-of-line character, the program flushes the socket so that the remote computer receives frequent updates.

The Other Side

Listing Two is the Java program for the host computer. This is an ordinary Java program that doesn't require any special TINI classes or conversion to run. It only requires one argument, a port number.

Instead of an ordinary socket, the host program uses ServerSocket, a specialized class that handles all of the details required to wait for client requests. Because the program only handles one client at a time, the program closes the socket after the call to accept (which returns when a client connects).

Once the socket is ready, it is a simple matter to make a BufferedReader and read the incoming data a line at a time. Listing Two simply echoes the data to the console output, but the same principle would apply if you wanted to do more sophisticated processing.

Conclusion

For $50.00, the TINI can act as a Java-programmable translator between an Ethernet connection and any other device you can connect to it. Not only is this a very inexpensive option, but Java makes it almost trivial to write programs that can interact over a network or the Internet.

At first it seems a bit odd to do cross development in Java and then download to the target computer using FTP. However, the fact that this modest board can support HTTP, FTP, Telnet, and serial servers is a testament to its true power.

Remember, the TINI is in beta testing as I write this. It still has some kinks. For example, several times during development my RAM corrupted and I had to go back to the loader and clear the heap before anything would work again. Assuming Dallas Semiconductor gets all the quirks out of the TINI, however, it looks like a winner.

DDJ

Listing One

// TINI sender class
import java.io.*;
import java.net.*;
import javax.comm.*;

public class SerialSender
  {
  SerialPort rs232;
  Socket sock;
  OutputStreamWriter os;
  InputStream is;
  String msg;
  public static void main(String args[])
   {
   if (args.length!=2)   // check arguments and go
     {
     System.out.println("Usage: SerialSender host port");
     System.exit(9);
     }
   new SerialSender().go(args);
   }
  void procError(String s) // Note: Tini Exceptions don't return messages
   {
   System.out.println("Error");
   System.out.println(s);
   System.exit(1);
   }
// main routine
  public void go(String args[])
    {
// Open socket
    try 
      {
        System.out.println("Connecting to " + args[0] +":"+ args[1]);
        sock=new Socket(args[0],Integer.parseInt(args[1]));
      }
    catch (Exception e)
      {
      procError("Can't open Socket");
      }
// Connect socket to stream
    try
      {
      os=new OutputStreamWriter(sock.getOutputStream());
      os.write("Start\r\n",0,7);
      os.flush();
      }
    catch (Exception e)
      {
      procError("Can't open stream");
      }
// Open RS232
     try
        {
// Use this code to open the RS232 port
        CommPortIdentifier cpi;
        cpi=CommPortIdentifier.getPortIdentifier("serial0");
        if (cpi==null) procError("Can't find SERIAL0");
        rs232 = (SerialPort)cpi.open("SSend",1000);
        rs232.setSerialPortParams(9600,SerialPort.DATABITS_8,
           SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
        is=rs232.getInputStream();
// Or... Just use stdin
//          is=System.in;
        }
        catch (Exception e)
         {
         procError("Can't open RS232 port " +msg);
         }
// main loop
    while (true) 
      {
      int c;
      try
        {
        c=is.read();
        }
      catch (Exception e) 
        {
        continue; // ignore rs232 exceptions
        }
      try
        {
        if (c==13) c=10;  // cr to LF
        os.write(c);
        if (c==10) os.flush();
        }
      catch (Exception e)
        {
        procError("Write error");
        }
      }
     }
    }

Back to Article

Listing Two

// Host program
import java.io.*;
import java.net.*;
public class SerialRcv
  {
  ServerSocket ssock;
  BufferedReader br;
  Socket sock;
  public static void main(String args[])
    {
    if (args.length!=1)  // check arguments and go
      {
      System.out.println("Usage: SerialRcv port");
      System.exit(1);
      }
    new SerialRcv().go(args);
    }
// main routine
  public void go(String args[])
    {
// get a connection
    try
      {
      ssock=new ServerSocket(Integer.parseInt(args[0]));
System.out.println("Listening on port " + args[0]);
      sock=ssock.accept();
      ssock.close(); // quit listening
      System.out.println("Status: Connection established");
      br=new BufferedReader(
         new InputStreamReader(
          sock.getInputStream()));
      }
    catch (Exception e)
      {
      System.out.println("Can't open or connect server socket");
      System.exit(1);
      }
// main loop
    while (true)
      {
      try
        {
        String s=br.readLine();
        if (s==null) break;
        if (s.length()==0) continue;  // no blank lines
        System.out.println(s);
        }
       catch (Exception e)
        {
        System.out.println("Read error");
        System.exit(2);
        }
      }
    }
  } 



Back to Article


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video