Developing and testing BLE products on nRF52840 in Renode and Zephyr

Published: April 13th, 2022

The Bluetooth Low Energy connectivity standard has gained immense popularity in recent years, mainly due to the growing ubiquity of IoT solutions in both consumer electronics and industry. Thanks to its low-power nature, it is widely used in healthcare (e.g. in blood pressure monitors), wearables, and smart home appliances. To enable product BLE development and testing, Antmicro implemented support for the protocol in Renode, our open source software development framework, with the Nordic Semiconductor nRF52840 SoC as the first platform with a BLE-capable Renode radio model.

Renode, Zephyr, and the nRF52840

Antmicro has provided multi-node simulation capabilities to its customers and the community via Renode for many years now, but until recently our attention was mainly focused on wired or IEEE 802.15.4 networks. However, as a Platinum Member of the Zephyr Project, which among other things features a completely open source BLE stack, we are in a unique position to cooperate with chip vendors focusing on BLE such as Nordic Semiconductors to fully support their platforms in Renode - helping their customers get the tools and expertise they need to develop well-tested solutions using the low-power standard.

Zephyr is a natural choice for many of our customers because of its open BLE stack and its wide support for a variety of popular SoCs, such as the nRF52840 which has been available in Renode for some time now.

Sharing a lot of design objectives and the open source philosophy, Zephyr and Renode are a natural pairing. Renode has extensive support for boards (including many of Nordic’s BLE-enabled boards) available in Zephyr, which you can check in the Renode Zephyr dashboard, an interactive CI dashboard we developed to showcase how various Zephyr-based firmware (such as TF Lite Micro, MicroPython and soon also micro-ROS) work in Renode.

Renode for multi-node BLE development and debugging

Developing multi-node setups is a complex process, involving many unique problems. In BLE solutions, reliability is often difficult to achieve, and thorough and repeatable debugging is necessary. In a typical scenario, when working with real hardware, you cannot fully isolate the device you're testing and any attempt to debug will make other nodes perceive the debugged node as unresponsive.

Hence, the functional simulation offered by Renode may come as an immense help in thoroughly testing BLE products, thanks to the ability to completely isolate the simulated device from its environment, and fully and deterministically control the simulation process. Every part of Renode’s simulation is controlled by a central virtual time controller, meaning that the communication between the nodes is under the user's complete supervision. Besides common debugging functions like stepping or breakpoints, Renode also enables you to control the time flow of the simulation. You can even record and replay events or simulate faults and lossy transmissions, which is crucial for the real-life usability of your IoT product. This makes debugging with Renode far more convenient and transparent compared to traditional methods.

The specifics of the IoT market require products to be scrupulously tested before deploying them at scale. Basic network testing can of course be done with abstract simulators which only focus on radio communication, but Renode enables you to simulate the whole device, using the real, production binaries. As a result, you can test both the hardware access layer and the more complex software running on top of your system, including end-to-end ML pipelines.

Our work with the Nordic nRF52840 SoC

We have been working with the nRF52840 for a long time now, for example cooperating with Google's TensorFlow Lite team when developing Renode support and CI infrastructure for TensorFlow Lite Micro - a dedicated version of TensorFlow optimized for running machine learning algorithms on microcontrollers and other small footprint devices. The platform we initially targeted in that project was Arduino Nano 33 BLE Sense, which is popular among both developers and hobbyist users. Together with Nordic, Antmicro recently organized a webinar devoted to development of edge AI solutions using Renode on the nRF52840 platform and the Arduino board.

Arduino Nano 33 BLE Sense board

Running Zephyr BLE samples in Renode

Zephyr comes with a great variety of samples and demos, which you can use to implement a wide range of useful features - from blinking an LED to creating Bluetooth mesh functionality. You can see the full list of Zephyr samples and demos in Zephyr documentation.

In the typical (non-mesh) scenario, the architecture of BLE involves an asymmetry in which the devices are assigned either a "central" or "peripheral" role. Initiators of the communication are called central nodes, while the nodes to which the central node chooses to connect are peripheral nodes. The "peripheral" device, such as e.g. a smart band, can send some sensor data to your smartphone and then enable sleep mode until the next read is requested, in order to conserve energy.

Zephyr includes an illustrative heart-rate monitor example, suggesting a real-world use case and Renode now ships with a demo script allowing you to run this example as a one liner. After installing Renode, run the following command to create two devices, one that generates heart-rate data and a second one that reads this data and reports the reading to a console over BLE:

renode -e "i @scripts/multi-node/nrf52840-ble-zephyr.resc"

Done! You should see the nodes communicating in dedicated terminal windows.

The script is a good starting point for your own development, and below we will describe how to compile your own binaries as well as explain the demo script itself.

Working with your own binaries

If the pre-built demo works for you, it's time to try your own binaries. After setting up Zephyr as described in the project's documentation you can run the following commands to build samples relevant for the BLE demo:

cd ~/zephyrproject/zephyr
west build -b nrf52840dk_nrf52840 -d central samples/bluetooth/central_hr
cp central/zephyr/zephyr.elf ./zephyr-ble-central_hr.elf

west build -b nrf52840dk_nrf52840 -d peripheral samples/bluetooth/peripheral_hr
cp peripheral/zephyr/zephyr.elf ./zephyr-ble-peripheral_hr.elf

Now, to run Renode with your own binaries, before you load the script, you will need to override the variables central_bin and peripheral_bin that the demo script is using. Launch renode, and in the CLI (called the Monitor) execute the following:

(monitor) $central_bin=@zephyr-ble-central_hr.elf
(monitor) $peripheral_bin=@zephyr-ble-central_hr.elf
(monitor) include @scripts/multi-node/nrf52840-ble-zephyr.resc
(central) start

Screenshot from Renode

Looking into the Renode demo script

The full demo script is presented below:

using sysbus

$central_bin?=@zephyr-ble-central_hr.elf
$peripheral_bin?=@zephyr-ble-central_hr.elf

emulation CreateWirelessMedium "wireless"

mach create "central"
machine LoadPlatformDescription @platforms/cpus/nrf52840.repl
connector Connect sysbus.radio wireless

showAnalyzer uart0

mach create "peripheral"
machine LoadPlatformDescription @platforms/cpus/nrf52840.repl
connector Connect sysbus.radio wireless

showAnalyzer uart0

emulation SetGlobalQuantum "0.00001"

macro reset
"""
    mach set "central"
    sysbus LoadELF $central_bin

    mach set "peripheral"
    sysbus LoadELF $peripheral_bin
"""
runMacro $reset

echo "Script loaded. Now start with the 'start' command."
echo ""

The script is responsible for creating two machines, opening up their UART analyzers, connecting them to a single network, and loading the provided binaries. Zephyr samples are loaded by providing the links or paths to custom binaries. The first block starting with mach create loads the central_hr sample and creates a machine named central that looks for active heart-rate monitors using BLE and connects to the device with the strongest signal. The other such block loads the peripheral_hr sample and creates a machine named peripheral that functions as a heart-rate monitor and generates dummy heart-rate values.

When a connection is established, central will report data reception from peripheral. This exemplifies the asynchronous architecture of BLE, as there is a clear division of roles and permissions among the created machines. Using Zephyr's BLE stack also requires setting the Quantum value for your CPUs. Picking the right value helps decrease synchronization times of your virtual nodes. For more details about BLE simulation in Renode, visit Renode’s documentation.

Packet interception hooks with BLE

Renode enables you to code your own hooks, like packet interception hooks, using Python. You can code your simulated machine to react to a packet appearing on the radio medium (like BLE). This hook will execute Python code either directly from the Monitor or from a designated file. To set up a packet interception hook on the machine from the example above run the following command:

(peripheral) wireless SetPacketHookFromScript radio "self.DebugLog('Received a packet of {} bytes'.format(len(packet)))"

This hook will print the byte length of a packet every time a network packet appears on the BLE connection of your machines.

Analyzing BLE traffic with Wireshark

Just like for Ethernet and 802.15.4 networks, you can use Wireshark to inspect the BLE traffic between your simulated machines. To set up a connection in which you observe and log only a specific interface (like BLE), run:

(machine) emulation LogBLETraffic

Wireshark screenshot

As you can see, all the packets transferred through the BLE wireless medium are captured and analyzed. Wireshark gives you useful information about your BLE traffic, like the type of protocol used or byte length of the captured data, as well as more information about the type of data that packet sends. Common types of packets you will encounter, while sniffing BLE traffic, are connections, write requests, or empty PDUs.

Keep in mind that you have to use the names of the interface and mediums that you specified earlier (i.e. "wireless" and "sysbus.radio" are string variables referring to specific entities you created with earlier commands rather than generic parameters).

Automated testing of BLE using Renode

Renode can be used in a variety of ways to help you with the testing and CI processes. One of the supported methods is via the Robot Framework, a popular testing tool whose test syntax mimics natural language, making the process of writing tests quite intuitive. We have created a set of tests for the nRF52840 chip, including a BLE sample test which can be adapted and run in any of your BLE projects.

For every test suite executed, Robot generates an HTML file providing detailed information about the performed test and allowing you to inspect it line by line to quickly identify errors.

BLE for real-life IoT solutions with Antmicro

The work on BLE support in Renode of course offers a lot of interesting potential follow-ups, such as end-to-end testing of device-user app interactions using e.g. Android studio. We're excited to see what kind of integrations and use cases BLE support will bring. Since Renode runs binary-compatible software to what you will be running on the final hardware, it allows you to build the best user experience of your IoT solution, whether it’s a smart home gateway, weareable, or remote industrial controller. And the demoa great starting point.

If you need commercial help in developing your Bluetooth Low Energy project, Antmicro’s engineering services can help you benefit from the streamlined development and advanced testing features provided by Renode. In a software-oriented, test-driven methodology, we can assist you in developing your next-gen hardware, Zephyr port or application as well as the accompanying Renode simulation models. To learn more, reach out to us at contact@antmicro.com.

Go back