-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Econotag Debugging with OpenOCD
The Econotag connects to USB through a dual-channel FTDI chip, the first channel giving access to the mc1322x JTAG interface. OpenOCD, the Open On-Chip Debugger has support for this interface and so can be used to control the mc1322x processor. The commands to OpenOCD can come through a telnet connection for simple tasks like downloading firmware, start, stop, and single step, or from high level debuggers like GDB or Emacs to debug from source code with memory watches, CPU breakpoints, etc.
These directions are for Windows 7/64 bit using cygwin. You will need git and the usual automake tools (the Econotag is a recent addition). Error messages during the configure stage will tell you is anything is missing.
OpenOCD can be built using libftdi/libusb or the ftdi usb drivers. On Windows the ftdi drivers are faster. Since they are proprietary they are not included in the OpenOCD repository, but rather obtained from ftdichip.com directly. Another advantage of using these drivers is that the FT_Prog Utility can be used to examine and customize the attached ftdi chips.
$cd ~ $git clone git://openocd.git.sourceforge.net/gitroot/openocd/openocd #Get ftdi Windows drivers from e.g. http://www.ftdichip.com/Drivers/CDM/CDM20814_WHQL_Certified.zip #Unzip into a folder in your home directory, call it "afolder" #Install these drivers if you have not already! The device manager should show the econotag as two COM ports; which ones will depend on which USB port you plug it into. $cd openocd $./bootstrap $./configure --enable-maintainer-mode --disable-werror --disable-shared --enable-ft2232_ftd2xx --with-ftd2xx-win32-zipdir=../afolder $make $make install
If all goes well you should be able to connect the econotag and OpenOCD will find it on startup. Change to a directory that contains a .bin file for the econotag and run:
$openocd -f board/redbee-econotag.cfg Open On-Chip Debugger 0.5.0-dev-00950-g898dd3a-dirty (2011-07-13-11:38) Licensed under GNU GPL v2 For bug reports, read http://openocd.berlios.de/doc/doxygen/bugs.html Info : only one transport option; autoselect 'jtag' srst_only separate srst_gates_jtag srst_open_drain jtag_ntrst_delay: 200 2000 kHz Info : device: 6 "2232H" Info : deviceID: 67330064 Info : SerialNumber: A Info : Description: Dual RS232-HS A Info : max TCK change to: 30000 kHz Info : clock speed 2000 kHz Info : JTAG tap: mc13224v.cpu tap/device found: 0x1f1f001d (mfg: 0x00e, part: 0xf1f0, ver: 0x1) Info : Embedded ICE version 7 Error: EmbeddedICE v7 handling might be broken Info : mc13224v.cpu: hardware has 2 breakpoint/watchpoint units ...
If that does not work you probably need to edit cygwin/usr/local/share/openocd/scripts/board/redbee-econotag.cfg to make it look like this:
source [find target/mc13224v.cfg] # The redbee-econotag has an onboard ft2232h with channel A wired # to the JTAG pins on the mc13224v # channel B is wired to UART1 # The ftdi.com drivers refer to these as "Dual RS232-HS A" and "Dual RS232-HS B" ft2232_layout redbee-econotag ft2232_vid_pid 0x0403 0x6010 ft2232_device_desc "Dual RS232-HS A"
Now would be a good time to make several copies of this file, naming them redbee-econotag1.cfg, redbee-econotag2.cfg, ... and changing the port by adding to the end of each
telnet_port 44441 gdb_port 33331 tcl_port 0
telnet_port 44442 gdb_port 33332 tcl_port 0
...
This will allow running several instances to connect to multiple econotags. Each instance will find the next econotag not already connected to openocd [the]. In different command windows you can then do
$openocd -f board/redbee-econotag1.cfg
$openocd -f board/redbee-econotag2.cfg
...
until the one you want is connected.
Once you get a successful connect, open another cmd window and telnet to it [install]telnet in cygwin or enable in windows using Control Panel->Programs and Features->Turn Windows features on and off->Telnet Client). See http://mc1322x.devl.org/openocd.html for more information. If you have .bin file you can now download it:
>telnet localhost 4444 (or 44441, 44442, ...) Open On-Chip Debugger > soft_reset_halt requesting target halt and executing a soft reset target state: halted target halted in ARM state due to breakpoint, current mode: Supervisor cpsr: 0x200000d3 pc: 0x00000000 > load_image border-router_redbee-econotag.bin 0x00400000 58448 bytes written at address 0x00400000 downloaded 58448 bytes in 2.129000s (26.810 KiB/s) > resume 0x00400000
You are ready to debug; if the Econotag hangs find the CPU address, and step a few times to see if it is in a tight loop. Compare the address to the .map or full listing to identify the subroutine it is in [get][the].
> halt target state: halted target halted in Thumb state due to debug-request, current mode: System cpsr: 0x4000003f pc: 0x004017f6 > step target state: halted target halted in Thumb state due to single-step, current mode: System cpsr: 0x4000003f pc: 0x004017ca ...
There is no need to load an image; you can connect to an econotag that is already running and/or hung to see what the cpu is doing. Bypass the soft_reset_halt in that case, and just give the halt/step/resume commands. That allows loading and running a contiki binary in the normal way and leaving mc1322x-load.pl connected for debug prints (or control-c out and running the slip border router). Since mc1322x-load.pl uses the B port, it does not conflict with the use of the A port by OpeOCD.
For completeness we will go on with the border-router example. Up to this point we have not needed to know the COM port number; now we want to connect to the mc1322x serial port on Dual RS232-HS B. Use the device manager to see which COM ports it uses; Let's say COM6 and COM7. Then cygwin can refer to either /dev/com7 or /dev/ttyS6 (tty ports start from 0). Connect to the rpl border router using wpcapslip6:
#In another window (DOS or cygwin) C:\Windows\System32>ping -n 100 -l 1200 bbbb::250:c2ff:fea8:cd1a Pinging bbbb::250:c2ff:fea8:cd1a with 1200 bytes of data: Reply from bbbb::250:c2ff:fea8:cd1a: time=139ms Reply from bbbb::250:c2ff:fea8:cd1a: time=64ms Reply from bbbb::250:c2ff:fea8:cd1a: time=77ms Direct browser to http://[bbbb::250:c2ff:fea8:cd1a]
See http://openocd.berlios.de/doc/html/GDB-and-OpenOCD.html and http://mc1322x.devl.org/openocd.html for some mc1322x specifics.
GDB is well documented on the internet, see for example http://www.gnu.org/software/gdb/documentation/, http://openocd.berlios.de/doc/html/GDB-and-OpenOCD.html, and http://mc1322x.devl.org/openocd.html for some mc13224x specifics such as the macros to add to ~/.gdbinit:
define conn target remote localhost:3333 end
You need a GDB that can disassemble the ARM .elf files, such as the one that is included in the CodeSourcery install. It connects to OpenOCD using port 3333. Let this port through the firewall! You also need an .elf file that contains the debugging information, such as the border-router.elf file built with $make TARGET=redbee-econotag border-router. Run OpenOCD as above to connect to the econotag(s). Then:
$cd ~/contiki/examples/ipv6/rpl-border-router/ $make TARGET=redbee-ecquitonotag border-router.elf $ arm-none-eabi-gdb border-router.elf GNU gdb (Sourcery G++ Lite 2008q3-66) 6.8.50.20080821-cvs Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=i686-mingw32 --target=arm-none-eabi". For bug reporting instructions, please see: <https://support.codesourcery.com/GNUToolchain/>. (gdb) shell ls Makefile border-router.txt border-router.elf border-router.minimal-net (gdb) target remote localhost:3333 (or 33331, 33332, ...) (gdb) go ... (gdb) quit
Emacs can be run under cygwin or installed as a Windows application. We will assume the native application http://ftp.gnu.org/pub/gnu/emacs/windows/emacs-23.3-bin-i386.zip. Probably you will want to select the windows cut and past shortcuts C-x, C-c, C-v in the options menu!
GDB uses the HOME environmental variable to locate the .gdbinit script which is defined under cygwin but not usually in Windows. To add it, right click on Start Menu->Computer, select Properties, Advanced System Settings, Environmental Variables, New, and add HOME pointing to your cygwin home directory (e.g. C:\cygwin\home\yourhome). Typing set HOME in a CMD window should now show the line HOME=C:\cygwin\home\yourhome. Verify that .gdbinit is there:
C:\Users\dak>ls %HOME%/.gd* C:\cygwin\home\dak/.gdbinit
Note: Adding HOME may break applications that used a fallback directory when HOME was not not defined, e.g. GIT may now look for certificates in %HOME%/.ssh instead of C:/Users/yourname/.ssh. You can just copy that folder to the new HOME directory.
Launch Emacs and open a .c file in the directory containing the .elf file you want to debug. Bring up the ARM gdb and pass it the filename:
Type M-x gdb ("Modifier-x", which is alt-x on most keyboards): M-x gdb Run gdb (like this):gdb --annotate=3 Edit that to be arm-none-eabi-gdb --annotate=3 border-router.elf
Select Gud->GDB-UI->Display Other Windows from the menu to bring up the full debugging panel. Now in the gdb pane you can type conn and go.
(gdb) conn 0x0001d6c8 in ?? () (gdb) go requesting target halt and executing a soft reset target state: halted target halted in ARM state due to breakpoint, current mode: Supervisor cpsr: 0x000000d3 pc: 0x00000000 Loading section .text, size 0xd660 lma 0x400000 Loading section .rodata, size 0xc9c lma 0x40d660 Loading section .ARM.exidx, size 0x10 lma 0x40e2fc Loading section .data, size 0x140 lma 0x40e30c Start address 0x400000, load size 58444 Transfer rate: 19 KB/sec, 8349 bytes/write. pc (/32): 0x00400000 (gdb)c Continuing.
Control-C twice to break:
C-c C-c Program received signal SIGINT, Interrupt. 0x0040aa7a in check_maca () at ../../../cpu/mc1322x/lib/maca.c:137 Current language: auto; currently c (gdb)
and the .elf pane will show the source, with an arrow at the current program counter:
-> if(*MACA_CLK == last_time) { PRINTF("check maca: maca_clk stopped, restarting\n"); /* clock isn't running */ ResumeMACASync();s
n
will single step, n 10 steps 10 times, etc.
If you want to simultaneously debug two econotags on the same machine (e.g. a border router and webserver) you can run two instances of OpenOCD, if you specify different ports for telnet and gdb. One way to do that is to make a copy of redbee-econotag.cfg called redbee-econotag2.cfg and add this to the start:
#daemon configuration telnet_port 44442 gdb_port 33332 tcl_port 0
Then run the second instance with OpenOCD -f redbee-econotag2.cfg and use those port numbers in telnet or gdb. This works because the second instance continues to scan the USB chain after it fails to attach the first econotag. Here is what it looks like on a laptop: