chakokuのブログ(rev4)

テック・コミック・ごくまれにチャリ

ESP32をデバッグできるようJTAGアダプタを接続してみる->なんとかデバッグ可能になった

ESP32をJTAGデバッグするには、JTAG信号を出力するためのアダプタが必要。手軽にやるならFT2232Hを使うそうなのだが、、大昔に購入したJTAGアダプタ(アルファプロジェクト社のHJ-LINK/USBというやつ)があったのでそれを使ってみる。実はこのボードもFT2232Hで実装されているので、結局は同じことなのであった。

USBケーブルを接続して適当にopenocd.exeを実行すると、libusbでエラーになる。これはFT2232用のドライバを入れ替える必要があるそうだ。

$ ./bin/openocd.exe -f scripts/interface/ftdi/hjlink_usb.cfg
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: 200 kHz
Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED
Error: libusb_open() failed with LIBUSB_ERROR_NOT_FOUND
Error: no device found
Error: unable to open ftdi device with vid 0403, pid 6010, description '*', seri
al '*' at bus location '*'

ZadigというツールでUSB用ドライバを入れ替えるらしい
記事によると、仮想COMポートが2つ出現するらしいのだが、、どうもそうはならない(仮想COMポートは一つだけ)。。なぜだろうか
このままでは動かないので、、Interface0を選択してWinUSBに切り替えるとして、ReinstallDriverをクリック(他の人の実行例と微妙に違うのだが。。)

実行すると、ユニバーサルシリアルバスバイスの下に、USB<->SerialCableというのができている。これでいいのか。。?

JTAGアダプタとはつながったのかが不明。当初出ていた2つのエラーのうち、まだ一つ残っている。

$ ./bin/openocd.exe -f scripts/interface/ftdi/hjlink_usb.cfg
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: 200 kHz
Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED
Info : clock speed 200 kHz
Warn : There are no enabled taps.  AUTO PROBING MIGHT NOT WORK!!
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Warn : Bypassing JTAG setup events due to errors
Warn : gdb services need one or more targets defined

汎用版のOpenOCDのせいか、ターゲットとしてesp32を指定すると、そんなターゲット知らんと怒られる。

$ ./bin/openocd.exe -f scripts/interface/ftdi/hjlink_usb.cfg -f  scripts/board/esp32.cfg
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: 200 kHz
embedded:startup.tcl:21: Error: Unknown target type esp32, try one of arm7tdmi,
arm9tdmi, arm920t, arm720t, arm966e, arm946e, arm926ejs, fa526, feroceon, dragon
ite, xscale, cortex_m, cortex_a, cortex_r4, arm11, ls1_sap, mips_m4k, avr, dsp56
3xx, dsp5680xx, testee, avr32_ap7k, hla_target, nds32_v2, nds32_v3, nds32_v3m, o
r1k, quark_x10xx,  or quark_d20xx
in procedure 'script'
at file "embedded:startup.tcl", line 60
in procedure 'target' called at file "scripts/board/esp32.cfg", line 82
in procedure 'ocd_bouncer'
at file "embedded:startup.tcl", line 21

ESP-IDFをインストールした時に、ESP32に対応したopenocdがインストールされたようで、これを使って、ターゲットとしてesp32を指定してみる。今度はターゲットとしては怒れられない(JTAGインタフェースとの通信でのエラー(LIBUSB_ERROR_NOT_SUPPORTED)は依然出ている)。

$ ./bin/openocd.exe  -f share/openocd/scripts/interface/hjlink_usb.cfg  -f share/openocd/scripts/target/esp32.cfg
Open On-Chip Debugger  v0.10.0-esp32-20190313 (2019-03-13-09:57)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: 200 kHz
Info : Configured 2 cores
esp32 interrupt mask on
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED
Info : clock speed 200 kHz
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: esp32.cpu0: IR capture error; saw 0x1f not 0x01
Warn : Bypassing JTAG setup events due to errors
Info : Listening on port 3333 for gdb connections

