Setting up JLink

Hello,

I have created a custom board platform (Nordic nRF9160 chip) Nordic Demo Kit board (nrf9160dk) has a built in J-Link debugger probe and I thought it would be great to add debugging support for this board.

After a lot of stumbling around, I somehow managed to get a working debugging configuration for a sketch, but I am not sure how I did it and I am not able to replicate the process.

I have followed both tutorials on how to setup debugging, analysed SAMD configuration, read numerous forum posts and I am still stuck. The most relevant information appears here: https://forum.arduino.cc/t/debugging-project-out-of-iot-sktechbook/965173.

What I can do is manually find for the current sketch, C:\Users\my_username\AppData\Local\Temp\arduino-ide2-<temporary_directory_name>, and copy into it a previously created launch.json. If this JSON contains all the right information, the IDE (both v2.2.1 and v2.1.1) immediately shows it in the list of available debugging configurations, and I can debug the sketch.

For the record, once launch.json is in place, the existence of debug_custom.json is irrelevant.

In Arduino IDE v2.2.1, the Debug button on the main toolbar is always disabled, no matter what I do. In v2.1.1 it is generally enabled, but when I place a known good launch.json into <sketch>/.theia directory and click Debug, I get a 'Cannot read properties of undefined (reading 'script') error message.

So, my question is, is there a way to automatically create a working debugging configuration from profile.txt and GUI only. I cannot expect ordinary users to create launch.json themself and then be able to copy it into the exact one of hundreds of temporary directories.

I am happy to add post linking hooks into profile.txt that would create a correct launch.json and copy it into the correct location. The trouble is that I don't know what this correct location is.

So as a minimum, I would appreciate if someone could tell me how to get the name of the debugger's temporary directory where I could place launch.json automatically. I would appreciate if someone took the trouble to point me towards the details of cortex-debug plugin integration into Arduino.

A working launch.json looks something like this:

{
    "version": "0.2.0",
    "configurations": [
      {
        "cwd": "${workspaceRoot}",
		"name": "Dejan",
        "executable": "C:/Users/username/AppData/Local/Temp/arduino/sketches/5D8829399059057C3570B582018D0B8D/AnalogInput.ino.elf",
        "type": "cortex-debug",
        "armToolchainPath": "C:/Users/username/AppData/Local/Arduino15/packages/platform_name/tools/gdb/1.0.0",
        "request": "launch",
        "device": "nrf9160",
        "servertype": "jlink",
        "serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe",
        "configFiles": [
          null
        ]
      }
    ]
}

If you read this far, thank you for your attention. If you can provide some information that can help me move forward, I'll be very, very grateful.

Regards,
Dejan

Hi @ddeletic.

Very cool! Did you publish it online? If so, please post the link to it. It might be useful for us to be able to look at the platform code during the course of the discussion here.

Beyond that, I make an effort to be aware of all the amazing board platforms created by the Arduino community (and especially for the ones that take advantage of the interesting new features like the Arduino IDE 2.x integrated sketch debugger!).

Arduino IDE determines whether a platform has debugger support by the presence of the debug.executable property in the platform configuration files:

https://arduino.github.io/arduino-cli/latest/platform-specification/#debugger-configuration-directives

This is exactly what Arduino IDE does. It automatically generates a launch.json file from the platform properties.

That automatically generated file is typically perfectly sufficient, so the user only needs to click the button in the Arduino IDE and they are set. However, at least in the "Arduino SAMD Boards (32-bits ARM Cortex-M0+)" platform, if the user wants to use a Segger J-Link probe specifically, it is also necessary for the user to create a debug_custom.json file. The reason is that the J-Link has a dependency on the proprietary "J-Link Software and Documentation Pack". The user must install that software on their own (as opposed to it being automatically installed by the Arduino IDE Boards Manager as is the case for the open source toolchains) so Arduino IDE doesn't have any way of automatically knowing where to find the JLinkGDBServerCL executable.

Maybe you will find some better approach to locating that executable in order to achieve a fully automatic debugger configuration. But even if not, at most the user should only need to specify that path in a debug_custom.json file. All this stuff you are doing with making your own launch.json is completely unnecessary.

What is profile.txt?

Hi @ptillisch,

thank you for taking the time to respond.

Not yet, mainly because none of the online services I use will accept a 133MB toolchain archive. Also, because it is still WIP - e.g. I am not sure yet that analogRead() produces valid readings. I will certainly let you know when I do eventually publish.

Oh, it was past 1am when I wrote that original post. It is a typo which was meant to be platform.txt. :slight_smile:

My platform.txt contains the following line:

debug.executable={build.path}/{build.project_name}.ino.elf

This should be sufficient, shouldn't it? I am not sure what it expands to when Arduino parses it. Is there a way to increase command line output verbosity level?

Even if I use:

debug.executable=C:/Users/username/AppData/Local/Temp/arduino/sketches/5D8829399059057C3570B582018D0B8D/AnalogInput.ino.elf

the Debug button remains disabled. I am positive that the elf file exists. In GitBash:

cd C:/Users/username/AppData/Local/Temp/arduino/sketches/5D8829399059057C3570B582018D0B8D && ls -l AnalogInput.ino.elf
-rw-r--r-- 1 user 197121 4018560 Dec 13 00:04 AnalogInput.ino.elf

image

I wouldn't be doing any of that, if only I could get past the first hurdle - getting the Debug button to be enabled. Hopefully all pieces fall into place after that. My intention is to require minimal, and if possible, no user action in order to debug.

