【Raspberry Pi】u-bootでJTAGピンを有効にする

スポンサーリンク
728×90 ビッグバナー

Raspberry Piで、ベアメタルなソフト開発をするのに、JTAGデバックできた方が便利なのだが、初期状態ではJTAGの信号がGPIOコネクタに割り当てられていない。
そこで、u-bootの初期化ソースコードを修正して、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なので未対応?なのか私の環境ではまだ動作できてないが、今後試して確認できたら報告していきたい。

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 TRST
7 GPIO4 ALT5 TDI
13 GPIO27 ALT5 TMS
22 GPIO25 ALT5 TCK
18 GPIO24 ALT5 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に公開、後の記事で紹介。

参照記事で報告の、Raspbery Pi Zero〜3用のコンパイル済みu-bootのバイナリファイルをGitHubに公開(下記URL) ...

参考

  1. ARM DSTREAM システムおよびインターフェースデザイン リファレンス(p.3-17)
  2. ベアメタルで遊ぶRaspberry Pi
  3. BCM2835 ARM Peripherals
  4. raspberrypi/documentation
  5. KMC Staff Blog:U-Bootのデバッグ
スポンサーリンク
レシポンシブ広告
レシポンシブ広告

シェアする

フォローする