platformio / platform-atmelsam

Atmel SAM: development platform for PlatformIO
https://registry.platformio.org/platforms/platformio/atmelsam
Apache License 2.0
79 stars 105 forks source link

Debugging with J-Link stuck in "Starting target CPU..." #104

Open lauraflu opened 4 years ago

lauraflu commented 4 years ago

Configuration

Operating system: Ubuntu 19.10

PlatformIO Version (platformio --version): 4.3.1

Description of problem

I am trying to debug an Adafruit Metro M0 Express board using a Segger J-Link Edu Mini debugger. Uploading the firmware works fine through the J-Link, but when I start the debugging, whatever I do (step into, step over, continue, etc.) after the first breakpoint, I get the console message Starting target CPU... and the debugging is stuck at this stage. I used Visual Studio Code, but I tried debugging in the console as well without success.

Steps to Reproduce

  1. Create an arduino-blink project.
  2. Start debugging.
  3. After the firmware is uploaded and it displays the current breakpoint, step into the function.

Actual Results

Debug console:

Processing adafruit_metro_m0_dbg (platform: atmelsam; board: adafruit_metro_m0; framework: arduino)
--------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelsam/adafruit_metro_m0.html
PLATFORM: Atmel SAM 4.3.0 > Adafruit Metro M0 Expresss
HARDWARE: SAMD21G18A 48MHz, 32KB RAM, 256KB Flash
DEBUG: Current (jlink) External (atmel-ice, blackmagic, jlink)
PACKAGES: 
 - framework-arduino-samd-adafruit 1.5.10 
 - framework-cmsis 1.40500.0 (4.5.0) 
 - framework-cmsis-atmel 1.2.0 
 - toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 10 compatible libraries
Scanning dependencies...
No dependencies
Building in debug mode
Checking size .pio/build/adafruit_metro_m0_dbg/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   7.4% (used 2416 bytes from 32768 bytes)
Flash: [          ]   4.7% (used 12284 bytes from 262144 bytes)
========================= [SUCCESS] Took 1.58 seconds =========================

Environment            Status    Duration
---------------------  --------  ------------
adafruit_metro_m0      IGNORED
adafruit_metro_m0_dbg  SUCCESS   00:00:01.578
========================= 1 succeeded in 00:00:01.578 =========================
SEGGER J-Link GDB Server V6.52 Command Line Version

JLinkARM.dll V6.52 (DLL compiled Sep 27 2019 17:53:31)

Command line: -singlerun -if SWD -select USB -device ATSAMD21G18 -port 2331
-----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:               on
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:                 ATSAMD21G18
Target interface:              SWD
Target interface speed:        4000kHz
Target endian:                 little

Connecting to J-Link...
J-Link is connected.
Firmware: J-Link EDU Mini V1 compiled Apr 16 2020 17:23:57
Hardware: V1.00
S/N: 801018724
Feature(s): FlashBP, GDB
Checking target voltage...
Target voltage: 3.30 V
Listening on TCP/IP port 2331
Connecting to target...
Connected to target
Waiting for GDB connection...
Reading symbols from /home/laura/Documents/PlatformIO/Projects/200417-145223-arduino-blink/.pio/build/adafruit_metro_m0_dbg/firmware.elf...
done.
PlatformIO Unified Debugger -> http://bit.ly/pio-debug
PlatformIO: debug_tool = jlink
PlatformIO: Initializing remote target...
Connected to 127.0.0.1
Reading all registers
Read 4 bytes @ address 0x000022FC (Data = 0x60632301)
SystemInit () at /home/laura/.platformio/packages/framework-arduino-samd-adafruit/cores/arduino/startup.c:353
353     SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP( 0x6u ) | /* cf table 15.10 of product datasheet in chapter 15.8.6 */
Received monitor command: clrbp
Received monitor command: speed auto
Select auto target interface speed (2000 kHz)
Select auto target interface speed (2000 kHz)
Received monitor command: reset
Resetting target
Received monitor command: halt
Halting target CPU...
...Target halted (PC = 0x00000288)
Resetting target
Loading section .text, size 0x2efc lma 0x2000
Downloading 12028 bytes @ address 0x00002000
Loading section .ramfunc, size 0x5c lma 0x4efc
Downloading 92 bytes @ address 0x00004EFC
Loading section .data, size 0x100 lma 0x4f58
Downloading 256 bytes @ address 0x00004F58
Start address 0x2144, load size 12376
Writing register (PC = 0x    2144)
Transfer rate: 12085 KB/sec, 4125 bytes/write.
Read 4 bytes @ address 0x00002144 (Data = 0x4A12B510)
Reading 64 bytes @ address 0x00002100
Read 2 bytes @ address 0x0000210A (Data = 0x2101)
Breakpoint 1 at 0x210a: file src/Blink.cpp, line 17.
PlatformIO: Initialization completed
Read 2 bytes @ address 0x00002124 (Data = 0x0020)
PlatformIO: Resume the execution to `debug_init_break = break Blink.cpp:17`
PlatformIO: More configuration options -> http://bit.ly/pio-debug
Setting breakpoint @ address 0x0000210A, Size = 2, BPHandle = 0x0001
Setting breakpoint @ address 0x00002124, Size = 2, BPHandle = 0x0002
Starting target CPU...
...Breakpoint reached @ address 0x0000210A
Reading all registers
Removing breakpoint @ address 0x0000210A, Size = 2
Removing breakpoint @ address 0x00002124, Size = 2
Read 4 bytes @ address 0x0000210A (Data = 0x200D2101)

