When most people hear about the iPAQ handheld, they find that it's pretty much like any other personal digital assistant. Made by Compaq, this PDA is similar to the Palm series of pocket-sized organizers. Both have touch-sensitive displays (for handwriting recognition) and can keep track of addresses, important dates, your to-do list, and so on. But the iPAQ is much more powerful. Even the low-end models have faster processors, higher-resolution displays, and more RAM than any Palm-compatible handheld on the market today.
For most users, this extra power doesn't provide much more than an ability to play videos and store gazillions of documents. For developers, however, the possibilities are more pervasive. The iPAQ is a full-fledged computer, versatile enough to run multiple operating systems and all kinds of applications. Proof of this comes from a Compaq research project launched in 2000 to explore the potential of running open-source software on handheld computers. The most significant result of this research is a version of Linux designed specifically for the iPAQ. For the first time, the world of Linux applications is now available on the iPAQ, and developers can write software for it without purchasing an expensive, proprietary development kit.
Recently, I decided to try an experiment to see just how feasible it was to write Linux software on the iPAQ. Rather than build an address book, a calendar, or some other copycat program, I wanted to see how the iPAQ would perform in an industrial setting, perhaps by integrating with some kind of embedded system. My end goal was to build a handheld controller for an industrial sensor or machine. After a little thought, I decided that a simple servo motor (available at any hobby supply store) would stand in as my pseudo-industrial application. The handheld controller would hook up to the motor, display its position, and, at the user's request, rotate the motor to a new position. I thought that these requirements would be complex enough to be interesting and non-trivial without making my experiment unnecessarily difficult.
A few weeks later, I had in my hands an embedded device that met my requirements. More importantly, it had taught me a lot about running Linux on the iPAQ and writing code for its unique processor: the StrongARM. In this article, I'll share what I've learned and explain the benefits and caveats of programming the iPAQ. Hopefully, I'll spark some new ideas for your next embedded project.
Unpacking the iPAQ
In April 2000, the first iPAQ went on sale, and according to the Guiness Book of World Records, it was the most powerful PDA available. The latest models feature a 400 MHz processor and 64 MB of RAM with 48 MB of Flash ROM for the operating system. (In a pocket-sized device, those specs are quite astonishing when you consider that desktop PCs just a few years ago didn't have that kind of computing power.) Other highlights include a speaker, microphone, infrared port, and touch-sensitive 16-bit color display. Microsoft's Pocket PC operating system is installed on all iPAQs at the factory and includes the usual collection of productivity applications: calendar, email client, miniature word processor, and so on. Clearly, the device was designed with mainstream consumers and business applications in mind.
But the iPAQ is attractive to embedded systems developers, too. Not only is it a powerful machine for hosting custom applications, but it also has a lithium-ion battery and high-density plastic shell that make it very portable and relatively durable in industrial environments. Inside, it has a full-fledged memory management unit, 20-bit stereo sound system, six-channel DMA controller, plus controllers for PC Card, USB, RS-232, and IrDA. With these features, the iPAQ is basically a desktop computer that just happens to have a stylus instead of a keyboard. It can run almost any program you can implement in C (and other languages, as I'll explain later) with minimal tweaking. The only drawback is the diminutive 240x320 resolution of its display, although most embedded applications don't require a detailed GUI anyway. Overall, the fancy features of the iPAQ allow embedded developers to spend less time getting around hardware limitations and more time implementing the requirements of their designs.
If a particular design requires custom hardware, the iPAQ can interface with it through a serial port, or, for a more compact package, the hardware can piggyback as a "sleeve" a plastic sheath that slides onto the back of the iPAQ and hooks up to its proprietary expansion port. Symbol Technologies, for instance, sells an iPAQ sleeve that integrates a bar-code scanner with a wireless network adapter. The idea is that embedded developers would only have to write some software in order to construct a mobile inventory management system. Building hardware as a sleeve, unfortunately, requires a proprietary design that works on the iPAQ exclusively. For a more industry-standard approach, you could implement the hardware as a PC Card that attaches directly to the iPAQ. (An optional PC Card adapter sleeve would still be required in this case.) Several vendors already offer PC Cards that give the iPAQ wireless networking, GPS navigation, and similar features.
It seems reasonable that an embedded system could be produced faster and more cheaply by building only the specialized hardware as a PC Card and plugging it into an iPAQ, rather than designing the entire system from the ground up. For example, a data acquisition device would need custom hardware simply for acquiring the data. The rest of the necessary electronics for processing and displaying the data has already been built, debugged, and is available off-the-shelf inside every iPAQ. Even if the power of the iPAQ is far more than an embedded project requires, its status as a mass-market device manufactured in the hundreds of thousands could actually make it cheaper than less-powerful one-off designs.
Of course, whether you base your embedded project on custom hardware or the iPAQ, you'll still have to write software for it, and on the iPAQ, that software must run on the StrongARM, the microprocessor at the core of nearly all iPAQ models. The StrongARM has a curious history because it has never been manufactured by ARM Ltd., the designers of the original family of 32-bit RISC processors known collectively as ARM. In fact, ARM Ltd. seldom fabricates any silicon, preferring instead to license its embedded processor designs to manufacturers. This is exactly what the company did in 1995 when it sold Digital Equipment Corporation the rights to build an enhanced version of the ARM core. The new version quadrupled the clock rate of the ARM while preserving its low-power characteristics. Today, StrongARM processors can run at 233 MHz without any heat sink or other cooling method, making them suitable for CPU-intensive embedded devices such as the iPAQ.
History lesson's over; it's time to compile some code. You've got plenty of options:
- Buy an ARM SDK. Several companies, including Mentor Graphics, Metrowerks, and (of course) ARM, sell complete development kits with graphical debuggers and powerful source-code editors. The power comes at a price: each kit costs several thousand dollars.
- Download and compile GNU GCC. The GNU GCC compiler is an alternative for developers who want to get started programming for ARM without making a heavy investment. You can download the source for free from <www.gnu.org>. Compiling GCC for the ARM target can be tricky, however, and you must compile the binutils and glibc libraries, as well. But once you've got them built, you can compile source code on your desktop PC and then copy the ARM executable to the iPAQ. (This is known as "cross-compiling.")
- Download a pre-compiled GNU GCC for ARM. A quicker, easier way to get GNU GCC is to download a set of binaries, or a "toolchain," already configured for the ARM target. Toolchains are hard-coded for a particular host that is, the computer that actually does the compiling and every toolchain I've found assumes that the host computer runs Linux. You might be out of luck if you want a pre-compiled GCC for other systems. (See the Links section for the location of Linux-hosted toolchains.)
- Log on to an iPAQ at CRL. CRL (Cambridge Research Labs) is the east coast division of Compaq's research team, and they've hooked up 40 GB hard drives and Ethernet cards to a bunch of iPAQs and put them on the Internet. Each one runs Linux and has a copy of the GCC toolchain. Anyone can telnet into one of these iPAQs, compile source code remotely, and then copy the executable back to their local machine. This type of development process, called native compiling, avoids the hassle of getting directory names and library locations just right for cross-compiling. But it is also dangerous: code compiled on CRL's iPAQs might not run on yours due to library mismatches.
- Compile code on your own iPAQ. GCC can compile itself with ARM as its target, thus producing a toolchain with iPAQ as the host. You could then do native compiling on your own iPAQ; some developers see this as the ideal build environment. There's a catch, though. The GCC toolchain is too large to fit on a standard iPAQ and requires extra storage space, either as a memory card add-on or a remote drive mounted on the iPAQ through a network.
All of these methods assume that your iPAQ is running a third-party operating system such as Linux or QNX Neutrino. If you want to develop software for the Pocket PC that comes with the iPAQ, you'll have to download Microsoft's eMbedded Visual Tools development kit. This kit requires familiarity with the Windows API and puts a number of constraints on the development process. For instance, it forces you to choose either Visual Basic or Visual C++ as both your programming language and development environment. A more subtle disadvantage is the Pocket PC's insistence on a window-icon-menu application structure, and for most embedded applications, this paradigm is less than ideal. Embedded devices in an industrial setting typically perform one specific task, and forcing the user to navigate through application launchers and dialog boxes to accomplish it is generally a bad idea.
Getting Familiar with Linux
For a more open development environment that can accommodate multiple languages and your favorite source-code editor, Linux is probably your best bet. You can't build iPAQ software for Linux in Visual Basic, but just about any other language is possible, including scripting languages like Python and Perl. You can also take your pick of popular widget toolkits such as GTK+ and Qt. And of course, being open source, Linux requires no licensing fees.
Linux's open nature is one of the reasons why its popularity is growing among embedded systems programmers. The key benefit is that it lets you see everything under the hood for no extra charge. With complete access to the source code, you can rip out features to make the OS fit in a tiny space, or you can dump all nine million lines of Linux into your embedded device, assuming it has enough memory.
For the iPAQ, ready-to-run Linux distributions of both extremes are available. On the smaller end of the scale is Familiar, based on the Debian distribution with some modifications by CRL. It includes:
- TinyX, a subset of the X Window System.
- ipkg, a lightweight package management system designed especially for the iPAQ.
- JFFS, a journaling, compressed file system for Flash RAM that distributes write requests evenly in order to extend the life of the RAM.
- BusyBox, a minimal collection of replacements for ls, cp, and enough of the other standard commands to make Linux usable on a diskless device.
If Familiar's subset of Linux doesn't meet your needs, you can install Intimate, a complete Debian distribution for the iPAQ that requires an IBM Microdrive or some other add-on storage to hold its 150 MB of packages. Both of these distributions have fairly convoluted installation procedures, but detailed instructions can be found on the Web at the addresses shown in the Links section.
Before jumping in, however, be aware of a few rough spots. First of all, Linux on the iPAQ is not meant to be a drop-in replacement for the Pocket PC. It has no equivalents for the address book, to-do list, and other PIM applications, although such software is available commercially as shown in Figure 1. Another caveat is that the input methods an on-screen keyboard and a handwriting recognizer aren't as polished as Microsoft's versions. And as for documentation, Linux finds itself in the unique position of suffering from too much of it. I recently wanted to know how to detect a press of the iPAQ's hardware buttons, and I found the answer on the Internet only after sifting through mountains of mailing list archives and HOWTO documents. (As it turns out, the X server in Familiar calls the Record button "XF86AudioRecord," while the hardware buttons at the bottom are, from left to right, "XF86Calendar," "telephone," "XF86Mail," and "XF86Start." These names are the keysym strings to watch for if you need to handle button-press events on the iPAQ.)
A Servo Motor Microcontroller
Despite these troubles, Linux on the iPAQ is still a pretty friendly environment for developing embedded applications. The servo motor experiment that got me going in the first place turned out to be a nice example of this idea. It proved that the iPAQ can work well with any sensor, microcontroller, or other system that has an RS-232 interface (a standard serial port).
To develop the prototype for my servo motor system, I first needed some way of sending commands to the motor. These motors can rotate to any position along 180 degrees of travel and hold there, making them ideal for robots and industrial machines (not to mention RC cars and airplanes). Sending the motor to a specific angle requires a modulated pulse of a specific frequency. This is known as Pulse Coded Modulation, and the longer the pulse, the greater the angle. For instance, a 1.5 ms pulse will turn the motor to 90 degrees, while a 1.75 ms pulse will turn it to 180 degrees.
Because I wanted a human interface for the servo motor, I needed to match these pulses with their corresponding angles (encoded in binary and displayed on the screen as a number). Even today's slowest, tiniest microprocessors can handle this task, but ironically the 32-bit 206 MHz chip in my iPAQ won't work. That's because the only output signal on the iPAQ comes through as RS-232 serial data, which the servo motor doesn't understand.
This is where the skills of a computer scientist end and the job of the embedded engineer begin. I needed to build a stand-alone microcontroller that can read bytes from the iPAQ's serial port, decode them, translate them into pulses, and send those pulses to the servo motor. A few microchips have been designed for this task exclusively, such as the FT639 from FerretTronics. This 8-pin chip needs only two resistors, a diode, and a 5-volt source to control up to five servo motors at once. It takes commands directly from the TX line (pin 3) of a 2,400-baud serial port, so assembly and debugging are pretty easy.
The problem with these dedicated chips is that they serve only one purpose. I wanted a more versatile design, ideally a programmable microcontroller that I could tweak and customize and possibly use in future projects. These days, there's a variety of 8-bit chips with just enough memory for small prototype projects like mine specifically, about a hundred bytes of RAM and less than a kilobyte of EEPROM (or Flash memory) for storing program code. The most popular of these is probably the 8051 family, first invented by Intel back in 1980. At least a dozen different companies have built unique flavors of the 8051 since then, and tons of books and third-party development kits are available. Another popular chip for simple projects is the 68HC11 from Motorola, notable for its 16-bit instructions and address bus. Plenty of assemblers, compilers, and development libraries are available for this series, as well. With these you can write 68HC11 programs in C, BASIC, and even Forth. Finally, there's the extensive line of PICmicro products (PIC = Peripheral Interface Controller) from Microchip. Like the other microcontrollers, they're available with built-in timers (usually with at least one watchdog timer) and a handful of A/D converters. The PIC chips are known for their low pin count and their RISC core, which reduces the number of opcodes to around 30 or 40 (depending on the model), much less than the Motorola's 140+ instructions, for example. The reduced set makes learning PIC assembly language easier but can also make certain routines, such as complex arithmetic expressions, much more difficult to implement.
All of these manufacturers sell their microcontrollers with pretty much the same range of features. You can buy chips with oodles of EEPROM or none at all, extra A/D converters or timers, and so on. For this reason, most developers base their choice of microcontroller not on design constraints but on the availability of development kits, quality of technical support, price, and other non-technical factors — anything that will shorten their development cycle. For instance, I selected Microchip's PIC16F84 for my project not because of its particular features (1 KB Flash, 68 bytes RAM, 10 MHz maximum frequency), but because it happens to be so popular that I could find documents on the Internet describing a PIC-based servo motor controller. This was exactly what I needed for my project and would let me avoid the trouble of writing the microcontroller code and designing the circuit from scratch. (Copyright issues weren't a concern because I didn't need to distribute the controller code or schematic.)
Eventually, I settled on a design from Reynolds Electronics (<www.rentron.com/servo.htm>). It can control up to seven servo motors using a couple of resistors, a 4 MHz crystal, and a PIC16F84 burned with about 700 bytes of code. This code is just a loop that reads input from pin 6 of the microcontroller (which is tied to the TX line of a serial port, such as the one on the iPAQ). The first byte read is the servo motor index (zero to six); the second is the angular position for that motor to turn to. The code uses these values to send 40 pulses of the appropriate width in 20 ms intervals. (Fewer than 40 pulses would probably be enough, but the code needs to make sure the pulses last long enough for the motor to detect.) It then starts over from the beginning and waits for more input. The complete PicBasic source code is on the Reynolds Electronics website.
Because the microcontroller handles the grunt work of converting the serial commands into electrical pulses, I only had to construct the circuit, burn the Reynolds Electronics code into the PIC16F84, and plug it in. The only missing piece in my project was a Linux program that could send commands from the iPAQ to the microcontroller.
Sending Serial Port Commands
When I began writing a program to do this, I discovered one of the nicer things about programming for Linux on the iPAQ: the libraries are exactly the same. I didn't have to lose any time learning a new API because I was already familiar with Linux programming. For example, in order to send commands from the iPAQ to the microcontroller, I used the same POSIX functions that I had used before in desktop distributions of Linux. (POSIX is the standard API for all Unix-like operating systems, including Linux.) These functions, shown in Table 1, can open a serial port, configure it, and send bytes through it.
The only difficulty I ran into when calling these functions is that the iPAQ's serial cable (which isn't bundled, by the way, and must be purchased separately) connects through a port called /dev/ttySA0. This is different from the standard /dev/ttyS0 port name in the PC. I also ran into a minor snag when I forgot to give the proper permissions for the iPAQ's port, but I fixed this easily by running the application as the root user. (As a safer alternative, I could have used the chmod command to give write-access permissions to /dev/ttySA0 for all users.)
Line 29 of Listing 1 shows how I called the POSIX functions to open the serial port on the iPAQ. First, I called open and passed the iPAQ port name, /dev/ttySA0, as a string in the first parameter. The second parameter is a bit field that tells how the port should be opened, such as O_WRONLY for writing only, O_NOCTTY to specify no controlling terminal, and O_NDELAY to return without waiting for the port to become available. (For a complete list of bit fields, see the man pages for open, section 2.)
Lines 38 through 40 in Listing 1 might look confusing, but they merely set the serial port to 2,400 baud. This requires a roundabout method of retrieving the current serial-port parameters, changing the speed flag, and setting the parameters back again.
The last line of this function returns the serial-port handle. The calling program has the responsibility of checking the return value to make sure it's not -1 (an error). If the return value is okay, the program can send bytes through the serial port by calling write, which takes the serial-port handle, a buffer of bytes, and the buffer size as parameters. You can see an example of this on line 25, where the code sends two bytes through the iPAQ's serial port and into the microcontroller: one byte to specify the servo motor ID number (always 1 in this case) and another byte to specify the position for the motor to turn to.
Once over these hurdles, I still couldn't be sure whether my code was sending the proper data to the microcontroller. I needed to see exactly what bytes were coming out of the serial port, but unfortunately I wasn't aware of any software tool that can spy on RS-232 data sent by another process. As a workaround, I dug up a null modem cable from a bucket of parts and hooked it up between the iPAQ and my PC. I then ran a serial port logging utility on my PC called Serial Device Tester from H.A.c.K Consulting (although any similar utility will also work). This program showed the actual bytes that the iPAQ was sending through its serial port and proved that the POSIX routines were working.
The GTK+ User Interface
So far, everything seemed fine under the hood, but my program still had no user interface. And although it was just a small project, I wanted this user interface to show the versatility of the iPAQ in embedded systems. For instance, in a traditional embedded system controller, the user interface is fixed. The buttons or dials are physical and often custom-built for each new project. This can get expensive, especially if you need to change the layout of the controls halfway through the development cycle.
The iPAQ's touch screen eliminates this problem. Instead of constructing a dial out of metal or plastic, I can simply write software to draw it on the screen. The user can then tap the virtual dial with the stylus to get the same effect as a real dial. If, at some point, I decide that a numeric keypad would work better than an analog dial, I can make the change cheaply and quickly just by rewriting code. For my servo controller program, I decided to give the user the best of both worlds by providing an option for choosing the input method at run time, as shown in Figure 2.
Of course, implementing this option, as well as the on-screen dials and buttons, is best accomplished with the help of a widget toolkit. Several high-quality toolkits for Linux are available: Fast Light Toolkit, Qt, FOX, and more. For this project, I chose the ever-popular GTK+ simply because I had worked with GTK+ in past projects, and its libraries are already included in the Familiar distribution. A big bonus with GTK+ is that its API, like any good toolkit, is identical across all platforms. This allowed me to build the application's framework on my desktop computer, iron out all the wrinkles, and then add the serial-port routines once the code was stable enough to test on the iPAQ.
This kind of cross-platform development required a makefile that could build either an x86 or an ARM executable, depending on whether I wanted to test the code on my desktop or the iPAQ. For this I needed two makefile variables, CC and GTK-CONFIG, as shown in Listing 2. By default, they point to the ARM versions of the GCC compiler and the gtk-config script (for automatically locating GTK+ header and library paths). To build the ARM target, I just run make as usual, but if I want to build the x86 target instead, I modify the variables at the command line:
make CC=gcc GTK-CONFIG=gtk-config
These changes remove the path from the commands, forcing the makefile to find the x86 versions in my system path instead of the hard-coded ARM toolchain. I can then build a prototype of the iPAQ program on my PC, which compiles code faster and has my favorite source-code editor (jEdit) already installed. I can also run the prototype right on my desktop screen, which not only avoids the extra step of copying the executable to the iPAQ, but also allows me to send input to the program with the desktop's keyboard and mouse. (Otherwise, with the iPAQ's microscopic on-screen keyboard and stylus, I can only do about 15 words per minute.) These differences might seem small, but I've found that they make my compile-debug-edit cycle go much faster.
Eventually, I would have to test the iPAQ-specific serial-port routines, and of course I wanted to verify that my program runs on an actual ARM processor. For that, I compiled the ARM executable on my desktop and copied it to the iPAQ using scp, a standard Unix command for sending files across remote machines. Obviously, the iPAQ isn't exactly "remote," given that it's tied to my desktop with a three-foot serial cable, but it's technically a remote machine because it communicates through the cable with PPP. Instructions for setting up a PPP connection to the iPAQ and sending files to it are at <www.handhelds.org>. (See the Links section for details.)
Listing 1 shows the end result of all this effort: a relatively simple GTK+ application. In main, I first get a handle to the serial port and initialize GTK+. Then I go through the obligatory process of creating the main window, setting its layout, and adding widgets using standard GTK+ functions. Notice, in line 79, that I create a notebook widget. This is where I fulfill my promise to give the user a choice of input methods, either analog or digital. The widget automatically sets up tabs in the dialog box, one to hold a dial and another to hold a numeric keypad, but it's my job to add these widgets, as shown in lines 81 and 85. When the program runs, the user can switch between the widgets by clicking (or tapping, in the case of the iPAQ) on the tabs.
Creating those analog and digital widgets was the tricky part. There is no standard dial widget in GTK+, although the official GTK+ tutorial includes a free (under the LGPL license) custom widget that implements a dial, complete with tick marks and 3-D highlighting. I took the path of least resistance and simply included the source files for this dial in my project. Lines 73 through 77 show where I created the widget and set its boundaries as 0 to 180, representing the 180 degrees of motion for the servo motor.
For the numeric keypad, I had to create my own custom widget, called numberpad, as shown in Listings 3 and 4. The numberpad_get_type and numberpad_new functions are simple enough; they just initialize the numberpad class and instances of numberpad objects, respectively. (numberpad is a descendant of the GtkVBox class, a standard widget container.) Things get a little messy in the numberpad_init function, where I add GTK+ buttons in a 3x4 table. This task was more difficult than I had expected because getting the calculator-style layout of the number buttons requires some extra logic note the funky for loops and the special case for the "zero" button in lines 77 through 88.
When the user clicks on one of these buttons, GTK+ invokes my numberpad_clicked function. This function, which I had previously registered as a callback using gtk_signal_connect (see line 68), uses a quick-and-dirty method to record the numbers entered into the number pad. It simply adds each new number to an array of characters, and when the Enter button is pressed, the function converts this string to an integer and broadcasts it as a value_changed event.
Coming full circle back to the main program, the value_changed event handler is in Listing 1, line 10. (Notice that the handler is the same for both the dial and number pad, thus reducing and simplifying the code, thanks to the abstraction provided by GTK+.) The function first makes sure that the value of the number has changed in order to avoid sending redundant signals to the servo motor. Next, it updates a label widget to show the new angle of the motor. Finally, it sends the angle to the microcontroller through the iPAQ's serial port using the handle obtained at the start of the program. Figure 3 shows the program and microcontroller in action.
The Coolness Factor
My servo controller experiment was just a proof-of-concept, an example of what can be done with the iPAQ. If I wanted to get really fancy, I might have internationalized the labels in the program. For instance, I could have added French, German, and other translations for the labels in the program, such as "Analog" and "Digital." This would have shown an additional benefit of having a virtual, software-based user interface for embedded systems control. Other ideas for using the iPAQ in embedded systems are limited only by your imagination. By following the example in the code listing, you can make the iPAQ talk to any device that has a standard RS-232 port.
Unfortunately, if you want to find other developers online to discuss your new project or ask for help, you might have trouble. Development of Linux on the iPAQ seems to have stagnated recently. In the tradition of so many new technologies, there was a flurry of activity when Compaq announced the first Linux port for the iPAQ in June 2000. Since then, news sites like <www.ipaqlinux.com> haven't been updated, and hackers have stopped trying to run Quake on the StrongARM. (They discovered that NetWinder's floating-point emulation makes it crawl at just one frame per second.)
Nevertheless, new versions of the Familiar distribution appear quietly around three times a year, and mailing lists about Linux on the iPAQ still move hundreds of messages every month. The "coolness factor" has presumably worn off, and now everyone is concentrating on getting real work done. Luckily, the developer community for Linux and the iPAQ still exists and can only make your next embedded project a whole lot easier.
iPAQ on Linux
<www.handhelds.org> Home of a research project dedicated to open-source software on handheld computers, sponsored by Compaq.
<http://familiar.handhelds.org> Home of Familiar, a lightweight Linux distribution for the iPAQ.
<http://ipkgfind.handhelds.org> A search engine for Familiar applications in ipkg format.
<http://intimate.handhelds.org> Home of Intimate, a complete Linux distribution for the iPAQ.
<www.handhelds.org/z/wiki/Toolchains> Where to download a GCC cross-compiler and how to build your own.
<www.handhelds.org:8080/wiki/PPPHowto> How to set up a PPP connection from a desktop to the iPAQ and copy files back and forth.
<http://affix.sourceforge.net/ipaq.shtml> A GCC cross-compiler that includes the GTK+ toolkit.
<www.handhelds.org/projects/skiffcluster.html> Instructions for logging on to an iPAQ at Compaq's research center and compiling code with it.
<www.uv-ac.de/ipaqhelp> A how-to for developing Linux software on the iPAQ with an emphasis on the QPE desktop from Trolltech and its free clone, OPIE.
The ARM Processor
<www.arm.com/support/567GCF/$File/DAI0034A_efficient-c.pdf> Tips for writing efficient C on the ARM processor.
<www.intel.com/design/strong/applnots/sa1100lx/sa1100lx.htm> Detailed steps for installing Linux onto any StrongARM-based machine.
<www.arm.com/armtech/StrongARM> An overview of the StrongARM architecture with links to more technical details.
<www.arm.linux.org.uk> Home of Russell King's Linux port for all ARM-based computers.
<www.compaq.com/products/handhelds/pocketpc/> Product information for iPAQ handhelds.
<www.iptel-now.de/HOWTO/PIC/pic.html> Projects ideas that turn the iPAQ into a wearable computer or interface it with PIC microcontrollers.
<www.comp.lancs.ac.uk/~kristof/research/notes/ca_ipaq/index.htmll> An experiment to connect an accelerometer, a light sensor, and other instruments to an iPAQ.
<www.seattlerobotics.org/guide/servos.html> A brief tutorial on servo motors.
<www.linuxdevices.com> News, articles, and discussion about embedded Linux projects.
Download the Code
About the Author
Trevor Harmon lives in Overland Park, Kansas and works as a freelance programmer and author. He can be reached at [email protected].