Saturday, September 25, 2010

Rebuilding the kernel

Although everything works so far out-of-the-box, I wanted to go through the exercise of building my own kernel, in case I need to change some of the configs or add any patches. Actually a PWM patch requires a change from the default Ubuntu kernel.

I tried a few ways of rebuilding the kernel, including the "old-fashioned Debian way", and using the automated Ubuntu scripts; however, I ran into various problems using these methods. I wanted to install the kernel on the SD card (not NAND) so that I could test different kernels out, while keeping the known good one in NAND in case the one on SD couldn't boot. The automated scripts would re-image NAND, and the "old-fashioned" way had various build/config issues and it was hard

The easiest way I found to rebuild the kernel is as follows. This keeps the kernel exactly as configured out of the box, allowing you to add your own patches on top.

1) install kernel sources on root filesystem with:
sudo apt-get build-dep --no-install-recommends linux-image-$(uname -r)
apt-get source linux-image-$(uname -r)
apt-get install qt3-dev-tools

2) copy over the old config
cp /boot/config-2.6.33-500-omap .config

3) configure the kernel
make xconfig

4) Build kernel and modules
make bzImage - builds vmlinuz
make modules - builds all the modules
make modules_install - installs modules in /lib/modules/

My kernel was named 2.6.33, so there are modules in /lib/modules/2.6.33

5) create an initramfs (similar to initrd) - I named mine "newinitramfs"
mkinitramfs -o newinitramfs 2.6.33

6) make a uboot compatible version of kernel - I called mine "newimage":
mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n "new kernel" -d arch/arm/boot/zImage newimage

7) make a uboot compatible version of the initrd - I called mine "newinitrd":
mkimage -A arm -O linux -T ramdisk -C none -a 0x0 -e 0x0 -n initrd -d newinitramfs newinitrd

8) copy "newimage" and "newinitrd" to root SD card (mine was mounted in /media/4BD6-F1E1)


9) test loading it from uboot:
mmc init
fatload mmc 0 0x80000000 newkernel
fatload mmc 0 0x81600000 newinitrd
bootm 0x80000000 0x81600000
setenv bootargs console=ttyS2,115200 root=UUID= splash vram=12M omap fb.mode=dvi:1280x720MR-16@60 fixrtc

Note that the old uboot command to boot from the NAND was:
bootcmd=nand read 80000000 280000 400000;nand read 81600000 680000 1000000;bootm 80000000 81600000

10) If everything works, can now overwrite it with the following, to auto-boot from SD instead:

setenv bootcmd "mmc init; fatload mmc 0 0x80000000 newimage; fatload mmc 0 0x81600000 newinitrd; bootm 0x80000000 0x81600000"
saveenv


I now have an Ubuntu 10.04 kernel booting the BeagleBoard from the SD card, and can easily modify the kernel, rebuild, and copy it over to the SD card and reboot. The nice thing is that I can make a copy of the known good SD card, and use another one for development. Alternatively, if anything goes wrong, the bootcmd can be changed back to boot from NAND.

Friday, September 24, 2010

testing the GPIO pins

We'll have to interface to some external devices using the GPIO pins. The expansion header has a couple dozen pins, most of which can be configured as GPIO's. There's also 3 pins that can be configured as PWMs (which can be controlled by hardware timers), and an I2C.

I verified that pin 3 can function as an output (driving either +1.8V high, or 0V low) using the following on the console:

#first, export the pin so the file shows up in /sys/class/gpio
sudo sh -c "echo 139 > /sys/class/gpio/export"

#now make an output
sudo sh -c "echo out > /sys/class/gpio/gpio139/direction"

#now we can toggle the pin high
sudo sh -c "echo high > /sys/class/gpio/gpio139/direction"

#or low
sudo sh -c "echo low > /sys/class/gpio/gpio139/direction"


We can also verify that the pins functions correctly as an input:

#change direction to an input
sudo sh -c "echo in > /sys/class/gpio/gpio139/direction"