Breakpoint 1, loop () at src/Blink.cpp:18
18    digitalWrite(LED_BUILTIN, HIGH);
Reading 64 bytes @ address 0x20002DC0
Read 4 bytes @ address 0x000022CA (Data = 0xFFE5F7FF)
Setting breakpoint @ address 0x00002124, Size = 2, BPHandle = 0x0003
Performing single step...
...Breakpoint reached @ address 0x0000210C
Reading all registers
Setting breakpoint @ address 0x0000210A, Size = 2, BPHandle = 0x0004
Performing single step...
...Breakpoint reached @ address 0x0000210E
Reading all registers
Performing single step...
...Breakpoint reached @ address 0x00002690
Reading all registers
Read 4 bytes @ address 0x00002690 (Data = 0x0043B570)
Read 4 bytes @ address 0x00002112 (Data = 0x00A424FA)
Reading 64 bytes @ address 0x00002680
Read 2 bytes @ address 0x00002692 (Data = 0x0043)
Setting breakpoint @ address 0x00002692, Size = 2, BPHandle = 0x0005
Starting target CPU...

Expected Results

Expect to step into the function or continue running, depending on the given command. But it simply hangs in this Starting target CPU... state.

The content of platformio.ini:

[platformio]
default_envs = adafruit_metro_m0_dbg

[env:adafruit_metro_m0]
platform = atmelsam
board = adafruit_metro_m0
framework = arduino
upload_protocol = jlink

[env:adafruit_metro_m0_dbg]
platform = atmelsam
board = adafruit_metro_m0
framework = arduino
build_type = debug
debug_tool = jlink
upload_protocol = jlink 
debug_init_break = break Blink.cpp:22

Source file to reproduce issue (the arduino-blink example):

#include <Arduino.h>

void setup()
{
  // initialize LED digital pin as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  // turn the LED on (HIGH is the voltage level)
  digitalWrite(LED_BUILTIN, HIGH);
  // wait for a second
  delay(1000);
  // turn the LED off by making the voltage LOW
  digitalWrite(LED_BUILTIN, LOW);
   // wait for a second
  delay(1000);
}

Additional info

I've just bought the J-Link debug probe and this is the first time I'm using it. I've updated the firmware, but I haven't tried using it with any other board. It works for uploading the firmware to the board, just not for debugging. I'm not sure if it's a problem with the platform or with the PlatformIO core.

Any help is greatly appreciated. Thank you!

lauraflu commented 4 years ago

Update

I also tried using the J-Link GDB Server and I have the same problem, so it seems to be something more fundamental. I used the following settings:

platformio.ini

[platformio]
default_envs = jlink_debug_and_upload

[env:debug_jlink]
platform = atmelsam
framework = arduino
board = adafruit_metro_m0

debug_tool = custom
debug_port = :2331

debug_server =
  /opt/SEGGER/JLink_V670e/JLinkGDBServerCLExe
  -singlerun
  -if
  SWD
  -select
  USB
  -port
  2331
  -device
  GMF03xxx6xx

debug_init_cmds =
  define pio_reset_halt_target
      monitor reset
      monitor halt
  end
  define pio_reset_run_target
      monitor clrbp
      monitor reset
      monitor go
  end
  target extended-remote $DEBUG_PORT
  monitor clrbp
  monitor speed auto
  pio_reset_halt_target
  $LOAD_CMDS
  $INIT_BREAK

