Abstract

This guide details the steps to setup a Linux cross-compilation and debugging environment. The Texas Instrument’s LM3S1968 evaluation kit is used as the target platform but the instructions should apply to other platforms supported by OpenOCD and GCC.

Note Please send and e-mail if you have any questions, corrections, suggestions.

1. Installation

Initialize $LOCALINSTALLPATH to the directory where all packages will be installed.

Some of the commands are specific to Ubuntu Linux and were tried on version 11.04.

1.1. FTD2232 driver

The FTD2232 chip in the evaluation board acts as the interface between the workstation’s USB controller and the LM3S1968’s JTAG/SWD controller. There are two drivers available:

The libftdi driver is used in this guide. First, libusb must be installed.

sudo apt-get install libusb-dev

After the installation completes the board connectivity can be tested by plugging the board and executing lsusb from the terminal. A message similar to this one should be displayed:

Bus 002 Device 003: ID 0403:bcd9 Future Technology Devices International, Ltd Stellaris Evaluation Board

If the board is detected, download the latest libftdi driver and install it with the following commands.

tar xzvf libftdi-x.x.tar.gz
cd libftdi-x.x
./configure --prefix=$LOCALINSTPATH
make
make install

After installation, the tarball and source directory can be deleted unless ftd2xx is being used. In this case the source directory is needed in a subsequent step.

1.2. OpenOCD

The debug commands are sent to the JTAG controller in the target device with OpenOCD. This software runs as a server to which telnet or gdb clients can connect in order to interact with the target device.

Download the latest openocd and install with the following commands. Note that the configure flags depend on wheter libftdi or ftd2xx were installed, and that one of the flags for ftd2xx points to its source directory. The tarball and source directory can be deleted after the installation.

libftdi
export FTDIFLAGS="--enable-ft2232_libftdi --prefix=$LOCALINSTPATH/bin/openocd"
ftd2xx
export FTDIFLAGS="--enable-ft2232_ftd2xx --with-ftd2xx-linux-tardir=<path to the FTD2XX source directory>
tar xjvf openocd-x.x.x.tar.bz2
cd openocd-x.x.x
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LOCALINSTPATH/lib
LDFLAGS="-L$LOCALINSTPATH/lib" ./configure $FTDIFLAGS --enable-ft2232_libftdi \
--prefix=$LOCALINSTPATH --includedir=$LOCALINSTPATH/include
make
make install
export PATH=$PATH:$LOCALINSTPATH/bin

Now run openocd to verify that it can communicate with the target board. It must be executed with sudo unless udev is configured to allow access to the device file . The full openocd path must be given when using sudo.

sudo $LOCALINSTPATH/bin/openocd -s $LOCALINSTPATH/share/openocd/scripts/ -f board/ek-lm3s1968.cf

A message similar to the one below should be displayed. Press Ctrl+C to close openocd for now.

Open On-Chip Debugger 0.5.0 (2012-02-13-19:20)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.berlios.de/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
500 kHz
Info : clock speed 500 kHz
Info : JTAG tap: lm3s1968.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
Info : lm3s1968.cpu: hardware has 6 breakpoints, 4 watchpoints

A bash script can be created to save some typing. Subsitute $LOCALINSTPATH by the actual path, as this environment variable will be lost when the terminal is closed. Also execute chmod +x on the script to make it executable and move it to some directory within $PATH.

run_openocd
#!/bin/bash
sudo $LOCALINSTPATH/bin/openocd -s $LOCALINSTPATH/share/openocd/scripts/ -f board/ek-lm3s1968.cfg

1.3. The GCC cross-compiler

Compiling a cross-compiler is a complex process but fortunately Crosstool-NG makes it as painless as possible. This tool automatically fetches the GCC source and dependencies, then it builds and installs a cross-compiler according to the configuration entered through a graphical interface.

Download the latest version and install with the following commands.

tar xjvf crosstool-ng-x.x.x.tar.bz2
cd crosstool-ng-x.x.x
./configure --prefix=$LOCALINSTPATH
make
make install

It is most likely that configure will fail because some dependency was not be met. Install the required dependencies with apt-get or with you distribution’s package manager. The packages that had to be installed on this system were expat, bison, flex, gperf, texinfo, curl, libtool, automake, and ncurses-dev but this will vary.

Now on to generate the cross-compiler configuration file. Change to a directory into which the cross-compiler configuration files will be saved. Crosstool-NG will complain if $LD_LIBRARY_PATH is set, so unset it before entering menuconfig.

unset $LD_LIBRARY_PATH
ct-ng menuconfig
ct-ng build

1.3.1. menuconfig

The configuration options vary slightly depending on the target architecture. Here we assume that the target is an ARM Cortex-M3. Since the StellarisWare compilation environment will be used, most options can be left with their default values. Help can be found for each option by highlighting it and typing ?.

  • Paths and misc options

    • ($LOCALINSTPATH/.build) Working directory

  • Target options

    • Target Architecture (arm)

    • [] Use the MMU

    • Floating point: (software)

  • C compiler

    • [*] C++

    • [] Enable GRAPHITE loop optimisations

  • Debug facilities

    • [] gdb

