Raspberry Piで、ベアメタルなソフト開発をするのに、JTAGデバックできた方が便利なのだが、初期状態ではJTAGの信号がGPIOコネクタに割り当てられていない。
そこで、u-bootの初期化ソースコードを修正して、JTAGピンを有効化し「JTAGデバッガ」を接続できるようにする。
JTAGデバッガ
JTAGデバッガは各社色々あるが、ネットでRaspberry Piで動作報告されてるのは下記のものがある。(他のものも使えると思う)
- Olimex ARM-USB-TINY-H
- Segger J-LINK
ARM-USB-TINY-Hは安価でいいが、私が持ってる環境では動作できなかった。手持ちにあった「J-Link」ではRaspberry Pi 2とZeroでは動作確認できた。Raspberry Pi 3は、Cortex-A53で新しめのCPUなので未対応?なのか私の環境ではまだ動作できてないが、今後試して確認できたら報告していきたい。
※追記(2019/5/8)※
J-Linkも、Raspberry Pi 3のCortex-A53には対応済み(2018 Jun.14)のようです。下記URL。

JTAGデバッガのピン配置
JTAGデバッガのピン配置は「ARM JTAG 20」というARM社より決められており(参考1)、この20ピンコネクタ配列で作られたJTAGデバッガが一般に多い。
ピン番号(奇数番) | 機能(奇数番) | ピン番号(偶数番) | 機能(偶数番) |
---|---|---|---|
1 | VTREF | 2 | VTARGET |
3 | nTRST | 4 | GND |
5 | TDI | 6 | GND |
7 | TMS | 8 | GND |
9 | TCK | 10 | GND |
11 | RTCK | 12 | GND |
13 | TDO | 14 | GND |
15 | nSRST | 16 | GND |
17 | DBGRQ | 18 | GND |
19 | DBGACK | 20 | GND |
Raspberry PiのJTAGピン配置
Raspberry Pi側のJTAGピンは、40ピンコネクタにGPIOと共用となっている。そこでJTAGを利用するには、プログラムでGPIOのモードをAlternativeモードに設定し、JTAGポートとして設定する必要がある。その設定を行うため、対象のピン番号とGPIO、GPIOモードの対応を下記に示す。Alternativeモードの対応についてはBCM2835 ARM Peripheralsの資料(参考3)を参照。
ピン番号 | GPIO番号 | GPIOモード | 機能(JTAG) |
---|---|---|---|
15 | GPIO22 | ALT4 | ARM_TRST |
7 | GPIO4 | ALT5 | ARM_TDI |
13 | GPIO27 | ALT4 | ARM_TMS |
22 | GPIO25 | ALT4 | ARM_TCK |
18 | GPIO24 | ALT4 | ARM_TDO |
Raspberry PiとJTAGデバッガの接続
上記で示した対応表をまとめると、JTAGデバッガとRaspberry Piのコネクタは下記の対応で接続する必要がある。
機能 | ピン番号(Raspberry Pi) | ピン番号(ARM JTAG 20) |
---|---|---|
VTREF | 1 | 1 |
TRST | 15 | 3 |
TDI | 7 | 5 |
TMS | 13 | 7 |
TCK | 22 | 9 |
TDO | 18 | 13 |
GND | 20,25 | 4,6,..,20 |
私は、USB-シリアルのケーブルも接続できるように、下記写真のケーブルを作成した。
u-bootでJTAGピンを有効にする
u-bootソースコードの初期化処理の箇所を修正する。
尚、コンパイル方法については前の記事を参照。

1)/arch/arm/cpu/arm1176/start.S
以下#ifdef〜#endif
の行を追加
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0, cpsr
bic r0, r0, #0x3f
orr r0, r0, #0xd3
msr cpsr, r0
#ifdef CONFIG_BCM2835
/* setup JTAG pin */
ldr r1, =0x20200000 @ GPFSEL0
ldr r0, [r1]
bic r0, r0, #7 << (3*4) @ GPIO 04 clear
orr r0, r0, #2 << (3*4) @ GPIO 04 set ALT5(ARM_TDI)
str r0, [r1]
ldr r1, =0x20200008 @ GPFSEL2
ldr r0, [r1]
bic r0, r0, #7 << (3*2) @ GPIO 22 clear
orr r0, r0, #3 << (3*2) @ GPIO 22 set ALT4(ARM_TRST)
bic r0, r0, #7 << (3*4) @ GPIO 24 clear
orr r0, r0, #3 << (3*4) @ GPIO 24 set ALT4(ARM_TDO)
bic r0, r0, #7 << (3*5) @ GPIO 25 clear
orr r0, r0, #3 << (3*5) @ GPIO 25 set ALT4(ARM_TCK)
bic r0, r0, #7 << (3*7) @ GPIO 27 clear
orr r0, r0, #3 << (3*7) @ GPIO 27 set ALT4(ARM_TMS)
str r0, [r1]
#endif
/*
*************************************************************************
*
2)/arch/arm/cpu/armv7/start.S
以下#if〜#endif
の行を追加
reset:
/* Allow the board to save important registers */
b save_boot_params
save_boot_params_ret:
/*
* disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
* except if in HYP mode already
*/
mrs r0, cpsr
and r1, r0, #0x1f @ mask mode bits
teq r1, #0x1a @ test for HYP mode
bicne r0, r0, #0x1f @ clear all mode bits
orrne r0, r0, #0x13 @ set SVC mode
orr r0, r0, #0xc0 @ disable FIQ and IRQ
msr cpsr,r0
#if defined(CONFIG_BCM2836) || defined(CONFIG_BCM2837_32B)
/* setup JTAG pin */
ldr r1, =0x3F200000 @ GPFSEL0
ldr r0, [r1]
bic r0, r0, #7 << (3*4) @ GPIO 04 clear
orr r0, r0, #2 << (3*4) @ GPIO 04 set ALT5(ARM_TDI)
str r0, [r1]
ldr r1, =0x3F200008 @ GPFSEL2
ldr r0, [r1]
bic r0, r0, #7 << (3*2) @ GPIO 22 clear
orr r0, r0, #3 << (3*2) @ GPIO 22 set ALT4(ARM_TRST)
bic r0, r0, #7 << (3*4) @ GPIO 24 clear
orr r0, r0, #3 << (3*4) @ GPIO 24 set ALT4(ARM_TDO)
bic r0, r0, #7 << (3*5) @ GPIO 25 clear
orr r0, r0, #3 << (3*5) @ GPIO 25 set ALT4(ARM_TCK)
bic r0, r0, #7 << (3*7) @ GPIO 27 clear
orr r0, r0, #3 << (3*7) @ GPIO 27 set ALT4(ARM_TMS)
str r0, [r1]
#endif
/*
* Setup vector:
* (OMAP4 spl TEXT_BASE is not 32 byte aligned.
作成したu-bootを起動してみる
上記で作成したu-boot.bin
をSDカードに書込み(前の記事参照)電源起動してu-bootが起動すると、JTAGデバッガが使える状態になる。
JTAGデバッガから、自作プログラムを転送してのソースデバックなどできる。
u-bootは最初0x8000番地から実行されるが、その後、後ろのアドレスに自分自身を移動して動作する。なので自作プログラムは、0x8000番地〜に配置するように作ればOK。
又、u-bootが移動するアドレス関係を理解しシンボル情報が解決できればu-boot自体のデバックも可能。

コンパイル済u-bootバイナリファイル(2016/8/25追記)
GitHubに公開、後の記事で紹介。

コメント