JTAG結線図
https://www.visualmicro.com/pics/Debug-Help-ESP32-JTAG-Connections.png

ドライバの問題なのか、JTAGアダプタの問題なのか切り分けできず。。
もう一つFT2232Hのボードを買うか。。(買うとまたヨメに怒られる)

正しく動かない原因としてWindows環境でのドライバのインストールというか設定がうまくってないのでは?と疑い、Linux環境ならどうか?というわけで、RaspberryPiのUSBを使って、JTAGアダプタと繋いでみた。OpenOCDはRaspberryPi上で稼働。すると、libusb_open() failed といったエラーは出なくなった。しかし、、There are no enabled taps. というのがまだ出ている。

# /usr/local/bin/openocd -f ft2232h.cfg
Open On-Chip Debugger 0.10.0+dev-01383-gd46f28c2e-dirty (2020-08-28-21:26)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 200 kHz
Warn : There are no enabled taps.  AUTO PROBING MIGHT NOT WORK!!
Warn : Haven't made progress in mpsse_flush() for 2126ms.
Warn : Haven't made progress in mpsse_flush() for 4166ms.
Warn : Haven't made progress in mpsse_flush() for 8247ms.
Warn : Haven't made progress in mpsse_flush() for 16152ms.
Warn : Haven't made progress in mpsse_flush() for 32217ms.

正しいかどうか不明だが、指定したConfigファイル(ft2232h.cfg)

adapter driver ftdi
ftdi_vid_pid 0x0403 0x6010
adapter speed 200
transport select jtag

ftdi_layout_init 0xfff8 0xfffb
ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
ftdi_layout_signal nSRST -data 0x0200 -oe 0x0200

RaspberryPi上でESP32用にブランチしたOpenOCDをビルドして接続

# /usr/local/bin/openocd -f scripts/board/hjlink_esp32-wrover-kit-3.3v.cfg
Open On-Chip Debugger  v0.10.0-esp32-20200526-14-g18fd8ac8 (2020-08-29-12:32)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Warn : Transport "jtag" was already selected
Info : FreeRTOS creation
Info : FreeRTOS creation
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 200 kHz
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: esp32.cpu0: IR capture error; saw 0x1f not 0x01
Warn : Bypassing JTAG setup events due to errors
Info : Listening on port 3333 for gdb connections

gdbで接続すると以下のようなエラーが出る

Warn : No symbols for FreeRTOS!
Error: Target not examined yet
Error executing event gdb-attach on target esp32.cpu0:

Info : New GDB Connection: 1, Target esp32.cpu0, state: running
Error: Failed to find HALTED core!
Error: Target not examined yet
Error: Failed to find HALTED core!
Error: Failed to find HALTED core!
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: esp32.cpu0: IR capture error; saw 0x1f not 0x01
Warn : Bypassing JTAG setup events due to errors
Info : esp32.cpu0: Debug controller was reset.
Info : esp32.cpu0: Core was reset.
Error: Couldn't halt target before SoC reset

Error: Target not examined yet

いろいろエラーが出ているが、根本的な問題はターゲットを止められないということ。走り続けている。。


最終的に正しく接続するにはは至らなかったが。。設定を記録

# cat  scripts/board/hjlink_esp32-wrover-kit-3.3v.cfg

source [find interface/ftdi/hjlink_usb.cfg]

bindto 0.0.0.0
gdb_memory_map disable

set ESP32_FLASH_VOLTAGE 3.3

source [find target/esp32.cfg]
# cat scripts/interface/ftdi/hjlink_usb.cfg

#
# Amontec JTAGkey
#
# http://www.amontec.com/jtagkey.shtml
#

interface ftdi
#ftdi_device_desc "USB <-> Serial Cable A"
ftdi_vid_pid 0x0403 0x6010
ftdi_channel 0

#ftdi_layout_init 0x0038 0x003b
ftdi_layout_init 0x0008 0x000b
transport select jtag
adapter_khz 200

このアプローチの問題としては、、ボードの配線がどうなっているのか分からないので、FT2232Hの設定ファイルをどう書くのが良いかわからないまま。