Exit menuconfig and select Yes when prompted to save the new configuration. The configuration will be saved to .config in the current directory. Build messages will be logged in build.log, check the end of this file in case of errors.

After the cross-compiler is installed, update $PATH. To reload the new $PATH when the system is restarted, also type the next line in ~/.bash_profile but replace $LOCALINSTPATH with the actual path as this variable will be lost when the terminal is closed. Other Linux distributions have similar configuration files.

export PATH=$PATH:$LOCALINSTPATH/bin/x-tools/arm-unknown-eabi/bin/

The new cross-compiler and debugger are called arm-unknown-eabi-gcc and arm-unknown-eabi-gdb.

1.4. StellarisWare

Texas Instrument’s StellarisWare consists of drivers, bootloaders, project configuration files, and code examples for the Stellaris family of microcontrollers and evaluation kits. It is recommended to download the complete StellarisWare for all the boards, but this is a +500MB download. An alternative is to download the firmware development kit for your particular MCU. Downloading requires registering a free acount.

It is possible to setup an IDE to use the StellarisWare environment but in this guide we’ll be only using the command line.

Here $SWPATH denotes the directory where the StellarisWare package will be unzipped.

unzip SW-LM3S-x.exe -d $SWPATH
cd $SWPATH

Looking at $SWPATH, there is a driverlib directory which contains the source for the Peripheral Driver Library. This library greatly simplifies using the different modules of the Stellaris MCUs. The boards directory has a subdirectory for each Stellaris board that is provided by Texas Instruments, and within each of these directories are example projects.

Before building a project, the StellarisWare compilation environment has to be configured so that it uses the new cross-compiler. Edit $SWPATH/makedefs and replace arm-none-eabi in the next line by the cross-compiler’s triple, in this case arm-unknown-eabi. Compilation flags can be added to the variables CFLAGS and AFLAGS as needed. When done, save and close the file.

PREFIX=${shell type arm-stellaris-eabi-gcc > /dev/null 2>&1 && \
echo arm-stellaris-eabi || echo arm-none-eabi}

Now compile the Peripheral Driver Library for the Cortex-M3.

cd $SWPATH/driverlib
make -f Makefile.driverlib-cm3

The next step is to compile an example project. Change directory to the target board’s directory, $SWPATH/boards/ek-lm3s1968 in this case. This directory contains project examples and bootloader code for this evaluation kit. We’ll be building the game example so change directory to qs_ek-lm3s1968.

Creating a new project can be easily done by copying and editing the Makefile from one of the project directories. So first lets explore the Makefile. The minimum changes to be done for a new project are changing the ROOT variable to point to $SWPATH. In addition and in the case of this example, all references to qs_ek-lm3s1968 must be changed to the filename of the ARM Exchange Format (.axf) binary to be produced from the compilation. Finally, all object filenames (.o) must be changed to the filenames corresponding to the sources of this project, including drivers compiled as object files and as static libraries (.a).

Now you can return to the example’s directory and enter make to compile the project. A gcc directory will be generated with the object files and the compiled binary. You can enter make clean from the example’s root directory to delete all the compilation output.

2. Flashing the target device

Make sure that the target board has been detected, as explained before.

Start the openocd server. First we’ll be using a telnet client to flash and execute an example binary. In the debugging section a remote gdb session is used to automate this process.

Once openocd is running, open a second terminal and start the telnet session.

telnet localhost 4444

An output similar to the one below should be displayed.

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger

Enter ? to show the help menu. And enter poll to see the device status. Before flashing, the target must be halted. If it isn’t, enter halt.

background polling: on
TAP: lm3s1968.cpu (enabled)
target state: halted
target halted due to undefined, current mode: Thread
xPSR: 00000000 pc: 00000000 msp: 00000000

Now erase the flash and write the binary, expanding $SWPATH by hand.

flash write_image erase $SWPATH/boards/ek-lm3s1968/qs_ek-lm3s1968/gcc/qs_ek-lm3s1968.axf

The flashing may take some time but the output should be similar to the one below.

auto erase enabled
wrote 122880 bytes from file $SWPATH/boards/ek-lm3s1968/qs_ek-lm3s1968/gcc/qs_ek-lm3s1968.axf in 43.597050s (2.752 KiB/s)

Typing reset will begin executing the demo. The client can be closed by typing exit, and the OpenOCD server with Ctrl + C.

3. Debugging

(TBD)

4. To be done

  • Links to the documentation and what to look for

  • Debugging

  • Purpose of the other project files, such as the link and startup files, and how to modify to e.g. update the vector interrupt table

  • Instructions on how to setup the Beagleboard

  • Configuring udev