nRF52840 DKで遊ぼう②~GDB Debug~

はじめに

プログラミングする上で一刻も早くデバッグ環境を整えねばなりません。 GDBで、nRF52840 DKのプログラムをデバッグする方法を確立します。

下記Nordic DevZoneの投稿を参考にしました。

devzone.nordicsemi.com

前回記事で行った環境構築が完了していることを前提にしています。

tomo-wait-for-it-yuki.hatenablog.com

手順

大まかな手順は下記の通りです。

  1. J-Linkで開発キットに接続する
  2. GDBサーバを起動する
  3. GDBクライアントからGDBサーバに接続する
  4. プログラムをロードする
  5. デバッグする

J-Linkで開発キットに接続する

ターゲットデバイスがnRF52840なので、connect時のDeviceにNRF52840_XXAAを入力します。

$ JLinkExe
J-Link>connect
Please specify device / core. <Default>: NRF52832_XXAA
Type '?' for selection dialog
Device>NRF52840_XXAA
Device "NRF52840_XXAA" selected.


Connecting to target via SWD
Found SW-DP with ID 0x2BA01477
Found SW-DP with ID 0x2BA01477
Scanning AP map to find all available APs
AP[2]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x24770011)
AP[1]: JTAG-AP (IDR: 0x02880000)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 003BB002 DWT
ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 002BB003 FPB
ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 003BB001 ITM
ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU
ROMTbl[0][5]: E0041000, CID: B105900D, PID: 000BB925 ETM
Cortex-M4 identified.

GDBサーバを起動する

別terminalでJ-LinkのGDBサーバを立ち上げます。 TCPポート2331で接続待ちすることがわかります。

$ JLinkGDBServer -if swd -speed 4000 -device nrf52840_xxaa
SEGGER J-Link GDB Server V6.42f Command Line Version

JLinkARM.dll V6.42f (DLL compiled Feb 26 2019 17:01:29)

Command line: -if swd -speed 4000 -device nrf52840_xxaa
-----GDB Server start settings-----
GDBInit file:                  none
GDB Server Listening port:     2331
SWO raw output listening port: 2332
Terminal I/O port:             2333
Accept remote connection:      yes
Generate logfile:              off
Verify download:               off
Init regs on start:            off
Silent mode:                   off
Single run mode:               off
Target connection timeout:     0 ms
------J-Link related settings------
J-Link Host interface:         USB
J-Link script:                 none
J-Link settings file:          none
------Target related settings------
Target device:                 nrf52840_xxaa
Target interface:              SWD
Target interface speed:        4000kHz
Target endian:                 little

Connecting to J-Link...
J-Link is connected.
Firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Jan  7 2019 14:07:15
Hardware: V1.00
S/N: 683516743
Checking target voltage...
Target voltage: 3.30 V
Listening on TCP/IP port 2331
Connecting to target...Connected to target
Waiting for GDB connection...

GDBクライアントからGDBサーバに接続する

さらに別ターミナルのGDBクライアントから、先ほど起動したJ-Link GDBサーバへ接続します。 GDBクライアントは、環境やターゲットによって異なります。

注記 Nordic SDKのblinkyサンプルをあらかじめビルドしています(nrf52840_xxaa.outがELFファイル)

$ arm-none-eabi-gdb nrf52840_xxaa.out
(gdb) target remote:2331
Remote debugging using localhost:2331
0x000015b0 in ?? ()

GDBサーバがクライアント接続を受け付けました。

Connected to 127.0.0.1
Reading all registers
Read 4 bytes @ address 0x000015B0 (Data = 0xD8FD3803)
Read 2 bytes @ address 0x000015B0 (Data = 0x3803)

プログラムをロードする

クライアント側でloadコマンドを実行します。

(gdb) load
Loading section .text, size 0x6a4 lma 0x1000
Loading section .ARM.exidx, size 0x8 lma 0x16a4
Loading section .data, size 0x6c lma 0x16ac
Start address 0x12b4, load size 1816
Transfer rate: 1773 KB/sec, 605 bytes/write.

無事、ターゲットデバイスに書き込まれたようです。

デバッグする

main関数にブレイクポイントを作って実行します。

(gdb) break main
Breakpoint 1 at 0x12f0: file ../../../main.c, line 62.

(gdb) continue
Continuing.

Breakpoint 1, main () at ../../../main.c:62
62      bsp_board_init(BSP_INIT_LEDS);

無事、main関数で止まりました。もう1度continueを実行すると、LEDが点滅します。