Remote development with Zephyr

Typically, installing your code on the target board with Zephyr is as simple as connecting a USB cable between your workstaiton and the board, then typing west flash.

But what if you can’t connect the board directly to your workstation? This might be because:

  • there’s a global pandemic and you’re working from home, or
  • you’re working from a notebook computer and you don’t want to be tethered, or
  • your target board needs to be somewhere you are not, or
  • you want multiple people (and/or your CI/CD system) to be able to deploy to the same target board.

Let’s look at some ways to develop with Zephyr, without having to connect the target board’s programming cable directly to your workstation.

In this article, we’ll use the term “helper system” to refer to the intermediate computer that we will use to facilitate remote installation.

Use remote access to the helper system

For minimum fuss, one could simply site a PC, a spare notebook, or a Raspberry Pi adjacent to the development board, and access this “helper system” via remote desktop, or remote login (ssh), keeping the source code on the helper system rather than on one’s workstation.

But for the rest of this article, we will presume that you do prefer to keep the source code on your workstation, where you have access to your preferred Integrated Development Environment (IDE), but deploy remotely.

Copy the compiled program and use west to install it

When you compile your program using west build, the output is generally a single file, named build/zephyr/zephyr.hex.

You can install this file on a remote development board by copying it to the helper system and using west to install it. We will use scp (secure copy) and ssh (secure shell) to access the helper system.

(An aside, the examples below involve ssh helper, where ‘helper’ is the putative name of the helper system. You can either substitute the actual name of your helper system, or edit your ~/.ssh/config file to define an alias named ‘helper’ which describes the helper system’s access details).

In order to use west, we will require a copy of the Zephyr build environment on the helper system (but not necessarily your application code)

Do this once:

We’re going to build one of Zephyr’s sample applications on the helper system, purely in order to create a zephyr build directory. We’ll then (ab)use this build directory to flash your application firmware.

ssh helper "cd zephyrproject/zephyr && west build -b YOURBOARDHERE samples/hello_world"

Do this each time you want to flash:

We’re going to copy your compiled application firmware onto the helper system, placing it within the zephyr build environment, then (ab)use the build directory we created above to flash your app:

west build
scp build/zephyr/zephyr.hex helper:zephyrproject/zephyr
ssh helper "cd zephyrproject/zephyr && west flash --hex-file zephyr.hex

Use OpenOCD to install the compiled hex file

If you don’t want to (or can’t) install Zephyr on the helper system, then you can use OpenOCD as a flexible flash programmer that supports most popular programming cables (such as J-Link, ST-Link, Blackmagic, or even a no-parts-programmer using the Raspberry Pi GPIO pins).

For example, if using a Segger J-Link cable and a Nordic nRF52 chip, one would do this:

west build
scp build/zephyr/zephyr.hex helper:
ssh helper 'sudo openocd -f interface/jlink.cfg -c "transport select swd" -f target/nrf52.cfg -c init -c "program zephyr.hex verify reset exit'" 

OpenOCD supports a number of programming interfaces and target devices. Look under /usr/local/share/openocd/scripts/interface/ and /usr/local/share/openocd/scripts/target/ on your helper system to find the scripts appropriate for your situation.

Remote reset or erase

We can also remotely reset or erase our target using OpenOCD:

To reset a remote board:

ssh -t helper 'sudo openocd -f interface/jlink.cfg -c "transport select swd" -f target/nrf52.cfg -c init -c reset -c exit' 

To mass erase an nRF52:

Some chips come from the factory with write-lock enabled, and require a mass-erase procedure to be performed to un-lock the chip. In particular many Nordic nrf52 chips require this, and there’s a special procedure defined by OpenOCD:

ssh -t helper sudo openocd -f interface/jlink.cfg -c "transport select swd" -f target/nrf52.cfg -c init -c "nrf52_recover" -c exit

Remote debugging with OpenOCD

Normally, when you type west debug, the west tool starts a copy of OpenOCD on your workstation to which you can connect a debugger such as gdb. OpenOCD listens on TCP port 3333 for debugger connections. Using SSH’s port forwarding We can do this remotely also:

ssh -L 3333:localhost:3333 helper 'sudo openocd -f interface/jlink.cfg -c "transport select swd" -f target/nrf52.cfg -c init'

Now when we instruct our debugger (say, gdb) to connect to “locahost, port 3333”, our SSH process will intercept the connection and forward it to the instance of OpenOCD running on the helper system.