Clearly, in my case things do not work as expected, launch.json isn't generated. And yet, if I generate it manually, debugging works.

Users will have to be instructed to install J-Link software somehow. Without it, there is no debugging. At this point, perhaps they can be asked to install into the default location (C:/Program Files/SEGGER/JLink) in which case platform.txt/debug_custom.json will know where to find it.

For the record, my platform.txt contains the following debug directives:

debug.name="nrf9160"
debug.executable={build.path}/{build.project_name}.ino.elf
debug.toolchain.path={runtime.tools.gdb.path}
debug.toolchain=gcc

debug.device=nrf9160
debug.server=jlink
debug.interface=swd

And both, the sketch and {build.path} directories contain debug_custom.json with the following:

{
    "name": "nrf9160",
    "device": "nrf9160",
    "serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe"
}

Again, any additional information would be greatly appreciated.
Thanks,
Dejan

If anybody stumbles here, and is interested in the topic, my experience may help.

I have made some progress with the helping hand of arduino-cli debug (v0.34.2) which provides more diagnostics than the IDE.

Several things I was doing wrong:

  • my debug.executable directive in platform.txt was incorrect, and arduino-cli helpfully pointed it out (I had an extra .ino)
  • in platform.txt, debug.server must be set to openocd. Setting it to 'jlink' is rejected as not supported, and omitting it altogether is not allowed
  • this must be overridden in debug_custom.json with "servertype": "jlink"
  • the above two points do not apply to Arduino IDE. It will happily accept debug.server=jlink in platform.txt
  • I was under the impression (perhaps implied from an earlier version of the documentation) that debug.toolchain.prefix defaults to arm-none-eabi-. Incorrect. It has to be explicitly stated.

After fixing the above, I was able to start debugging using arduino-cli.


However, Arduino IDE debugging is still a struggle.

The 'Start Debugging' button on the main toolbar is always disabled on startup. Therefore launch.json can never be created. By pure accident, I discovered that I can re-enable it by changing the board type, and then reverting back to my board. Once I get the button enabled, launch.json is created and debugging can commence. Debugging works just fine after this point.

Unfortunately, besides being quite unintuitive and annoying having to do it for every sketch, this trick for enabling the button works in Arduino IDE v2.2.1 but not in the latest nightly build (202031225), so I expect it will cause problems down the line.

Addditionally, selecting the correct directives in platform.txt and debug_custom.json was NOT plain sailing either. After a lot of trial and error attempts I found out that:

  • platform.txt must contain 'debug.server.jlink.script=' directive even if empty. Otherwise when creating launch.json the IDE issues a cryptic notification "Cannot read properties of undefined (reading 'script')"
  • Platform specification documentation describes debug.cortex-debug.custom.* directives. Unfortunately they do NOT work in v2.2.1. Not even when copied verbatim from the documentation.
  • until the previous point is resolved, there is no way around having debug_custom.json maanually created next to the sketch file. This is not a great user experience and I feel that a small effort is needed to allow developers to automate this step.

For the record, my latest set of debugging directives in platform.txt is:

debug.server=jlink
debug.server.jlink.script=
debug.toolchain.path={runtime.tools.arm-none-eabi-gdb.path}
debug.toolchain.prefix=arm-none-eabi-
debug.svd_file={runtime.platform.path}/nrf9160.svd
debug.executable={build.path}/{build.project_name}.elf

and debug_custom.json is:

{
    "name": "BoSL nrf9160",
    "serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe",
    "device": "nrf9160"
}

NOTE: The cortex-debug plugin appears to be helpful by offering to create or add debugging configuration right in the GUI, and with a skeleton configuration and handy hover hints. However, it saves launch.json in .theia directory which seems to be completely ignored by the IDE. The only way to correctly create launch.json is to click on the 'Start Debugging' button on the main toolbar (providing it is enabled).

This is a known bug in Arduino IDE 2.2.0 and 2.2.1:

It has already been fixed, but there hasn't been a release since that time. The fix is in the Arduino IDE nightly build. The download links for the nightly build are listed here:

https://www.arduino.cc/en/software#nightly-builds

I highly recommend you to use the nightly build if you are doing any work with the debugging framework because the framework was recently completely redone. The reason for this was that the platform developers ran into limitations of the old framework that forced them to make hacky workarounds like automatically generating debug_custom.json files. You might find that the problems you are currently experiencing no longer exist once you use the new framework.

You should refer to the "dev" version of the Arduino Platform Specification which is applicable to the 0.35.0-rc.7 pre-release version of Arduino CLI currently used by the latest nightly build of Arduino IDE:

If you are working with Arduino CLI directly, you will also want to use the 0.35.0-rc.7 pre-release, which is available for download from the links under the "Assets section of the GitHub release page:

Hello, Arduino gurus, and @ptillisch in particular. Thanks for your help so far. Sorry for the long delay, I have been busy with other, non-arduino stuff.

Firstly

It has now been published at `https://www.bosl.com.au/code/nrf9160dk/package_bosl_nrf9160dk_index.json

As for my troubles with JLink, they are still there. Nightly builds do not resolve the issue. As a matter of fact, the issue is even worse, given that the Debug button is always inactive, and I cannot get the workaround used in v2.2.1 to work. Hopefully someone can use my package to test and perhaps resolve the issue.

Thanks,
Dejan

1 Like

Wooooooo Hooooo!

Arduino IDE v2.3.2 finally solves debugging issues I've had. Debugging now works as expected.

Thank you developers!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.