February 1, 2013

Stellaris, Cygwin and OpenOCD for Debugging

So in my previous post, Chris laid down the challenge in the comments to set up debugging within Cygwin [1]. As I don't know anything about it, I figured I'm the perfect fool match to do this task. Chris kindly provided me  a link as a start [2], and from there I proceeded to let google be my friend to supplement that background. This ended up yielding a nice tutorial from Mauro Scomparin [3] via Hack-a-Day[4]. With some timely help from Spencer Oliver [5], OpenOCD developer-extraordinaire, I now have a means of debugging the board under program. So know you know the rabbit trail. So what are the basic steps to get debugging under cygwin?
  1. Make sure you have appropriate tools and libraries installed for Cygwin
  2. Get the latest code base of OpenOCD
  3. Get the windows version of libusb set up in cygwin
  4. Build the sucker
  5. Play gently with the sucker

Step 1. Make sure you have the appropriate tools.
Let the errors be your guide. I wish I could tell you specifically what packages you need, but at this point, what I've installed and what is actually necessary are not easily separated. One thing to note: please make sure the package tcl (under 'Interpretors') is *not* installed; openocd includes an embedded tcl engine called jimtcl, and for whatever reason, it really does not like the cygwin tcl package existing with its nasty DLLs and whatnot. If you're going to use the exact same commands as I have listed below, make sure to install the mingw-gcc development tools as well.


Step 2. Get the latest code base of OpenOCD
It is easiest to do this with git. From your cygwin prompt
$ git clone http://git.code.sf.net/p/openocd/code openocd


Step 3.  Get the windows version of libusb set up in cygwin
We need to get the libusbx library and headers[6] if we're going to cross-compile with the mingw cross-compiler in cygwin.  Add the header and lib files to the compilers. For 32-bit sugary-goodness, create /usr/i686-w64-mingw32/sys-root/mingw/include/libusb-1.0/ and place libusb.h into it (note call it libusb-1.0 not libusbx-1.0. For 64-bit magic, create /usr/x86_64-w64-mingw32/sys-root/mingw/include/libusb-1.0/ .

For the record, I used the static library and not the shared object/DLL version.

Step 4.  Build the sucker

Using Spen's original guidance, I decided to just cross-build it using the 64-bit mingw packages from cygwin.
$ cd openocd
$ ./bootstrap
$ ./configure --enable-maintainer-mode --build=i686-pc-cygwin --host=x86_64-w64-mingw32 --disable-shared --disable-werror --enable-stlink
$ make

If you wanted to build it with 32-bit mingw cross-compilers, then you would use instead
$ cd openocd
$ ./bootstrap
$ ./configure --enable-maintainer-mode --build=i686-pc-cygwin --host=i686-w64-mingw32 --disable-shared --disable-werror --enable-stlink
$ make

Trying to build it natively at this point under cygwin didn't work for me, but I was able to run with the mingw-built binaries, so that's good enough for government work and me.

A quick note here; the --enable-stlink flag, as Spen notes, builds for the ti-icdi as well, as they use the same driver backend.


5. Play gently with the sucker

Pretty easy up to this point. Like Mauro, we're not going to invoke make install, but rather I chose to dump the requisite executables and support files into a separate directory. In my case, that is /home/pimmel/work/stellaris/openocd. Basically copy the contents of the tcl directory and openocd.exe executable to where you want. Following Mauro's guide, we need a configuration file for OpenOCD.
Use the following text and save it as LM4F120XL.cfg in the openocd-bin folder  (again from Mauro):
# TI Stellaris Launchpad ek-lm4f120xl Evaluation Kits
#
# http://www.ti.com/tool/ek-lm4f120xl
#
#
# NOTE: using the bundled ICDI interface is optional!
# This interface is not ftdi based as previous board were
#
source [find interface/ti-icdi.cfg]
set WORKAREASIZE 0x4000
set CHIPNAME lm4f120h5qr
source [find target/stellaris_icdi.cfg]

Now we’re ready to launch it; connect the board to a USB port and just type in the command line:
./openocd.exe --file ./LM4F120XL.cfg

Next connect arm-none-eabi-gdb to OpenOCD and load the program! First start the debugger with something like this:
arm-none-eabi-gdb main.axf

This will open up gdb for arm-none-eabi with a target file called main.axf. Next, at the gdb prompt connect to the OpenOCD interface via the following commands:
target extended-remote :3333
monitor reset halt
load
monitor reset init

Now the target processor is halted at the beginning of the startup_handler() code of the LM4F_startup.c file. At this point, just use the standard gdb commands to set breakpoints and display variables. From Mauro's tutorial here are some examples:
b main.c:51
b Timer1A_ISR
display count
c
A tutorial on gdb is beyond the scope of this little write-up, but it is an intuitive and easy program to use. So now we have another tool in our box to help our development along.
Inconclusion?
So now we have a working open circuit debugging interface, which upon after launching, we can attach a working program and control it via gdb. Pretty cool...now time to dust off my gdb reference material. Much thanks to Spen and Mauro on doing all of the heavy lifting in getting this stuff put together.

[1] - http://underwaterwhistler.blogspot.com/2013/01/getting-started-with-stellaris-launchpad.html
[2] -  http://elinux.org/Compiling_OpenOCD_Win7
[3] - http://scompoprojects.wordpress.com/2012/11/07/debugging-a-program-on-the-stellaris-launchpad-board/
[4] - http://hackaday.com/2012/11/19/how-to-build-openocd-with-stellaris-launchpad-support/
[5] - http://forum.stellarisiti.com/topic/490-openocd-and-cygwin-causing-stackdump/?p=2409
[6] - http://sourceforge.net/projects/libusbx/files/releases/1.0.14/Windows/libusbx-1.0.14-win.7z/download