#short pin3 to pin1 (1.8V) to verify it's high
cat /sys/class/gpio/gpio139/value
1

#short pin3 to pin 27 (gnd) to verify it's low
cat /sys/class/gpio/gpio139/value
0

Finally, note that the 2 user LED's (USR0 and USR1) are already configured by the default Ubuntu kernel, and can be turned on and off like so:

sudo sh -c "echo 1 > /sys/devices/platform/leds-gpio/leds/beagleboard\:\:usr0/brightness"
sudo sh -c "echo 0 > /sys/devices/platform/leds-gpio/leds/beagleboard\:\:usr0/brightness"

In summary ,this verifies that the kernel gpio module is working and we can properly manipulate the GPIO's. Note this can also be done programatically within a C program using fopen, fread, fwrite, etc.

Wednesday, September 22, 2010

up and running

My BeagleBoard and accessories arrived from LiquidWare within a couple of days. I powered it with a wall-wort phone charger from an Android phone via the mini USB connector, and plugged in a USB hub with USB<->Ethernet and the USB stick, and the DVI cable to a monitor. After trying to install the netbook image, I was seeing CRAMFS errors on the monitor. It turns out the first image I downloaded and dd'd onto the SD card was a bad image - the MD5 sum didn't match.

I re-downloaded the image and verified the MD5 sum. However, now the BeagleBoard boot parameters were set up to boot from NAND, and not the SD card. So, I needed access to the serial port to change this.

I bought a Micro Connectors, Inc. "IDC10" connector from Fry's - a 10-pin female header to a 9-pin DB9F (PLU #257237, F02-203, barcode 1586000620); and a null-modem cable (DB9F <-> DB9F). Unfortunately this didn't work - I saw either nothing or garbage characters out of the BeagleBoard.

It turned out the "IDC10" connector I got was not wired up to the DB9 as expected. Pin 1 of the header went to pin 1 of the DB9; but Pin 2 of the header went to Pin 6 of the DB9! I cut the ribbon cable in half and re-routed the 3 wires (TX, RX, and GND), and was finally able to access the serial port.

This command (found on the Ubuntu wiki) got me booting from the SD card again:
OMAP3 beagleboard.org # mmc init
OMAP3 beagleboard.org # fatload mmc 0 0x82000000 boot.scr
...
OMAP3 beagleboard.org # source 0x82000000

This time, the Ubuntu netbook image booted from the SD card, and installed onto the USB stick out of the box - I now have a BeagleBoard running Samba, sshd, Ubuntu netbook desktop on the DVI monitor, and set up for remote building under NetBeans on my MacBook.

Here's the extra packages I installed:

sudo apt-get install openssh-server
sudo apt-get install samba
sudo apt-get install build-essential
sudo apt-get install libsdl1.2-dev
sudo apt-get install manpages manpages-dev manpages-posix manpages-posix-dev freebsd-manpages

Finally I purged this package, as it was taking a lot of CPU (update-apt-xapi showed 90+% CPU in 'top') and not needed for this type of embedded environment:
sudo aptitude purge apt-xapian-index

Tuesday, September 14, 2010

webcam issues

One problem I ran into today was a strange issue with the webcam. For my project, I need to capture video at 30 fps and perform some image analysis. I'm using the luvcview project as a starting point.

The problem is that I wanted to shut off auto-exposure, and that didn't seem to work with my particular webcam. I'm using WC1200RED webcam, which internally has an Arkmicro Technologies Inc. device (18ec:3299). According to the Linux uvc page this is model number QC3231, although I don't see this model number anywhere (although I since tossed the packaging).

After playing around with the camera for a bit, I stumbled upon a way to disable auto-exposure with the following change:

case A_EXPOSURE_OFF:
control.id =V4L2_CID_EXPOSURE_AUTO;
- control.value =8;
+ control.value =2;
if ((value = ioctl(videoIn->fd, VIDIOC_S_CTRL, &control)) < 0)
printf("Set Auto Exposure off error\n");



