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 email@example.com.XXX firstname.lastname@example.org.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…
- TDD in C with Ceedling and WSL2 – performance issues - October 7, 2021
- C++20 modules with GCC11 - August 18, 2021
- Modern Embedded C++ – Deprecation of volatile - May 12, 2021