Here at Feabhas we tend to favour using Segger J-Link’s as our ‘go-to’ solution for target flashing and debug, as they fall into that category of tools that just work.
As part of our ongoing work around Agile and CI (Continuous Integration), we’re always interested in addressing that challenging step of automating target based test in a cost-effective manner.
The Raspberry Pi (RPi) is a ubiquitous low-cost platform for numerous tasks. One useful tasks that it can be used for is as a network-based conjugate between a client machine and a target board, where the target board is connected to the RPi via a local J-Link.
Setting up the RPi
The Segger J-Link utilities are available for ARM-based systems, which means it should work on any Raspberry Pi. However, we have, so far, only tested it on a RPi3+, but intend to try the PiZero as well.
As we are using the RPi in a headless setup we installed Raspbian Stretch Lite, connected an HDMI screen plus keyboard and booted up the Pi.
We then proceeded through the usual Pi setup
- ensured all software was updated
- changed the pi user password (I know many people go further and swap out pi for a different user)
- enabled SSH (this becomes useful later when remote working from a client):
$ sudo raspi-config --> 5 Interfacing Options Configure connections to peripherals --> P2 SSH Enable/Disable remote command line access to your Pi using SSH
In addition, make a note of the RPi’s IP address (assuming you’re using the WiFi interface), as we’ll need that later to connect:
$ ip addr show wlan0
and make a note of the
inet number (e.g. 192.168.0.XXX or similar), or use
Installing the J-Link utilities
Connect your J-Link via USB to the Pi and to your target board via the appropriate header. Assuming SSH was set up we can now work remotely from the client machine.
On our client machine, log in to the RPi via ssh:
$ ssh firstname.lastname@example.org.XXX email@example.com.XXX's password: Linux raspberrypi 4.19.50-v7+ #1234 SMP Thu Jun 13 11:06:37 BST 2019 armv7l The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Thu Jun 20 10:27:31 2019 from 192.168.0.YYY pi@raspberrypi:~ $
pi user home directory, download and un-tar the Segger utilities for the Pi. Then configure the
udev rules as per
README.txt file in the
$ wget --post-data 'accept_license_agreement=accepted&non_emb_ctr=confirmed&submit=Download+software' https://www.segger.com/downloads/jlink/JLink_Linux_arm.tgz $ tar xvf JLink_Linux_arm.tgz $ cd JLink_Linux_V646g_arm/ $ more README.txt $ sudo cp 99-jlink.rules /etc/udev/rules.d/ $ sudo reboot
This will close the ssh connection.
Starting the RPi’s J-Link Server Software
Re-login to the RPi via ssh.
Under the directory
JLink_Linux_V646g_arm there are a number of utilities. As we are running from the command line we need to invoke the application
JLinkRemoteServerCLExe on the RPi:
$ ./JLink_Linux_V646g_arm/JLinkRemoteServerCLExe -Port 19020 SEGGER J-Link Remote Server V6.46g Compiled Jun 14 2019 19:38:47 'q' to quit '?' for help Connected to J-Link with S/N xxxxxxxxx Waiting for client connections...
Reading the documentation, the
-Port 19020 shouldn’t be required as it’s supposedly the default port, however, at the time of writing without specifying this the client connection always fails.
Connecting the client via CLI
On the client machine, download and install the Segger J-Link Software and Documentation Pack specific for your host OS (I’m using macOS).
Once installed, simply type the following (substituting the IP address as appropriate):
$ JLinkExe ip 192.168.0.XXX SEGGER J-Link Commander V6.46g (Compiled Jun 14 2019 19:36:04) DLL version V6.46g, compiled Jun 14 2019 19:35:53 Connecting to J-Link via IP...O.K. Firmware: J-Link V10 compiled Jun 14 2019 19:25:26 Hardware version: V10.10 S/N: xxxxxxxxx License(s): FlashBP, GDB OEM: SEGGER VTref=3.303V Type "connect" to establish a target connection, '?' for help J-Link>
On the RPi you should see:
Conn. 8: Client connected. Connected to J-Link with S/N xxxxxxxxx
To disconnect the client, simply type
qc at the J-Link command line and the RPi should go back to:
Waiting for client connections...
Connecting a client debugger
If the J-Link remotely connects correctly, then it is also possible to use tools such as Segger’s Ozone to do remote target debugging. For example, in Ozone simply set the IP address of the remote RPi in the J-Link Settings under the Tools menu.
You can then download and debug an image as if the target was local to the client machine:
Back in February if this year (2019), Segger announced a new feature call tunnelling. This enables remote connection to a J-Link Server via the internet.
To use this utility, then on the RPi, type:
$ ./JLink_Linux_V646g_arm/JLinkRemoteServerCLExe -UseTunnel -TunnelByName <some_name> -TunnelPW <some_password>
$ ./JLink_Linux_V646g_arm/JLinkRemoteServerCLExe -UseTunnel -TunnelByName feabhas_jlink_42 -TunnelPW monkey
And before you ask, no we don’t use
monkey as our password 😉
On the client connect via:
$ JLinkExe ip tunnel:feabhas_jlink_42:monkey
Full details can be found at https://www.segger.com/products/debug-probes/j-link/tools/j-link-remote-server/.
Note: I was unsuccessful getting this to work with Ozone
It is important to note, that for the Linux ARM utilities, Segger clearly state that the :
This package comes without any support.
I have found that quite regularly once I have quit the client I am then unable to reconnect, with the following error:
$ JLinkExe ip 192.168.0.XXX SEGGER J-Link Commander V6.46g (Compiled Jun 14 2019 19:36:04) DLL version V6.46g, compiled Jun 14 2019 19:35:53 Connecting to J-Link via IP...FAILED: Can not connect to J-Link via TCP/IP (192.168.0.XXX, port 19020)
And the Server application still thinks the client is connected. The only option I’ve found is to type
q in the RPi session which quits
JLinkRemoteServerCLExe and then to restart it from the command line. This is the major reason for using SSH as it allows
JLinkRemoteServerCLExe can be restarted remotely.
The same issue was persistent when using tunnelling and, obviously, having no SSH connection to the RPi it proved pretty useless (if I use our VPN to connect to the RPi it negates the benefit of tunnelling).
However, others have indicated they have had no such problems (it may be something LAN specific?).
The use of a Raspberry Pi acting as a network-connected conduit to a target board is very attractive. RPi’s are easy to source and very inexpensive. Combined with Segger’s J-Link utilities, including applications to handle GDB and SWO, then it may provide a good platform for taking many CI pipelines to their next step.
Unfortunately, the issues of failed reconnection do seem to only be happening with the Linux Arm utilities. Running the same Remote Server commands a Linux laptop proved reliable, both on the local LAN and using tunnelling.
As Raspberry Pi’s support Docker, then my next angle of attack is to see if there is a way I can run the server software in a docker container, which would allow for simpler restarts without needing the SSH connection.
For now, we’ll live with the reconnection issue and continue to use SSH, but watch this space…
- Disassembling a Cortex-M raw binary file with Ghidra - December 20, 2022
- Using final in C++ to improve performance - November 14, 2022
- Understanding Arm Cortex-M Intel-Hex (ihex) files - October 12, 2022
Co-Founder and Director of Feabhas since 1995.
Niall has been designing and programming embedded systems for over 30 years. He has worked in different sectors, including aerospace, telecomms, government and banking.
His current interest lie in IoT Security and Agile for Embedded Systems.
Thanks for your valuable guidance through this blog.
You explained well for case of RPI as Jlink server , But how we can handle for other micro controller . The reason I'm asking this question is because I want to try automating debugging/flashing using CI for bare controller like ST/ADU ARM controller (RPI is abstracted Embedded system with all facilities & driver ) .
My thought to implemented is invoking Jlink server on dedicated PC System ( with Board connected to Jlink debugger ) using 1 jenkins plugin called JENKINS External Resource dispatcher. In one of my Automotive project there was requirement to automate through CI (Jenkins) after developer commit code to SVN/GIT . Test Enginner will also commit Jlink script to github .
Hi. What you want to do is what we're also looking to do here.
We have an STM32F4 connect via the j-link to the RPi as a bare-metal unit.
Thanks for the link to the External Resource dispatcher, I wasn't aware of that.
My plan/hope is to use Docker on the RPi in conjunction with the j-link and see how I can use Jenkins to kick off a test.
Ultimately I'd like to have a bespoke Docker image build on the fly for a particular test, incorporating python test drivers.
I'm some way off this, but having the RPi with remote re-flashing capability is a step along the journey.
Let me know if you get the External Resource dispatcher going, if I do I'll document it.
Thanks for your article. Did you ever get around to run the JLink tools in a docker container as you mention at the end of your article?
No, unfortunately, I didn't, it's still on my (very long) backlog list.
We've been very distracted over the last year developing a comprehensive QEMU simulation of our target system, so the physical world has taken a bit of a backstop.
That said, I'm just embarking on some new work where I may look to get this working.
What this space 😉
Thanks for your reply Niall. I might be experimenting with this myself too, hence my question.
Side note: is it expected that the comments themselves don't show up on the site? I see there are 4 responses to the article but I can't see the responses themselves?
Yes they should show up - not sure what's going on . Will get "web" people to take a look.
Thanks and let me know if you get anything working
just as a follow-up: the process described on the Segger wiki just works out of the box on the Rpi.
the problem disappears when using the sudo command:
$ sudo ./JLink_Linux_V696_arm/JLinkRemoteServerCLExe -Port 19020
Spent some time on this step. Should have read the comments before.
$ ./JLink_Linux_V696_arm/JLinkRemoteServerCLExe -Port 19020