アルファプロジェクト社のApplicationNoteを再度確認、ftdiデバイスの設定が書かれている
https://www.apnet.co.jp/support/an/an162.pdf
この資料に従い、interfaceを再設定
file:hjlink_usb.cfg

interface ftdi
#ftdi_device_desc "USB <-> Serial Cable A"
ftdi_vid_pid 0x0403 0x6010
ftdi_channel 0

transport select jtag
adapter_khz 200

ftdi_layout_init 0x0c08 0x0f1b
#ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400
#ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800

上記の、ftdi_layout_init が、ftdiのIOピン設定らしいのだが、、ここが正しくないとCPU HALTとかに失敗するようであった。回路図に従い決めるべき値と思われる(詳細調査未)
上記設定で起動させるとOpenOCDの出力は以下

# /usr/local/bin/openocd -f scripts/board/hjlink_esp32-wrover-kit-3.3v.cfg
Open On-Chip Debugger  v0.10.0-esp32-20200526-14-g18fd8ac8 (2020-08-29-12:32)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Warn : Transport "jtag" was already selected
Info : FreeRTOS creation
Info : FreeRTOS creation
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 200 kHz
Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : esp32.cpu0: Target halted, PC=0x400E30AE, debug_reason=00000000
Info : esp32.cpu1: Target halted, PC=0x400851B7, debug_reason=00000004
Info : Listening on port 3333 for gdb connections

PC上でgdbを起動してラスパイ上のOpenOCDと接続、OpenOCDの出力は以下。gdb側も正しくソース表示がなされる。

Info : accepting 'gdb' connection on tcp/3333
Warn : No symbols for FreeRTOS!
Info : New GDB Connection: 1, Target esp32.cpu0, state: halted
Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : esp32.cpu0: Debug controller was reset.
Info : esp32.cpu0: Core was reset.
Info : esp32.cpu0: Target halted, PC=0x500000CF, debug_reason=00000000
Info : Set GDB target to 'esp32.cpu0'
Info : esp32.cpu0: Core was reset.
Info : esp32.cpu0: Target halted, PC=0x40000400, debug_reason=00000000
Info : esp32.cpu1: Debug controller was reset.
Info : esp32.cpu1: Core was reset.
Info : esp32.cpu1: Target halted, PC=0x40000400, debug_reason=00000000
Info : esp32.cpu0: Target halted, PC=0x400D4480, debug_reason=00000001
Info : Set GDB target to 'esp32.cpu0'
Info : esp32.cpu1: Target halted, PC=0x400E30AE, debug_reason=00000000

これまでうまく行かなった原因((2)は推測)
(1)デバッグ対象バイナリをまずFlashに書き込む必要があるが、行っていなかった。変なプログラムが焼かれた状態でデバッグを開始、変なプログラムはハングしており、gdbでTRAPをキャプチャした
(2)ft2232h用の設定で、ftdi_layout_init 0x0c08 0x0f1b という記述があり、FT2232HのI/Oの設定パラメータと思われる。これはボード上の配線に応じて修正が必要と思われるが(調べてないので推測)、これが正しくなかった。それにより、CPUがHALTできなかった(多分)

起動メモ
Raspberry Pi側(OpenOCDを起動)

# pwd
/usr/local/share/openocd
# /usr/local/bin/openocd -f scripts/board/hjlink_esp32-wrover-kit-3.3v.cfg

WSL Ubuntu側(gdbを起動)

xtensa-esp32-elf-gdb  -x build/gdbinit  build/hello-world.elf

file:gdbinit

target remote 192.168.11.8:3333
symbol-file  build/hello-world.elf
mon reset halt
flushregs
thb app_main
c

OpenOCD 設定マニュアル
OpenOCD User’s Guide: Debug Adapter Configuration

■追記(JTAGアダプタ動いたので不要になったが)
別の手段として、、ラスパイ自体をJTAGアダプタに仕立てる方法もある。
Using a Raspberry Pi as a JTAG Dongle · synthetos/PiOCD Wiki · GitHub