Setting up the Texas Instruments JTAG Development Tool (TI MSP-FET430UIF) for the GNU Debugger on Linux is a non-trivial task. This is mostly due to a closed source user-space driver and program for the JTAG adapter. Additionally, due to a bad implementation of the corresponding Kernel device driver.
Using the following steps the GNU Debugger could be successfully set to be used with with the tmote sky node from Moteiv (with an MSP430 F1611 processor) as a remote target. These steps are known to work on Gentoo Linux (x86 32-bit platform) using the 2.6.22-r5 (based on vanilla 2.6.22.4) kernel. Because of the native software (gdbproxy plus MSP430 library) the JTAG can only be used in a 32-bit x86 environment.
The following guide is mainly based on the article at mikrocontroller.net with a few more detailed instructions and hints.
It is assumed that the msp430-gcc compiler and the MSP430
binutils are already installed. Otherwise, you can build
a working tool chain automatically with the build-mspgcc script,
which can be found in the TinyOS-1.x CVS repository.
Check it out with:
$ cvs -z3 -d:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos \
co -P tinyos-1.x/tools/src/mspgcc
and build it (preferably as root):
# INSTALL_DIR=/usr/local/msp430 ./build-mspgcc install
Also make sure that you have /usr/local/msp430
in your PATH.
Make sure that you have compiled the usb-serial device driver
ti_usb_3410_5250 as a module in your kernel.
Note: This module is not much more than a lump of code.
As noted in the mailing list it is a crutch. However,
using gentoo-sources-2.6.22-r5 on Gentoo Linux I got
it working. So, make sure that you have
CONFIG_USB_SERIAL_TI=m
in your .config file. Recompile your kernel,
the modules, and install them.
# make # make modules # make modules_install
Note: in order to compile gdb-6.0 you cannot use a gcc-4.x compiler. At least for compiling gdb you have to stick to a 3.x version. This is completely against common sense, but unfortunately there does not seem to be any way around.
$ wget http://mirror.switch.ch/ftp/mirror/gnu/gdb/gdb-6.0.tar.bz2 $ tar xfj gdb-6.0.tar.bz2
Get the GNU Debugger and the patches (actually, we are going to just replace the files in the original gdb-6.0 version).
$ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co gdb/gdb-current
You have to use a blank password when you are asked for one. Now, replace the content in the original gdb sources.
$ cp -r gdb/gdb-current/* gdb-6.0/ $ cd gdb-6.0 $ CC=/usr/bin/gcc-3.4.6 ./configure --prefix=/usr/local/msp430 --target=msp430
The CC environment variable can be used to specify
the correct host-gcc for building gdb. This is required if, e.g.,
the default compiler has version 4.x.
$ make
and as root
# make install
The gdbproxy will directly connect the JTAG serial device. The msp430-gdb will connect to the proxy through a socket. First, we need to build the Hardware Interface Library.
$ cvs -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc login $ cvs -z3 -d:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc co jtag $ cd jtag/hardware_access $ make
Copy the shared library into your /usr/lib directory directory.
This is a bit easier than putting it into /usr/local/msp430/lib.
Otherwise the library search path would have to be extended or reconfigured.
However, for purists this is also a bit messier.
# cp libHIL.so /usr/lib # ldconfig
Next, we need the msp430-gdbproxy executable and
the libMSP430.so shared library. Unfortunately,
both are closed source. We have to download the x86 32-bit binaries.
$ wget http://www.soft-switch.org/downloads/mspgcc/msp430-gdbproxy $ wget http://www.soft-switch.org/downloads/mspgcc/libMSP430.so
Make it executable and copy it into the msp430 directory.
$ chmod +x msp430-gdbproxy # cp msp430-gdbproxy /usr/local/msp430/bin # cp libMSP430.so /usr/lib
The gdb is operated on a remote target. The configuration
of this target can be specified in the ~/.gdbinit script
file, which is executed when gdb is started. Important:
this script will also be executed when the native
(host) gdb is started. In this case, if you want to use the host
gdb rename the file to something like ~/.gdbinit_msp430.
The file ~/.gdbinit should contain the following content:
set remoteaddresssize 16 set remotetimeout 999999 set download-write-size 512 target remote localhost:2000 set remote memory-write-packet-size 512 set remote memory-write-packet-size fixed set remote memory-read-packet-size 512 set remote memory-read-packet-size fixed
Compile the following C program:
#include <io.h>
void wait(); /* prototype for wait() */
int main()
{
/* main function, called by startup-code */
P5DIR = 0xFF; /* port 5 = output */
P5OUT = 0x70; /* set bits 4-6 in port 5 */
for(;;) {
/* infinite loop */
P5OUT ^= 0x10; /* invert port 5 bit 4 */
wait(); /* call delay function */
}
}
void wait()
{
/* simple delay function */
volatile int i; /* declare i as volatile int */
for(i = 0; i < 32000; i++)
; /* repeat 32000 times (nop) */
}
When running this program the red led (PORT 5, Pin 4) will blink.
Compile the program for the tmote sky (MSP430 F1611 CPU).
$ msp430-gcc -Os -mmcu=msp430x1611 -g -o blink.elf blink.c
Create the Intel Hex format file out of the ELF file.
$ msp430-objcopy -O ihex blink.elf blink.hex
Attach the tmote sky to the host machine (do not yet attach the JTAG to the mote nor the JTAG to the host machine). Install the program using tos-bsl (from TinyOS), which installs the program through the MSP430 boot loader.
$ tos-bsl --telosb -r -e -I -c /dev/ttyUSB0 -p blink.hex MSP430 Bootstrap Loader Version: 1.39-telos-8 Mass Erase... Transmit default password ... Invoking BSL... Transmit default password ... Current bootstrap loader version: 1.61 (Device ID: f16c) Changing baudrate to 38400 ... Program ... 160 bytes programmed. Reset device ...
The red led of the node should now be blinking.
First, disconnect the tmote sky from the host machine.
Connect the node through the JTAG cable with the MSP-FET
box. Do not attach neither the mote nor the JTAG box
to the host machine.
Load the kernel module using the following parameters:
# modprobe ti_usb_3410_5052 product_3410=0xf430 vendor_3410=0x0451
You can also add debug=1 if you want verbose debugging output
from the USB subsystem. The last lines from dmesg should
indicate that the device driver is loaded:
# dmesg ... drivers/usb/serial/usb-serial.c: USB Serial support registered for TI USB 3410 1 port adapter drivers/usb/serial/usb-serial.c: USB Serial support registered for TI USB 5052 2 port adapter usbcore: registered new interface driver ti_usb_3410_5052 drivers/usb/serial/ti_usb_3410_5052.c: TI USB 3410/5052 Serial Driver v0.9
Now plugin the USB connector of the JTAG box. You probably now see an error with dmesg:
usb 1-2: new full speed USB device using uhci_hcd and address 3 usb 1-2: configuration #1 chosen from 1 choice ti_usb_3410_5052 1-2:1.0: TI USB 3410 1 port adapter converter detected usb 1-2: reset full speed USB device using uhci_hcd and address 3 usb 1-2: device firmware changed ti_usb_3410_5052: probe of 1-2:1.0 failed with error -5 usb 1-2: USB disconnect, address 3 usb 1-2: new full speed USB device using uhci_hcd and address 4 usb 1-2: configuration #1 chosen from 2 choices ti_usb_3410_5052 1-2:1.0: TI USB 3410 1 port adapter converter detected ti_usb_3410_5052: probe of 1-2:1.0 failed with error -5
This is not really a problem. Apparently, this is completely normal! This is due to the way the driver is implemented. You now--still being root--need to massage the device driver through the sysfs:
# echo 2 > /sys/bus/usb/devices/1-2/bConfigurationValue
Change the path to the device accordingly, see the dmesg output on which bus-port the device was detected. Now, the driver initialisation should have resumed
$ dmesg ... ti_usb_3410_5052 1-2:2.0: TI USB 3410 1 port adapter converter detected usb 1-2: TI USB 3410 1 port adapter converter now attached to ttyUSB0
and you now have a device. Test it using the msp430-proxy.
$ msp430-gdbproxy msp430 --selftest-usb-fet /dev/ttyUSB0 Remote proxy for GDB, v0.7.1, Copyright (C) 1999 Quality Quorum Inc. MSP430 adaption Copyright (C) 2002 Chris Liechti and Steve Underwood GDBproxy comes with ABSOLUTELY NO WARRANTY; for details use `--warranty' option. This is Open Source software. You are welcome to redistribute it under certain conditions. Use the '--copying' option for details. notice: msp430: TI USB FET self-test requested debug: MSP430_Initialize() open: No such file or directory error: msp430: Could not initialize device interface (1) debug: MSP430_Initialize() debug: MSP430_Configure() debug: MSP430_VCC(3000) debug: MSP430_Identify() info: msp430: Target device is a 'MSP430F1611' (type 42) debug: MSP430_Configure() notice: msp430-gdbproxy: waiting on TCP port 2000
In case you get an error indicating that the firmware does not match the driver then update it:
$ msp430-gdbproxy msp430 --update-usb-fet /dev/ttyUSB0
This will update the firmware of the JTAG box.
Since you verified that it is working you can actually omit
the --self-test option when invoking the proxy the next time,
but it should not cause any harm. You need to keep the
gdbproxy running and continue on a different shell.
You do not need to connect tmote sky to the host machine (unless you
need the serial port) since the tmote is powered through the JTAG adapter
or the batteries. Launch gdb together with
the elf file generated earlier (note that you generated
it with the -g, i.e., debug-flag).
$ msp430-gdb blink.elf
GNU gdb 6.0
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu
--target=msp430"...0x00004000 in ?? ()
(gdb) list
1 #include <io.h>
2
3 void wait(); /* prototype for wait() */
4
5 int
6 main()
7 { /* main function, called by startup-code */
8 P5DIR = 0xFF; /* port 5 = output */
9 P5OUT = 0x70; /* set bits 4-6 in port 5 */
10
(gdb) list
11 for(;;)
12 { /* infinite loop */
13 P5OUT ^= 0x10; /* invert port 5 bit 4 */
14 wait(); /* call delay function */
15 }
16 }
17
18 void wait()
19 { /* simple delay function */
20 volatile int i; /* declare i as volatile int */
When operating on a remote target you do not start
a program using run. Instead start it with continue
or c. But first set a break point:
(gdb) break 13 Breakpoint 1 at 0x404e: file blink.c, line 13.
Then run it until the first iteration.
(gdb) c Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. main () at blink.c:13 13 P5OUT ^= 0x10; /* invert port 5 bit 4 */
Have a look at the registers.
(gdb) info registers pc/r0: 404e sp/r1: 3900 sr/r2: 0003 r3: 0000 fp/r4: 084e r5: 1528 r6: 012f r7: 351a r8: 850a r9: 3481 r10: 0118 r11: 074a r12: 053a r13: 1100 r14: 1100 r15: 1100
Have a look at the assembly code.
(gdb) disass Dump of assembler code for function main: 0x00004040 <main+0>: mov #14592, r1 ;#0x3900 0x00004044 <main+4>: mov.b #-1, &0x0032 ;r3 As==11 0x00004048 <main+8>: mov.b #112, &0x0031 ;#0x0070 0x0000404e <main+1>: xor.b #16, &0x0031 ;#0x0010 0x00004054 <main+2>: call #16478 ;#0x405e 0x00004058 <main+2>: jmp $-10 ;abs 0x404e 0x0000405a <main+26>: br #0x407c ; End of assembler dump.
Continue until break point is reached in the next iteration.
(gdb) c Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. main () at blink.c:13 13 P5OUT ^= 0x10; /* invert port 5 bit 4 */
Observe, that the red led was turned on this time. Continue until it starts to get boring. That's all!
In step 5 the program was installed through the TinyOS bootstrap loader (BSL). It is also possible to flash through JTAG. This is done in the debugger using the ELF file.
$ msp430-gdb blink.elf GNU gdb 6.0 Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "--host=i686-pc-linux-gnu --target=msp430"...0x00004000 in ?? () (gdb) monitor erase main Erasing target flash - main... Erased OK (gdb) load Loading section .text, size 0x80 lma 0x4000 Loading section .vectors, size 0x20 lma 0xffe0 Start address 0x4000, load size 160 Transfer rate: 1280 bits in <1 sec, 80 bytes/write. (gdb) cont