retrage.github.io

VisionFive 2をJTAGデバッグ

VisionFive 2 (以下、VF2) はStarFive Technologyが開発したSBCである。名前からわかるように、RISC-VのSoCを搭載している。ここではVF2をJTAGデバッグする方法を簡単にまとめる。

なお、この記事の内容は以下のVF2のフォーラムの投稿を参考に、具体的な手順を整理したものである。

JTAGインターフェースのピン配置

まずピンヘッダ上でのJTAGインターフェースの配置を確認する。以下の通りである。

JTAG:       Header Number
U74_TMS:    35
U74_TCK:    37
U74_TRSTN:  36
U74_TDI:    38
U74_TDO:    40

上記の通り接続すると以下の写真のようになる。

VisionFive 2 JTAG PinOut

今回は手元にあったSipeed RV-Debugger-BL702というRISC-Vベースのデバッガを利用した。

OpenOCDを使ったJTAGデバッグの設定

次にデバッガをPCに接続してOpenOCDを起動する。

OpenOCDの設定ファイルは利用するJTAGデバッガに合わせて用意する必要がある。以下に一例として、RV-Debugger-BL702向けの設定を掲載する。

# REF: https://github.com/orangecms/RV-Debugger-BL702/blob/nezha/tools/openocd/openocd-usb-sipeed.cfg
# REF: https://github.com/strangerover2002/visionfive2-/blob/main/u74.cfg
# SiPEED USB-JTAG/TTL based on FT2232D
adapter driver ftdi
ftdi vid_pid 0x0403 0x6010
# http://blog.sipeed.com/p/727.html
ftdi channel 0
reset_config trst_only
transport select jtag
adapter speed     1000

ftdi layout_init 0x0508 0x0f1b
ftdi layout_signal nTRST -data 0x0200 -noe 0x0100
ftdi layout_signal nSRST -data 0x0800 -noe 0x0400

jtag newtap e24 cpu -irlen 5 -expected-id 0x07110cfd
jtag newtap u74 cpu -irlen 5 -expected-id 0x07110cfd

target create e24.cpu0 riscv -chain-position u74.cpu -coreid 0 -rtos hwthread
target create u74.cpu1 riscv -chain-position u74.cpu -coreid 1 
target create u74.cpu2 riscv -chain-position u74.cpu -coreid 2
target create u74.cpu3 riscv -chain-position u74.cpu -coreid 3
target create u74.cpu4 riscv -chain-position u74.cpu -coreid 4
target smp e24.cpu0 u74.cpu1 u74.cpu2 u74.cpu3 u74.cpu4        #remove for separate harts gdb

init

この設定をファイルに保存した上で、以下のようにOpenOCDを起動する。

openocd -f openocd-usb-sipeed-visionfive2.cfg

OpenOCDが起動してVF2側のJTAGが認識されれば、以下のようにOpenOCDがGDBを待ち受ける。

Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : Hardware thread awareness created
Error: Invalid command argument
Error: Invalid command argument
Error: Invalid command argument
Error: Invalid command argument
Error: Invalid command argument
Warn : libusb_detach_kernel_driver() failed with LIBUSB_ERROR_ACCESS, trying to continue anyway
Info : clock speed 1000 kHz
Info : JTAG tap: e24.cpu tap/device found: 0x07110cfd (mfg: 0x67e (Guangdong StarFive Technology Co), part: 0x7110, ver: 0x0)
Info : JTAG tap: u74.cpu tap/device found: 0x07110cfd (mfg: 0x67e (Guangdong StarFive Technology Co), part: 0x7110, ver: 0x0)
Info : datacount=2 progbufsize=16
Info : Disabling abstract command reads from CSRs.
Info : Examined RISC-V core; found 5 harts
Info :  hart 0: XLEN=64, misa=0x8000000000901107
Info : datacount=2 progbufsize=16
Info : Disabling abstract command reads from CSRs.
Info : Core 1 made part of halt group 1.
Info : Examined RISC-V core; found 5 harts
Info :  hart 1: XLEN=64, misa=0x800000000094112f
Info : datacount=2 progbufsize=16
Info : Disabling abstract command reads from CSRs.
Info : Core 2 made part of halt group 1.
Info : Examined RISC-V core; found 5 harts
Info :  hart 2: XLEN=64, misa=0x800000000094112f
Info : datacount=2 progbufsize=16
Info : Disabling abstract command reads from CSRs.
Info : Core 3 made part of halt group 1.
Info : Examined RISC-V core; found 5 harts
Info :  hart 3: XLEN=64, misa=0x800000000094112f
Info : datacount=2 progbufsize=16
Info : Disabling abstract command reads from CSRs.
Info : Core 4 made part of halt group 1.
Info : Examined RISC-V core; found 5 harts
Info :  hart 4: XLEN=64, misa=0x800000000094112f
Info : starting gdb server for e24.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Info : starting gdb server for u74.cpu1 on 3334
Info : Listening on port 3334 for gdb connections
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections

待ち受けているポートに対してGDBをアタッチすると、以下のようにVF2をGDBでデバッグできるようになる。

(gdb) target extended-remote :3334
Remote debugging using :3334
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
0xffffffff8000329a in ?? ()
(gdb) i r
ra             0xffffffff800322d2	0xffffffff800322d2
sp             0xffffffff81403ed0	0xffffffff81403ed0
gp             0xffffffff815006b8	0xffffffff815006b8
tp             0xffffffff81411fc0	0xffffffff81411fc0
t0             0x1b057	110679
t1             0x8	8
t2             0x1b057	110679
fp             0xffffffff81403ee0	0xffffffff81403ee0
s1             0x0	0
a0             0x0	0
a1             0x200000020	8589934624
a2             0x1	1
a3             0x1b7df	112607
a4             0x1b7df	112607
a5             0xffffffe1f89776e0	-128973310240
a6             0x0	0
a7             0x54494d45	1414090053
s2             0xffffffff815021c0	-2125454912
s3             0xffffffff81502374	-2125454476
s4             0xffffffff80c21778	-2134763656
s5             0xffffffff815020a8	-2125455192
s6             0xffffffff81535218	-2125245928
s7             0x1	1
s8             0x0	0
s9             0x0	0
s10            0x0	0
s11            0xfffb9cd0	4294679760
t3             0x0	0
t4             0x23a	570
t5             0xc5672a10	3311872528
t6             0x2	2
pc             0xffffffff8000329a	0xffffffff8000329a
(gdb) x/8i $pc
=> 0xffffffff8000329a:	csrsi	sstatus,2
   0xffffffff8000329e:	ld	s0,8(sp)
   0xffffffff800032a0:	addi	sp,sp,16
   0xffffffff800032a2:	ret
   0xffffffff800032a4:	addi	sp,sp,-32
   0xffffffff800032a6:	sd	s0,16(sp)
   0xffffffff800032a8:	sd	s1,8(sp)
   0xffffffff800032aa:	sd	ra,24(sp)

JTAGデバッグで気になる点

以上の手順でJTAGデバッグができるが、一点だけ気になることがある。それは、電源投入直後の待ち受け方法についてである。JTAGが使いたくなる場面の多くはUARTも使えない起動初期のタイミングだが、VF2で待ち受けさせる方法がわからない。

この点については、何かわかったことがあれば追記したい。

参考文献