Olimex ARM-USB-OCD
Don't have a lot of money to spend on an
ABATRON BDI-2000 JTAG
unit (USD $2700)? Why not look into a simpler, cheaper, solution?
While the parallel port wigglers may be one solution, they are not
one that I have found to be very reliable. The USB wiggler appears
to be a more effective solution, although a little more expensive
than a wiggler. I ordered mine
from Sparkfun Electronics
for about USD $70.
The unit comes with an installation CD to install a lot of Windows stuff
(probably under cygwin). Since I abandoned the use of MicroSoft Windows
as a developement platform, the CDROM is pretty much useless for a Linux user.
Heh, seems that these days, everything sold must have some sort of a
Windows CDROM of some kind...
This page describes how I setup OpenOCD and the Olimex ARM-USB-OCD JTAG pod
to work on a Mandriva 2007 Linux system (2.6 kernel).
TopInstall the libftd2xx0 driver
Unfortunately, the OPENOCD website seems to lean heavily towards the Windows
user, but does make references to using thier software with Linux. Curious.
However, After doing some reading from various websites and discussion forums,
I finally divined that I should be using
the libftd2xx0 version 4.13 driver
.
Get the driver for the Linux operating system from the ftdichip website
untar it and follow the README.DAT installation instructions. The version
that I used is 4.13 and did the following under Mandriva 2007, as root:
copied the dynamic lib with cp libftd2xx.so.0.4.13 /usr/local/lib/
created symlink of ln -s /usr/local/lib/libftd2xx.so.0.4.13 /usr/local/lib/libftd2xx.so
created symlink of ln -s /usr/local/lib/libftd2xx.so.0.4.13 /usr/lib/libftd2xx.so
copied ftd2xx.h and WinTypes.h into /usr/include
edited /etc/ld.so.conf and added the line /usr/local/lib
run ldconfig from a console to rebuild the runtime loader database of available libraries
edited /etc/fstab to add a line of none /proc/bus/usb usbfs defaults,devmode=0666 0 0
run mount -a from a console to mount the new USB filesystem
Whenever you boot the system, this USB filesystem and libary will
there to use. You do not need to do these steps again.
TopBuilding OpenOCD
Now that the communications layer to the ftdi232 chip has been installed,
it is now time to build the layer that will reside between that
and gdb (insight). First, we get the OpenOCD source from the svn repository.
As a user, make a directory
mkdir ~/OpenOCD and change to it
cd ~/OpenOCD.
Fetch the source with
svn checkout http://svn.berlios.de/svnroot/repos/openocd/trunk. This will pull in the svn sources for OpenOCD.
go into the downloaded dir: cd trunk
Next, we read the INSTALL textfile, it is good to do this, things may change!
I built OpenOCD, as a user, by following the INSTALL steps of:
./bootstrap to create the configure file.
prepare the source: ./configure --enable-ft2232_ftd2xx
make to build the binary.
as root user, do make install
This installed 'openocd' in the /usr/local/bin directory.
TopCreating the Config File
If you have looked around on this website, you will see that I am using
LPC2000 processors and my own build of ARM binutils, gcc and Insight
debugger. If you have something else, YMMV as to these steps. While
a GUI is nice, at times, I primarily use command line tools. The Insight
debugger is an exception, this is where a GUI is of benefit.
First off, this is important, NEVER ASSUME! When in doubt, RTFM.
In this case, it is 'info openocd'. The method of creating a configuration
file has recently changed with openocd. We have two things that have to be
specified: the inteface (what type of JTAG there is) and the target
(the processor that we are plugged into).
There is no ready-to-use configuration for an LPC2214 using the Olimex
ARM-USB-OCD dongle. We need to build our openocd.cfg file to describe the
interface and target. So, in /usr/local/lib/openocd, there is an interface
directory and a target directory. I will build my config file with
cat /usr/local/lib/openocd/interface/olimex-arm-usb-ocd.cfg
/usr/local/lib/openocd/target/lpc2294.cfg > ~/openocd.cfg as the
lpc2294 is close enough to the lpc2214.
I did have to edit this configuration (openocd.cfg) and add 'jtag_speed 2' to
slow down the jtag clockrate so that it would see the processor. Otherwise it
would come up with an error.
TopA Quick Test
At this point, we should have a working JTAG pod. To see if this is so,
go to the directory where the newly created
openocd.cfg file is
located and run openocd. Without having the JTAG connected to the target
board, you should see something like this printed out:
[tom@laptop ~]$ openocd
Open On-Chip Debugger 1.0 (2008-09-10-22:39) svn:983
$URL: http://svn.berlios.de/svnroot/repos/openocd/trunk/src/openocd.c $
jtag_speed: 2
Error: JTAG communication failure, check connection, JTAG interface, target power etc.
Error: trying to validate configured JTAG chain anyway...
Error: Error validating JTAG scan chain, IR mismatch, scan returned 0x00
Error: Could not validate JTAG chain, continuing anyway...
This is good! OpenOCD sees the pod! Now, connect up an LPC2000 development
board and see if it works with the JTAG on the CPU. Power the development
board, plug the JTAG connector into the board, then re-run openocd (you can stop
openocd with ctrl-C) as before and I get:
[tom@laptop ~]$ openocd
Open On-Chip Debugger 1.0 (2008-09-10-22:39) svn:983
$URL: http://svn.berlios.de/svnroot/repos/openocd/trunk/src/openocd.c $
jtag_speed: 2
Info: JTAG device found: 0x4f1f0f0f (Manufacturer: 0x787, Part: 0xf1f0, Version: 0x4)
Warning:no telnet port specified, using default port 4444
Warning:no gdb port specified, using default port 3333
Warning:no tcl port specified, using default port 6666
Now, telnet into the openocd daemon to see if that works:
'telnet localhost 4444'. You should connect and get:
[tom@jtag trunk]$ telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.
Open On-Chip Debugger
>
At this point here, we have a working connection to JTAG of the target CPU.
You can type 'help' at the command prompt and take a look at some of the
commands OpenOCD offers from the telnet prompt. All those commands do seem
to work as I was able to erase and program the Flash memory of an
LPC2214 board. Ahem, that was
after I went back and carefully edited
my openocd.cfg file and setup the flash statement to match what was in
the LPC2214. If you recall, I just used the lpc2294.cfg file as it was
"close enough" to the LPC2214 processor?
TopTest with Insight Debugger
Using openocd with Insight (gdb) is very straight forward, if you have
used gdb and a remote tcp debug session before. If not, I will walk you
through this. First, build your ARM toolchain (I suggest you use my
toolchain, but other should work fine as well). You should have openocd
still running from the previous test. Launch Insight.
Insight is really gdb with a pretty face, it does make working with a
remote target easier than entering commands into the gdb console
command line. From Insight, choose '
File | Target Settings', set the
Connections to: '
Target: Remote/TCP', '
Hostname: localhost' and
'
Port: 3333'.
Try to connect to the target now with '
Run | Connect to Target' and you
should get a report of 'Successfully Connected'. That is it! You now
have a working JTAG POD over the USB + OpenOCD. What is left now is
to fine tune the contents of the arm7_ft2232.cfg file and to create
a usable target_script.
TopLPC2214 Config
I have an LPC2214 project where there is an external 256K x 16bit SRAM
connected to it. The SRAM is mapped out at 0x81000000. This is the
arm7_ft2232.cfg contents:
telnet_port 4444
gdb_port 3333
interface ft2232
ft2232_device_desc "Olimex OpenOCD JTAG"
ft2232_layout jtagkey
ft2232_vid_pid 0x15ba 0x0003
jtag_speed 2
reset_config trst_and_srst srst_pulls_trst
jtag_device 4 0x1 0xf 0xe
daemon_startup reset
target arm7tdmi little run_and_halt 0 arm7tdmi-s_r4
target_script 0 reset h2214_init.script
run_and_halt_time 0 30
working_area 0 0x40000000 0x40000 nobackup
flash bank lpc2000 0x0 0x40000 0 0 lpc2000_v1 0 14765 calc_checksum
flash bank cfi 0x80000000 0x400000 2 2 0
TopInit script for LPC2214
The target_script referred to in the arm7_ft2232.cfg:
arm7_9 write_xpsr 0x000000d3 0
mww 0xE01FC040 0x00000001 #MEMMAP: User flash mode
mww 0xE01FC080 0x00000000 #PLLCON:
mww 0xE01FC084 0x00000000 #PLLCFG:
mww 0xE01FC08C 0x000000AA #PLLFEED:
mww 0xE01FC08C 0x00000055 #PLLFEED:
sleep 10
mww 0xE002C014 0x0D002914 #config P2 pins for 256Kx16 EXRAM.
mww 0xFFE00004 0x1000040F #config CS1 select at 0x81000000.
sleep 10
#arm7_9 force_hw_bkpts enable # program resides in Flash
arm7_9 force_hw_bkpts disable # program resides in RAM
TopComments about ARM-USB-OCD
As with anything, you get what you pay for. The ARM-USB-OCD and OpenOCD do a
credible job to replace the ABATRON BDI2000 (I have one of these) but does
not perform as well. You can program / erase the flash memory from the
telnet session, and you can download code into the target RAM.
You can also run breakpoints, and single step, examine registers, etc..
However, you cannot do these things as quickly as with the BDI2000.
For example, to download a 40K program into RAM with the OpenOCD + USB
takes about 6 seconds, with the BDI2000 it takes about a second. Single
stepping assembler code with the OpenOCD + USB is slow, each step takes about 2
seconds. Single stepping the same code with the BDI2000 is very rapid with
no noticable delay.
It does depend on your expectations. For the price, the ARM-USB-OCD + OpenOCD
combination would be great for that occasional "thing", or for Production people
to use to bang hardware. I would not use them everyday to do serious
code development as I tend to be an impatient chap who dislikes waiting for
things to happen. ;-)