Thursday, 4 July 2013

BeagleBone debugging with OpenOCD

The original BeagleBone (White) comes with a built-in JTAG emulator which allows you to debug your code without needing to go out and buy an expensive JTAG debugger. There's a neat tool called OpenOCD which, among many other things, can be used to debug code on your BeagleBone. I found that the few guides and tutorials available didn't work for me when I was trying to get it going, so I'm posting what I did in hopes that it'll help someone else and save them some time.

I did this on Gentoo Linux using OpenOCD 0.6.1, but similar steps should apply elsewhere. The first step is to install OpenOCD as well as usbutils. You'll need OpenOCD built with usb and ftd2xx support. In Gentoo, there are USE flags for this (USE="usb ftd2xx"). Connect your BeagleBone to your computer via USB, and then run `lsusb` as root. You should find a "Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC" in the list (ID: 0403:6010). If you don't, then the driver isn't installed properly.

The next part is to configure OpenOCD. This is where I ran into problems. There is a default configuration script for the BeagleBone called ti_beaglebone.cfg. You specify it when you run OpenOCD like this `openocd -s /usr/share/openocd/scripts -f board/ti_beaglebone.cfg`. The '-s' is to specify the base of the scripts directory.


Unfortunately, as you can see above, the default script doesn't work out of the box. It prompts you to add a line for your device with this message: "Error: please add "ft2232_device_desc <string>" or "ft2232_serial <string>" to your .cfg file". It wasn't 100% clear how to find out the serial number or device description so I experimented. I found that if you put in a bogus serial number, it will list the available serial numbers. I added the following line to /usr/share/openocd/scripts/board/ti_beaglebone.cfg:
ft2232_serial "XXX"
Then I ran openocd...


From that list I found the serial number "TIWKAE5U A". I edited /usr/share/openocd/scripts/board/ti_beaglebone.cfg again with that serial number and executed `openocd -s /usr/share/openocd/scripts -f board/ti_beaglebone.cfg` again. This time it worked.


Once the OpenOCD server is up, you can connect to it via telnet on port 4444. From there you can issue commands. In the example below I display the value of the I2C revision of the first I2C controller.


Monday, 1 July 2013

Using i2c-tools with Angstrom Linux on the BeagleBone Black

Today I'm going to take a slight detour from my usual Minix posts and post about Linux. I was doing some debugging of my Minix i2c driver and wanted to make sure that my hardware setup was good because I wasn't able to access an EEPROM on the 3rd i2c bus from Minix. I booted into Angstrom Linux to see if the third bus was working at all.

Finding what Linux calls the 3rd i2c bus is a bit of a pain because they are numbered in the order that they are initialized in, and one of the buses is disabled by default. To really know for sure you have to check sysfs. That will give you the memory address of the device on the SoC which you can use to determine the hardware bus number. Here's an example:

root@beaglebone:~# ls -l /sys/bus/i2c/devices/i2c-1
lrwxrwxrwx 1 root root 0 Jan  1 00:00 /sys/bus/i2c/devices/i2c-1 -> ../../../devices/ocp.2/4819c000.i2c/i2c-1


Then I ran i2cdetect from i2c-tools to discover devices on the bus. You need the '-r' option because the am335x doesn't support something called quick writes (0 byte writes). The '-y' option is to acknowledge that you know it could hang or otherwise mess up your i2c bus. Finally, the '1' is the number of the bus according to Linux which we found above. As you can see, my device with slave address 0x50 was detected. The 'UU' means busy. The addresses marked busy were probably reserved by a driver as the cape EEPROMs have address 0x54-0x57.

root@beaglebone:~# i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --   
          
           

Finally, I wanted to look at the data I had previously written. Both to verify that it was there after the chip was powered off and to verify that bus 3 and my circuit were functional. I did this with the i2cdump command. This too needs a '-y' argument to let it know that you know what you're doing. The '1' is the bus number, the 0x50 is the slave address, and the 'c' is the mode (consecutive byte). As you can see, the characters I wrote previously are still there and the i2c bus is functional.

root@beaglebone:~# i2cdump -y 1 0x50 c
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 6d 69 6e 69 78 33 ff ff ff ff ff ff ff ff ff ff    minix3..........
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................


I found it a bit confusing when I first needed to use these tools, so I hope this post helps someone else debug their i2c issues.