Programming example: the watchdog timer

7 May

Programming example: the watchdog timer

The CPU has an interesting feature known as a watchdog timer, that we can utilize in our Java applications. The watchdog timer is a clock, internal to the CPU, that keeps track of the passage of time since the last time it was fed. If the watchdog timer doesn’t get fed within a certain interval, it resets the CPU. You can set this interval. Below is a very simple program that demonstrates the use of the watchdog timer. You pass the program one command line parameter, the timer interval, in milliseconds. The watchdog will start counting down, and if your interval of time passes, TINI will reboot. You can feed the timer, restarting the timer, and temporarily preventing the reboot by hitting any key. We’ll first present the code in its entirety, then we’ll go through it bit by bit.

Listing 6-1: WatchDogDemo.java
import java.io.*;
import com.dalsemi.system.*;
public class WatchDogDemo {
public static void main(String[] args) {
int feedInterval;

if (args.length == 0) {
feedInterval = 10000;
} else {
feedInterval = Integer.parseInt(args[0]);
}
TINIOS.setWatchdogTimeout(feedInterval);
System.out.println(“Hit any key to feed the dog!”);
while(true) {
try {
int keyBoardInput = System.in.read();
} catch(Exception e) {System.out.println(e);}
TINIOS.feedWatchdog();
System.out.println(“You have just fed the watchdog!”);
}
}
}
We need to import two libraries, java.io because we print to the screen, and
com.dalsemi.system, because that’s where the watchdog class lives. Our class will
be called WatchDogDemo.
import java.io.*;
import com.dalsemi.system.*;
public class WatchDogDemo {

Our program has one method, main(). We begin by doing some simple checking to make sure we have been given a command line parameter. If not, we will use a default of 10 seconds, which is 10000 milliseconds. The integer, feedInterval, is the time interval for our watchdog timer.

public static void main(String[] args) {
int feedInterval;
if (args.length == 0) {
feedInterval = 10000;
} else {
feedInterval = Integer.parseInt(args[0]);
}

Next, we set the watchdog timer interval, by using the TINIOS.setWatchdogTimeout() method. We also print a line to the screen, giving instructions. TINIOS.setWatchdogTimeout(feedInterval);
System.out.println(“Hit any key to feed the dog!”);

We create a loop, which will wait for a key to be pressed.
Whenever a key is pressed, we’ll exit the loop, and feed the dog with the TINIOS.feedWatchdog() method, and print a phrase to the screen. If we don’t exit the loop by the time the timer expires, the
TINI will reboot.
while(true) {
try {
int keyBoardInput = System.in.read();
} catch(Exception e) {System.out.println(e);}
TINIOS.feedWatchdog();
System.out.println(“You have just fed the watchdog!”);
}
}
}

The following are the commands that can be used to compile the program. We are assuming that the WatchDogDemo.java file is in its own folder, and the commands below are being executed in that folder. Again, the Javac and Java commands are shown with their command line parameters on separate lines, only for readability. They all need to be on the same line for each command.

C:\> javac -classpath %TINI_HOME%\bin\tiniclasses.jar
-d tini WatchDogDemo.java
C:\> java -classpath %TINI_HOME%\bin\tini.jar TINIConvertor
-f tini
-o tini\WatchDogDemo.tini
-d %TINI_HOME%\bin\tini.db

Figure 6-5 shows a screen capture of the WatchDogDemo program in action. We could execute the program from a Telnet session through Ethernet, but we won’t see exactly when the reboot happens, as nothing will be printed back to us (we’ll simply lose the connection). So, we’ve used JavaKit to demonstrate it, because this will allow us to see exactly when the watchdog reboots, as the system messages will be echoed back to us during the reboot. In the example, we’ve moved the program over to TINI via ftp (Ethernet), then logged onto the stick via JavaKit. Upon running the program, we’ve selected a 5-second delay between “feedings.” We hit a key a couple of times, at less than 5-second intervals, to feed the dog, then let the watchdog reboot.

The Memory

A few words about the TINI address space
The term address space refers to the range of addresses that the TINI operating system can make use of. This address space bears some examination. The TINI address space is broken up into two four-megabyte blocks: 0-0×3FFFFF and 0×800000-0xBFFFFF. This immediately leads to an interesting question. The TINI schematic shows a 20-bit address bus, which implies our address space should be 1 Mbyte. If our address bus is only 20 bits, how can we address 8 Mbytes? The answer is through the use of the chip enable signals, /CE0-/CE03, and /PCE0-/PCE3. Each of these chip enables refers to 1 Mbyte of our 8-Mbyte space.

Table 6-2: Mapping chip enable signals to the address regions they select

So, on the TINI stick, we’ll see a 20-bit address whose placement within the 8-Mbyte space is determined by which one (and only one) of the chip enables is pulled low (Table 6-2). Even though we only have those 20 address lines on the stick, in software, we will proceed as if we have a 24-bit address bus. For example, the Dataport class makes use of addresses 0×00000000 – 0×003FFFFF, and 0×00800000 – 0×00BFFFFF. The TINI Firmware will look at the lower 20 bits of that and send it out TINI stick signal lines A0 – A19, while it uses the upper four bits to select which of the eight chip select signals is to be driven low. Many examples using the Dataport class are included in Chapter 9, when we discuss memory-mapped I/O.

The TINI memory map

In the previous section, we looked at the address space of TINI. A related concept is the memory map. The memory map defines where the TINI OS thinks devices reside within the address space. A general memory map for TINI has been documented in several places by the manufacturer, but a more detailed memory map has only been discussed in the TINI interest group message archive3. Below, we’re going to present the memory map as described in the interest group. In doing so, we’re also incorporating corrections that were presented in the message archive.

1 The 512K memory has an 18 bit address bus, but is residing in a 1Mbyte region in memory. This means that two addresses refer to the same spot in memory, which results in the lower half of this 1Mbyte memory space looking exactly like the upper half (an image of itself). 2 See note 1. 3 See note 1. 4 If we just look at the address bits involved on the LAN91C96 device, it would appear that it could reside in a larger space. It’s place in the memory map as presented here has been taken on faith from discussions on the TINI interest group message. 5 While the Real Time Clock has been given a 64K block in memory, it only uses one specific location within that block. The rest is room for future expansion. 6 The memory map as posted to the TINI interest group message list had this region as being 0×320000 – 0×38FFFF. We believe that was a typo. In our map, again, we see 24-bit addresses. The lower 20 bits map directly to A0- A19 on the stick, and the upper four bits imply one of eight chip enables going to logic ‘0’. There are a couple of items to note about the map. The first deals with the concept of images. Our memory parts are 512k each, and as such, they only use a 19-bit address bus. But they are residing in their own 1-Mbyte memory space within the map. This means that there is a redundancy in our addressing: two memory map addresses map to a single physical memory location. So, one-half of the 1-Mbyte region will look exactly like the other half, hence the term image. The second thing to note about this map is that there are subtleties involved with respect to how the firmware and hardware interact, making it difficult to see why the map is defined the way it is sometimes. As we go through the individual portions of the design, we’ll discuss what we know about why this map is defined the way it is.

Random Posts

Comments are closed.