-
Notifications
You must be signed in to change notification settings - Fork 256
Description
I have got a NRF52840-dk devkit and got the ITM tracing to work using JLinkGDBServer.
I tried to get it working using OpenOCD but yet to no avail.
I'm on arch linux with the latest of everything
JLinkGDBServer
SEGGER J-Link GDB Server V6.54c Command Line Version
JLinkARM.dll V6.54c (DLL compiled Nov 7 2019 17:05:41)
OpenOCD
Open On-Chip Debugger 0.10.0+dev-00957-g9de7d9c81 (2019-11-13-15:32)
vscode 1.40
Cortex-Debug (3.4), This it what it lists in vscode, but the repo seems to have 2.7 as the latest release, how is that????
I'd like to understand exactly what is going on, why it works with JLink but not OpenOCD, and also how i can pipe the ITM to a file (I saw that one can have "external" servers now, but unsure how to set that up correctly, so that might be an option once I figure out what happens here).
My launch
{
"type": "cortex-debug",
"request": "launch",
"servertype": "jlink",
"name": "usbd (debug) jlink",
"preLaunchTask": "cargo build",
"executable": "($cwd)../../target/thumbv7em-none-eabi/debug/nrf52840-usb",
"device": "nrf52",
"interface": "swd",
"postLaunchCommands": [
"monitor semihosting enable",
"monitor semihosting ioclient 3"
],
"cwd": "${workspaceRoot}",
"swoConfig": {
"source": "probe",
"enabled": true,
"swoFrequency": 6000000,
"cpuFrequency": 64000000,
"decoders": [
{
"port": 0,
"label": "Output",
"type": "console",
}
]
}
},
}
I get the desired output in the SWO: Output window.
In the Adapter output I get.
SEGGER J-Link GDB Server V6.54c Command Line Version
JLinkARM.dll V6.54c (DLL compiled Nov 7 2019 17:05:41)
Command line: -if swd -port 50000 -swoport 50001 -telnetport 50002 -device nrf52
-----GDB Server start settings-----
GDBInit file: none
GDB Server Listening port: 50000
SWO raw output listening port: 50001
Terminal I/O port: 50002
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: nrf52
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: 683134511
Checking target voltage...
Target voltage: 3.30 V
Listening on TCP/IP port 50000
Connecting to target...Connected to target
Waiting for GDB connection...Connected to 127.0.0.1
Reading all registers
Read 4 bytes @ address 0x0000A9EC (Data = 0x4770BEAB)
Read 2 bytes @ address 0x0000A9EC (Data = 0xBEAB)
Received monitor command: halt
Halting target CPU...
...Target halted (PC = 0x0000A9EC)
Received monitor command: reset
Resetting target
Downloading 256 bytes @ address 0x00000000
Downloading 16256 bytes @ address 0x00000100
Downloading 16176 bytes @ address 0x00004080
Downloading 16208 bytes @ address 0x00007FB0
Downloading 6584 bytes @ address 0x0000BF00
Downloading 16336 bytes @ address 0x0000D8C0
Downloading 6340 bytes @ address 0x00011890
Downloading 216 bytes @ address 0x00013154
Writing register (PC = 0x d83e)
Received monitor command: reset
Resetting target
Received monitor command: semihosting enable
Semi-hosting enabled (Handle on BKPT)
Received monitor command: semihosting ioclient 3
Semihosting I/O set to TELNET and GDB Client
Received monitor command: SWO EnableTarget 64000000 6000000 0x1 0
SWO enabled successfully.
Read 4 bytes @ address 0xE0000E00 (Data = 0x00000001)
Read 4 bytes @ address 0x0000D83E (Data = 0xF82FF000)
Downloading 4 bytes @ address 0xE0000E00
Reading all registers
Read 4 bytes @ address 0x0000D83E (Data = 0xF82FF000)
Read 4 bytes @ address 0xE0000E00 (Data = 0x00000000)
Downloading 4 bytes @ address 0xE0000E00
Reading all registers
Read 4 bytes @ address 0x0000D83E (Data = 0xF82FF000)
Read 4 bytes @ address 0xE0001000 (Data = 0x40000BFF)
Downloading 4 bytes @ address 0xE0001000
Reading all registers
Read 4 bytes @ address 0x0000D83E (Data = 0xF82FF000)
Read 4 bytes @ address 0xE0000E80 (Data = 0x0001000D)
Downloading 4 bytes @ address 0xE0000E80
Reading all registers
Read 4 bytes @ address 0x0000D83E (Data = 0xF82FF000)
Read 4 bytes @ address 0xE0001000 (Data = 0x40000BFF)
Downloading 4 bytes @ address 0xE0001000
Reading all registers
Read 4 bytes @ address 0x0000D83E (Data = 0xF82FF000)
Reading register (MSP = 0x20040000)
Reading register (PSP = 0x 0)
Reading register (PRIMASK = 0x 0)
Reading register (BASEPRI = 0x 0)
....
So here is my wild guessing, please correct me where I'm wrong.
Received monitor command: SWO EnableTarget 64000000 6000000 0x1 0
SWO enabled successfully.
Read 4 bytes @ address 0xE0000E00 (Data = 0x00000001)
Read 4 bytes @ address 0x0000D83E (Data = 0xF82FF000)
Downloading 4 bytes @ address 0xE0000E00
Here we first see that Cortex Debug sends an EnableTarget command (or rather that JLINK successfully received it).
But what happens next? Is it that Cortex Debug actively runs some internal script for setting up the NRF ITM tracing, or? The 0xE0000E00 is ITM_TER (one of the ITM registers). Then for some reason the content of the PC where the MCU was halted is read as well.
Then it seems that Cortex Debugs writes a word to 0xE0000E00 (likely a zero).
then it reads Read 4 bytes @ address 0xE0000E00 (Data = 0x00000000)
, to confirm that the write was successful (perhaps, guessing here).
... and so forth.
So my question here is, where is this "script", and who is running it (is it Cortex Debug that invokes its own script, or is it a "high level command" sent by Cortex Debug to do this magic)?
I need to know since I want to run ITM tracing in a background process (either using JLink, OpenOCD, or PyOCD), so that I can rout that to an external viewer, and also NOT need to restart the gdb server on each debug run, unless there is some way of pinning adapter output/SWO output to different windows, but that seems like a long shot....
I assume what the Data exchange amounts to in the end is programming the ITM HW on the NRF52 to the correct clock divider, etc.
Attempting to replicate the behavior from terminal(s).
.gdbinit
target remote :50000
set print asm-demangle on
monitor semihosting enable
monitor semihosting ioclient 3
mon SWO GetSpeedInfo
mon SWO EnableTarget 64000000 6000000 1 0
load
cont
When I try running JLinkGDBServer with the same invocation parameters as listed in the output log:
I get the following output:
> JLinkGDBServer -if swd -port 50000 -swoport 50001 -telnetport 50002 -device nrf52
SEGGER J-Link GDB Server V6.54c Command Line Version
JLinkARM.dll V6.54c (DLL compiled Nov 7 2019 17:05:41)
Command line: -if swd -port 50000 -swoport 50001 -telnetport 50002 -device nrf52
-----GDB Server start settings-----
GDBInit file: none
GDB Server Listening port: 50000
SWO raw output listening port: 50001
Terminal I/O port: 50002
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: nrf52
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: 683134511
Checking target voltage...
Target voltage: 3.30 V
Listening on TCP/IP port 50000
Connecting to target...Connected to target
Waiting for GDB connection...Connected to 127.0.0.1
Reading all registers
Read 4 bytes @ address 0x00003D3A (Data = 0xB086E7FE)
Read 4 bytes @ address 0x00000002 (Data = 0xD83F2004)
Received monitor command: semihosting enable
Semi-hosting enabled (Handle on BKPT)
Received monitor command: semihosting ioclient 3
Semihosting I/O set to TELNET and GDB Client
Received monitor command: SWO GetSpeedInfo
Base frequency: 12000000Hz, MinDiv: 1
Received monitor command: SWO EnableTarget 64000000 6000000 1 0
SWO enabled successfully.
Downloading 256 bytes @ address 0x00000000
Downloading 16256 bytes @ address 0x00000100
Downloading 16176 bytes @ address 0x00004080
Downloading 16208 bytes @ address 0x00007FB0
Downloading 6584 bytes @ address 0x0000BF00
Downloading 16336 bytes @ address 0x0000D8C0
Downloading 6340 bytes @ address 0x00011890
Downloading 216 bytes @ address 0x00013154
Writing register (PC = 0x d83e)
Starting target CPU...
So far so good. But listening on the port (assuming udp).
> nc -l -u 50001 > /tmp/log
one can see that nothing happens.
> ls -sh /tmp/log
0 /tmp/log
the /tmp/log
never changes. So I'm not sure what happens here. What I can see is that there is no visible reading/writing of the ITM registers. I'm not sure exactly what SWO EnableTarget is doing under the hood (the JLink doc is not clear about this, but I would expect it to program ITM registers of the target, and perhaps validate that the clock divider was correct). I tried to force some problems by setting an illegal SWO frequency, and indeed it reported an error. Even if I don't do anything with the trace data I would expect the size of the /tmp/log
to change.
I tried doing a similar setup for OpenOCD both in vscode and from terminal. There the behavior was slightly different. In vscode, I could not get any trace data. From terminal, I could see that data was written by openocd to the file alotted, but it was garbage, at least I was not able to decode it correctly using the itmdump
tool. Looking at the data in an hex editor gave me the impression that the data was garbage. I tried a few different SWO speed settings and the data changed but still looked like garbage (itmdump
failed to decode it at least). So regarding OpenOCD, there might be some bug in the itm setup management for the NRF52).
Sorry for the lengthy post, but if you got this far, please shed some light on this if you have any idea on what could be going on?
Thanks in advance,
Per