I can't find this documented anywhere, but it does seem to work; it's probably worth posting a question on the UVC list at some point.

Monday, September 13, 2010

Set up Development Environment

I'd like to set up a comfortable environment for editing, building, and debugging the apps running on the BeagleBoard, from my MacBook running OS X. I found this excellent post on the subject, describing remote debugging using NetBeans, a great IDE (I prefer it to Eclipse):
http://mechomaniac.com/BeagleboardDevelopmentWithNetbeans

The idea is to run the IDE on your host machine, and mount the BeagleBoard root filesystem via Samba, so you can build, run, and debug the code on the device. This is great, especially if your host machine is OS X, because you don't have to worry about cross compilation, Linux header files, etc.

It skipped a couple of steps, which are described here:


Set up Samba on BeagleBoard
  • Install samba on BeagleBoard with: sudo apt-get install samba
  • create a samba password for any user account with: sudo smbpasswd <username>
  • edit samba config (etc/samba/smb.conf) to map the root filesystem to a samba share:

[Root]
comment = Root
path = /
guest ok = no
browseable = yes
public = yes
writable = yes

Finally, restart samba: "sudo /etc/init.d/smbd restart"


Now you can connect to the samba share via the Finder, or with the NetBeans IDE. To connect via the Finder, launch the Finder; then select "Go -> Connect to Server ..."and enter "smb://<BeagleBoard IP address>" for the Server address.

Preparing the SD Card

While I'm waiting to get the parts, I'm going to prepare an SD card for installing Ubuntu Linux on the BeagleBoard. I'm following the BeagleNetbookInstall instructions found here: https://wiki.ubuntu.com/ARM/Beagle

Step 1

wget http://cdimage.ubuntu.com/ports/releases/lucid/release/ubuntu-10.04-netbook-armel+omap.img

Note the image is 525M

Step 2
I'm doing this from OS X:
  • Insert 2G sdcard
  • diskutil unmount disk1s1
  • dd if=~/ubuntu-10.04-netbook-armel+omap.img of=/dev/disk1
It's that easy! Now we have an sdcard ready to use for booting.

Ordering the Gear

Here's the initial parts list for this project:
  • (1) BeagleBoard C4 from LiquidWare - $149
  • (1) USB Ethernet Adapter from LiquidWare - $33.78
  • (1) Belkin USB 2.0 Plus Hub (7 Port) F5U307-BRN from Amazon - $22.99
  • (1) Kingston DataTraveler I - 8 GB USB 2.0 Flash Drive DTI/8GB from Amazon - $22.79
  • (1) Plugable USB to RS-232 DB9 Serial Adapter (Prolific PL2303HX Chipset) from Amazon - $14.95
  • (1) Cables Unlimited PCM-2296-06 HDMI to DVI D Cable, 6 feet from Amazon - $6.79
  • (1) WC1200RED UVC compliant webcam from Office Depot - $19.99

Welcome

This blog was created to document my adventures with BeagleBoard for my own reference; as well as anyone else who is considering a project using the BeagleBoard, and would like to hear about my experience.

My first project is a factory automation application. I prototyped part of the project with a PC running Linux, and plan to replicate my work on the BeagleBoard. Specifically, I need to:
  1. Interface to a webcam to capture video frames at 30 frames/sec, and perform some analysis on the image;
  2. Interface to an external piece of equipment using the serial port;
  3. Control at least (2) stepper motors;
  4. Possibly interface to 1 or 2 external sensors (TBD).

The BeagleBoard was chosen for this project for: its small size, "hackability" (GPIO's, PWM's, I2C, etc are brought out to headers), relatively low cost, and most importantly, its support for Linux (it looks like Ubuntu should run out of the box).

I'll try to document aspects of this project that might help myself replicate what I've done here for application to other projects; or someone else get started with their own project.

So let's get started!

PS: The title of this post comes from a song by the Boards of Canada.