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

January 9, 2013

TI Stellaris Launchpad and Cygwin on Windows

With an exciting title like that, how can it not be enthralling?

Eschewing the use of TI's Code Composer Studio for commandline tools, I am exploring the best workflow on Windows in that vein. To whit, I have the following build environment. Since I am a commandline guy, I opted to use Cygwin[1]. This provides a litany of familiar tools; I made sure to install all of my favorites.While I haven't personally tried it, I would be willing to bet that MinGW/MSYS[2] would work equally well. As I am a complete neophyte to ARM microprocessors and the Stellaris Launchpad, I based almost all of my effort here on the shoulders of others, notably Christian Jann[3] and Recursive Labs Blog[4].

To get things started with the Stellaris, you need to have a compiler, of course. I use a precompiled toolchain provided on the launchpad site by some ARM folks [5]. After extracting it, I added the bin directory to my .bashrc for access to my new arm-no-eabi-* tools, like so:

export PATH=/cygdrive/c/bin/gcc_for_arm:$PATH

I leave it as an exercise for the reader to figure out where I installed my toolchain :)

As an aside, I tried as well the summon-arm-toolchain[6] script. After letting it run for multiple hours (much longer than I experienced on a slower linux box), it seemed to build most tools but bombed on openocd. So my advice is save yourself the trouble and use the pre-compiled binaries.

With a toolchain in place, my next task is to build the TI-provided libraries and example source code, found in the StellarisWare download from TI's site[7]. Launching a cygwin window, I changed into the head directory of the StellarisWare install and issued a simple 'make' command, resulting in built libraries and example code.

With binaries available for flashing, the next step is to see if I can get the bugger uploaded via commandline. I had tried using TI's LMFlash tool[7], but for whatever reason, it was causing me issues. I decided to borrow  the flashing tool lm4flash used by the cool Energia[8] project, particularly lm4flash, found in the energia-*\hardware\tools\lm4f\bin directory. I placed it in the same directory that I installed by ARM toolchain so cygwin would be able to find it easily.

The chip used in the Stellaris Launchpad falls under the LM4F120x1 family. If you installed StellarisWare in its default directory (C:\StellarisWare), then the binaries of interest for the Launchpad can be found in C:\StellarisWare\boards\ek-lm4f120x1 or in cygwin's parlance /cygdrive/c/StellarisWare/boards/ek-lmf4120x1.

I decided to try and load the examples built in StellarisWare. First up was the blinky project. I loaded the blinky.bin file found in the gcc directory (i.e., /cygwin/c/StellarisWare/boards/ek-lm4f102x1/blinky/gcc with the following command

lm4flash -v blinky.bin

Lo and behold, we have blinking lights. Attempting to restore the demo program shipped loaded (found in qs-rgb), it was as simple as changing again into the bin directory of qs-rgq and issuing

lm4flash -v  qs-rgb.bin

Using the comm client PuTTY[9] to connect to the serial interface provided by the qs-rgb program, I was able to interact with it.

Next up is attempting to automate as much as possible for future project work, so I'm going to use a template program/makefile from Mauro Scomparin[10], and then work from within Vim for editing and build control. Note that because we are using Microsoft executables and not cygwin executables for the build tools, directories need to be in the form of MS file formats, e.g.,
#STELLARISWARE_PATH=/cygdrive/c/StellarisWare/ # No good for us!
STELLARISWARE_PATH=c:/StellarisWare/

While I don't have a particular need for it, I will need to figure out debugging.



That's all for now...

[1] - http://cygwin.com
[2] - http://mingw.org
[3] -http://www.jann.cc/2012/12/11/getting_started_with_the_ti_stellaris_launchpad_on_linux.html
[4] - http://recursive-labs.com/blog/2012/10/28/stellaris-launchpad-gnu-linux-getting-started/
[5] - https://launchpad.net/gcc-arm-embedded
[6] - https://github.com/esden/summon-arm-toolchain
[7] -http://www.ti.com/tool/ek-lm4f120xl
[8] - http://energia.nu/
[9] - http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
[10] - https://github.com/scompo/stellaris-launchpad-template-gcc/blob/master/Makefile