In preparation for ESC Silicon Valley, I recently got my hands on a BeagleBone -- thanks to Jason Kridner. As you may know, the Bone is a trimmed-down version of the full BeagleBoard. The former retails for about 89$ while the latter goes for around 149$. Both are perfect for tinkering and prototyping.

We had already used the BeagleBoard xM and the then-just-out ULCD for the last ESC Boston but we were looking to reduce the number of moving parts for this ESC. And given The PTR Group's Mike Anderson convincing demo of Android over VNC on an xM last week at ELC (he actually wrote the code that made that possible; thanks Mike), we decided to go with the Bone. So this is a summary of my work on Bone as of now.

One of the first things I ran into was the setup of the Bone's USB connection to my host. The really cool thing about the Bone is that it has both a JTAG and a Serial device integrated. In other words, you don't need to have a USB-to-serial dongle nor any JTAG debugger. It's all on the Bone readily accessible as soon as you plug the Bone onto your host. You must, however, set up the host to use all that. My host is an 11.04 Ubuntu. So I had to do the following:

  1. Modify my /etc/udev/rules.d/51-android.rules to add this:
    SUBSYSTEM=="usb", SYSFS{idVendor}=="18d1", MODE="0666"
    SUBSYSTEM=="usb", SYSFS{idVendor}=="0451", MODE="0666"
    
  2. Add a /etc/udev/rules.d/73-beaglevone.rules:
    ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_interface", \
            ATTRS{idVendor}=="0403", ATTRS{idProduct}=="a6d0", \
            DRIVER=="", RUN+="/sbin/modprobe -b ftdi_sio"
    
    ACTION=="add", SUBSYSTEM=="drivers", \
            ENV{DEVPATH}=="/bus/usb-serial/drivers/ftdi_sio", \
            ATTR{new_id}="0403 a6d0"
    
    ACTION=="add", KERNEL=="ttyUSB*", \
    	ATTRS{interface}=="BeagleBone", \
            ATTRS{bInterfaceNumber}=="00", \
    	SYMLINK+="beaglebone-jtag"
    
    ACTION=="add", KERNEL=="ttyUSB*", \
    	ATTRS{interface}=="BeagleBone", \
            ATTRS{bInterfaceNumber}=="01", \
    	SYMLINK+="beaglebone-serial"
    
  3. Force udev to reread its rules:
    $ sudo udevadm control --reload-rules
    
  4. Set up minicom to use 115200-8N1 without flow control and use the /dev/beaglebone-serial device; TI's documentation says to use hardware flow control but I found that this doesn't work for me -- maybe there's something I'm not doing right.

Here's some of the documentation I used:

I then proceeded to set up VNC to view Android on Bone. There are 2 ways to do this: a) over Ethernet, or b) using port forwarding on top of ADB. I first tried the Ethernet route. On the target I did:

# netcfg eth0 up
# ifconfig eth0 192.168.1.1 255.255.255.0

And on the host:

  • Network icon->Edit Connections->Wired->Add
       Name: BeagleBone
  • IPv4 settings:
       IP: 192.168.1.2
       Mask: 255.255.255.0
       GW: 192.168.1.1
  • Network icon->BeagleBone (i.e. select this as the network connection)

I then shelled into the Bone and started the VNC server:

# androidvncserver &

On the host side, I tried both xvncviewer and vinagre and I have to admit I have a preference for the latter. One of the first things I noticed, and which annoys me, is that as soon as I exit the client connection, the server also exits. So I had to go back and restart the VNC server on the Bone every time I exited the client. The inconvenient thing with a setup where the Bone is directly linked to your development workstation is that it can be tricky to continue having regular network connectivity. Of course you could just plug the Bone to your regular network and have DHCP itself, but that's no always posssible.

These networking issues eventually convinced me to try the ADB port forwarding over USB. To set that up, you can do something like this on your host:

$ adb forward tcp:5901 tcp:5901
$ adb shell
# androidvncserver &

You can then use a VNC client to connect to "localhost:5901". That, though, made me run into a number of issues. First, I found that xvncviewer would very rapidly die. And whatever killed it also killed the ADB connection. So, after it died, a standard "adb devices" on the command line showed no devices connected. Very irritating. It eventually came back up, but it was usually faster to just yank the USB cable out, replug it and restart. I also found that vinagre was much reliable on this setup. Also, vinagre gave me the option to enable JPG over the connection and I highly recommend you do that, it makes for a much smoother interaction. However, still vinagre could also eventually loose its connection to the server. Often, though, it was because the VNC server on the Bone segfaulted; which required shelling into the Bone and restarting it :(

I doing all this, I also discovered that the CPU speed of the Bone isn't the same as the xM; I was initially under the impression that it was, though that might just be my misunderstanding. While the xM runs at 1GHz, the Bone's speed depends on its power source. If you're running on USB, the CPU speed is 500MHz. On 5V DC, it's 720MHz. And that actually shows when using Android over VNC on the board. While Mike's demo on the 1GHz xM was pretty smooth, it's rather sluggish on a 500MHz Bone but quite usable on the DC-powered 720MHz Bone. Also, the other benefit of powering it off 5V DC is that you can deplug/replug the USB without any impact on the OS. In the USB-powered config, unplugging USB removes power to the board ...

The other issue I ran into with VNC, and which I haven't solved quite yet, is that most events need to be followed by a mouse click in order to propagate to the Bone. For example, if I click the Home button on my keyboard it has no effect until I click the mouse. So I have to press the Home key on the keyboard, click the mouse on the screen and then the Bone gets a "HOME" button click. Same with typing text in or clicking the BACK button (i.e. right-click on the mouse.) Maybe this is just operator error and there's something I forgot to set up.

That's it for my experimenting with Android over VNC on the Bone for now. There will certainly be more to come later.