[env:jlink_debug_and_upload]
platform = atmelsam
framework = arduino
board = adafruit_metro_m0
extra_scripts = extra_script.py
upload_protocol = custom
debug_tool = jlink
debug_server =
  /opt/SEGGER/JLink_V670e/JLinkGDBServerCLExe
  -singlerun
  -if
  SWD
  -select
  USB
  -port
  2331
  -device
  GMF03xxx6xx

If I do not set a custom breakpoint, it is set to the init() line in the main.cpp file and I am able to step over the lines until it hits the setup() function and then it gets stuck in the Starting target CPU....

main.cpp

#define ARDUINO_MAIN
#include "Arduino.h"

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

// Initialize C library
extern "C" void __libc_init_array(void);

/*
 * \brief Main entry point of Arduino application
 */
int main( void )
{
  init();

  __libc_init_array();

  initVariant();

  delay(1);

#if defined(USE_TINYUSB)
  Adafruit_TinyUSB_Core_init();
#elif defined(USBCON)
  USBDevice.init();
  USBDevice.attach();
#endif

  setup();

  for (;;)
  {
    loop();
    yield(); // yield run usb background task

    if (serialEventRun) serialEventRun();
  }

  return 0;
}

#if defined(USE_TINYUSB)

// run TinyUSB background task when yield()
extern  "C" void yield(void)
{
  tud_task();
  tud_cdc_write_flush();
}

#endif
LaBus3 commented 3 years ago

Hello, was this issue ever fixed? I have somewhat same issue while debugging my custom SAMD21G18AU board. In my situation the debugger works and steps through until initVariant(). If i step over the delay(1) statement the debugger automatically steps into _malloc_r.dbgasm and the XPSR interrupt number is set to 0x03 (Hard Fault??).

OS: Pop!_OS 20.04 LTS x86_64 Debugger: J-link EDU V10.10 IDE: Visual studio Code

[env:zero]
platform = atmelsam
board = zero
framework = arduino
upload_protocol = jlink
debug_tool = jlink

The upload seems to work but I do not see the code executing (uploaded a simple led blink program).

I have verified my board works by other means (uploading and debugging using the visualgdb extension for visual studio works flawlessly)

I have experienced somewhat similar issue while using the internal debugger jlink present in another development board #https://github.com/platformio/platform-nordicnrf52/issues/91#issuecomment-677777818

Regards

lauraflu commented 3 years ago

Hello! I did not get any more help than what you see here. In the end, I managed to debug the board while still compiling with platformio but using gdb (I wrote a guide for posterity here about how to do it). I needed to debug a bigger project which uses platformio, but I didn't care too much about the debugging tool I'm using. Anyway, I'm not sure if the fact that this worked means that the problem is not with platformio itself, but with the Visual Studio interface.

LaBus3 commented 3 years ago

Hello! I did not get any more help than what you see here. In the end, I managed to debug the board while still compiling with platformio but using gdb (I wrote a guide for posterity here about how to do it). I needed to debug a bigger project which uses platformio, but I didn't care too much about the debugging tool I'm using. Anyway, I'm not sure if the fact that this worked means that the problem is not with platformio itself, but with the Visual Studio interface.

I'd like to go with the last statement, just tested uploading and debugging via the Atom IDE and it works. Something really is rotten in Visual studio code. @valeros maybe this is worth looking into?

lauraflu commented 3 years ago

In this case, perhaps it's better to post the issue on platformio-vscode-ide?

pearson commented 3 years ago

I've run into basically the same issue, although with a generic Nordic nRF52832 board. However, it is only Zephyr that has this issue through VS Code -- if I try to debug a sample Arduino or Mbed application with the same board and the same J-Link, the debugger works properly.

@CzzzViewer , do you have information regarding settings for VS Code? You seem to be referring to an Eclipse solution.

pearson commented 3 years ago

In case anyone else runs into this problem, try adding this line to your environment in platformio.ini: debug_build_flags = -O0 -ggdb2 -g2

For me it was the optimization flag -Og (the PlatformIO default) that was the problem. Changing that to -O0 allows debugging to work correctly.

CzzzViewer commented 3 years ago

I've run into basically the same issue, although with a generic Nordic nRF52832 board. However, it is only Zephyr that has this issue through VS Code -- if I try to debug a sample Arduino or Mbed application with the same board and the same J-Link, the debugger works properly.

@CzzzViewer , do you have information regarding settings for VS Code? You seem to be referring to an Eclipse solution.

Oh, Yes, You are totally right. My post was about Eclipse and it was in the wrong place. Sorry for the confusion.