ARM-USB-TINY-H で Raspberry Pi を JTAG デバッグ

概要

Windows 環境から、JTAG デバッガ Olimex ARM-USB-TINY-H で Raspberry Pi に接続して、JTAG デバッグを行います。

ロスコンパイラはすでにビルドしてあるものとします。 インストール先等のパスは適宜読み替えてください。

環境

Debian Linux

MinGW 向けビルド用に、Debian Linux 環境を用意します。以下のものを入れておきます:

sudo apt-get install mingw-w64 cmake pkg-config

OpenOCD のビルド

OpenOCD は、JTAG デバッガ等を経由でターゲットに接続し、GDB プロトコルデバッグを可能にするプログラムです。

今回は、OpenOCD を MinGW 向けにビルドします。

pkg-config

https://www.flameeyes.eu/autotools-mythbuster/pkgconfig/cross-compiling.html を参考にして、 MinGW-w64 向けに *.pc ファイルのパスを変更した pkg-config を作成します。

sudo cat > /usr/bin/i686-w64-mingw32-pkg-config
sudo chmod 755 /usr/bin/i686-w64-mingw32-pkg-config

i686-w64-mingw32-pkg-config の内容は、以下の通り:

#!/bin/sh

export PKG_CONFIG_DIR=
export PKG_CONFIG_LIBDIR=/usr/i686-w64-mingw32/lib/pkgconfig/
export PKG_CONFIG_SYSROOT_DIR=/

exec pkg-config "$@"

libusb-1.0.9

libusb をビルドします。

tar xjf libusb-1.0.9.tar.bz2
./configure --build=`./config.guess` --host=i686-w64-mingw32 --prefix=/usr/i686-w64-mingw32/
make
sudo make install

libftdi1-1.1

libftdi をビルドします。

cmake -DCMAKE_TOOLCHAIN_FILE=/cmake/Toolchain-i686-w64-mingw32.cmake \
    -DCMAKE_INSTALL_PREFIX="/usr/i686-w64-mingw32" \
    -DPKG_CONFIG_EXECUTABLE=`which i686-w64-mingw32-pkg-config` \
    -DLIBUSB_INCLUDE_DIR=/usr/i686-w64-mingw32/include/libusb-1.0 \
    -DLIBUSB_LIBRARIES=/usr/i686-w64-mingw32/lib/libusb-1.0.a
make
sudo make install

README.mingw には PKG_CONFIG_EXECUTABLE を与えろと書いてあるので指定していますが、実際には参照していないようです。

openocd-0.7.0

OpenOCD をビルドします。 今回、なぜか 0.7.0 をビルドしてしまいましたが、0.8.0 でよいと思います。

sudo cp /usr/i686-w64-mingw32/include/libftdi1/ftdi.h /usr/i686-w64-mingw32/include/
tar xjf openocd-0.7.0.tar.bz2
./configure --build=`./config.guess` --host=i686-w64-mingw32 --prefix=/usr/i686-w64-mingw32/ \
    --enable-ft2232_libftdi
# ここで下記の修正を行う
make
sudo make install

ビルドエラーになるので修正します。openocd-0.7.0/src/jtag/drivers/ft2232.c (138) に以下の記述がありますが、ftdi_chip_type は ftdi.h で既に定義されているので削除しておきます。

    enum ftdi_chip_type { TYPE_2232H = 4, TYPE_4232H = 5, TYPE_232H = 6 };

また、Makefile 中で LIBS=-lftdi -lusb となっている部分を LIBS=-lftdi1 -lusb-1.0 に変更します。 たとえば、以下のようなコマンドを実行すればよいでしょう。

find -name Makefile | xargs sed -b -i "s/\-lftdi \-lusb/\-lftdi1 \-lusb\-1\.0/"

ドライバ

Olimex ARM-USB-TINY-H の公式ドライバは署名されていないため、普通には Windows 7 以降の 64-bit Windows にインストールすることができません。

Zadig を使用して、WinUSB をインストールします。 Olimex OpenOCD JTAG ARM-USB-TINY-H (Interface 0) に WinUSB (v6.1.7600.16385) を Install します。

ARM JTAG 20 コネクタと配線

ARM JTAG 20 のソケットを用意します。

今回は、2.54mm ピッチ 20p ボックスヘッダ のようなものを使用して、以下の信号線を引き出します。※向きを間違えない自信があるならピンヘッダ 2*10 でもよいと思います。

  • GND: 2,4,6,8,10,12,14,16,18,20
  • VTREF: 1
  • nTRST: 3
  • TDI: 5
  • TMS: 7
  • TCK: 9
  • TDO: 13

f:id:asmichi:20140815202522j:plain

アダプティブクロッキングを使用しないので、RTCK は接続しなくてもよいと思います。

SRST を接続しても上手くリセットできなかったのですが、リセットできたとしても後述する GPIO の設定もリセットされてしまいデバッグが継続できないはずなので、SRST を接続しても無意味だと思います。

デバッグ

準備: GPIO ポートの設定

ターゲット起動時に動作させるプログラムで、GPIO の設定を変更しておきます。

GPIO番号 ALT番号 ピン 信号名
GPIO22 ALT4 P1-15 nTRST
GPIO04 ALT5 P1-07 TDI
GPIO27 ALT4 P1-13 TMS
GPIO25 ALT4 P1-22 TCK
GPIO24 ALT4 P1-18 TDO

先ほどのコネクタから引き出した線をこれらのピンに接続します。

VTREF は、3.3V 電源のピンのいずれかに接続します。 http://elinux.org/RPi_Low-level_peripherals#General_Purpose_Input.2FOutput_.28GPIO.29 を参考にします。

接続

OpenOCD で Raspberry Pi に接続します。

まず、OpenOCD の設定ファイルを用意します。

Olimex ARM-USB-TINY-H 用の設定ファイルは、OpenOCD のソースファイル中にあります。 openocd/tcl/interface/olimex-arm-usb-tiny-h.cfg です。

Raspberry Pi 用の設定ファイルは、David Welch さんのリポジトリ のものを使わせてもらいます。armjtag/raspi.cfg です。

以下の通り、OpenOCD を起動します。デフォルトでは、TCP 3333 で GDB プロトコルのサーバが上がります。

openocd.exe -f olimex-arm-usb-tiny-h.cfg -f raspi.cfg

別のターミナルで、GDB を起動します。接続後、一度 continue しておかないと、うまくデバッグできないようです。

arm-unknown-eabi-gdb hoge.elf
> target remote localhost:3333
> continue
^C

これで、デバッグできます。

References