ARM-USB-TINY-H で Raspberry Pi を JTAG デバッグ
概要
Windows 環境から、JTAG デバッガ Olimex ARM-USB-TINY-H で Raspberry Pi に接続して、JTAG デバッグを行います。
クロスコンパイラはすでにビルドしてあるものとします。 インストール先等のパスは適宜読み替えてください。
環境
- ホスト: Windows 8.1 Pro 64-bit
- ターゲット: Raspberry Pi (Rev.2)
- ビルド用の Debian Linux
- Olimex ARM-USB-TINY-H
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 でもよいと思います。
アダプティブクロッキングを使用しないので、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
これで、デバッグできます。