Tag Archive for: Embedded

Team members Lachlan and Chris discuss an implementation of a Rust code sample with Golioth and the Nordic Semiconductor nRF9160. There is a demo of the code working in the video attached below.

What is Rust?

Rust is a high-level, general-purpose programming language, syntactically similar to C and C++. It is fast and memory-efficient and is specifically designed for performance and safety. It has no runtime or garbage collector, while taking advantage of the higher-level concepts and safety guarantees. Rust can run on embedded devices, and can be easily integrated with other languages, and is ideal for performance-critical services. Rust is still in early days of development, starting in 2010 and only coming to embedded devices a few years ago. The developer community around Rust is passionate and growing. While Rust and C/C++ share similarities, Rust is relatively faster than C/C++ in some cases. Rust also has the benefit of a package management system, which makes implementing different libraries easier than C (which existed long prior to the internet). Easy package management encourages code reuse by allowing libraries to be readily integrated into applications, not to mention building the overall community around Rust.

Why we’re trying it

Golioth was interested in trying out Rust as part of our Golioth Labs segment on GitHub, where the code is currently hosted. It represents one of many trials we have and will take on in order to showcase the Golioth platform. We are committed to showing ways to access Golioth services and APIs outside of our normal recommended path Golioth SDK based on Zephyr RTOS. Not only does this represent the reality for many users, it also showcases how Golioth services are accessible from many different programming paradigms, in addition to a wide range of hardware. Another good example from Golioth Labs is our Arduino SDK discussed in our last article.

We chose to try Rust on the nRF9160 because the hardware represents a key product on the platform. This Nordic part has great support from Golioth and Nordic Semiconductor, and is listed as “Verified + Quickstart” on the Golioth Hardware Catalog. While the quickstart is using Zephyr to get users up and started, it is a well-supported part internally at Golioth. The nRF9160 is also primed for Rust integration: Nordic Semiconductor provides a library for the NRF devices that exposes the API which communicates with the hardware. There is also a Rust binding for it which makes it quite easy to implement the rust code and enables you to connect to Golioth servers and send and receive data. In addition, Rust has some code abstraction features and doesn’t require a debugger.

Video explanation and demonstration

In the demo below, Lachlan shows how he is able to use the library and bindings to connect over CoAP to the Golioth servers and replicate many of the functions that exist in Golioth samples.

One of the first challenges any embedded software developer faces is installing and configuring their development environment and toolchain. Toolchain version, silicon vendor libraries, Windows versus Linux, debug configuration, IDE settings, and environment variables are just a few components of the modern embedded developers workspace. The result of all this complexity is a fragile, hard to reproduce workspace for software often used in critical systems. We consider this developer experience equivalent to torture, and believe it is trapping value from reaching the market.

We know there is a better way. If the development environment can be entirely packaged and abstracted away from the developer they will be able to more quickly begin application development.  A remotely managed toolchain also facilitates more efficient teamwork. It eliminates the cryptic mantra: “Works On My Machine” accompanied by an obligatory shrug.

The Established Way

The traditional approach to eliminating toolchain headaches has typically been through the use of Integrated Development Environments (IDEs).  However, these packages are generally locked to a particular silicon vendor or compiler, may have paywalls to expose premium features, and can be constrained in feature availability. Our ‘gold standard’ for years has been the following:

  • Ubuntu Virtual Machine
  • Eclipse
  • GNU MCU Eclipse Tools
  • USB Passthrough from VM for debugging boards

Modern Web Options

Technologies like, VS Code, containerization, Microsoft’s Debug Protocol, and Language Server protocol have come together to enable a transformational developer experience. Most of the current approaches to bringing these technologies together in the market are built on top of some variation of VS Code. Each solution is vying to take advantage of VS Code’s capacity to run in the browser as seamlessly as it runs on a local machine.

One option is Github Codespaces.  Which option requires the user to be on a paid plan, is not focused on embedded development, and uses a closed source server that is closed source. Another option is Keil Studio.  Keil Studio is optimized for embedded development with ARM based microcontrollers. Pricing and roadmap are not yet established. It provides no terminal access and offers a limited number of embedded targets to work with.

Why We Chose Gitpod

We chose Gitpod in part for our mutually valued stance on open source, sustained active community engagement, and obsession with developer experience. Of note is Gitpod’s full-feature free tier. They provides 50 hours of running workspace per month; No payment details required. As a result, the psychological barrier of getting up to get one’s credit card is avoided. Fifty hours is enough time to introduce oneself to the Zephyr and Golioth ecosystems. Finally, Gitpod being open source enables us and our developers to optimize their workspaces to their needs.

 

Our Current Gitpod Workflow

Setting up the application begins with cloning the Example Application from Zephyr GitHub. Next, the Golioth SDK is added as a dependency.  Changes are then added to the .gitpod.yml and .gitpod.Dockerfile. After running ‘west update’ with the configurations in place, the hello application is copied from the Golioth SDK directory to the project root directory in place of or at the same level as the ‘app’ folder. Here is a link to the end result.

Also, some background info on Gitpod.

Our target embedded cloud developer experience would be one in which the developer instantiates the cloud development environment and has zero local tool dependencies.  They can then plug their debug hardware into any machine from anywhere with internet access and develop.  Our current implementation requires three local tools to facilitate debugging functionality with the current state of the Gitpod software and VS Code. Gitpod provides a Gitpod Local Companion which allows localhost access to any TCP port in a remote workspace. The second piece of software required locally is SSH.  SSH is necessary to establish an ssh tunnel between the Gitpod instance and local machine. The final software that is run on the local machine is JLinkGDBServerCL.

 

 

State of the Art

The technology to facilitate cloud-based development has arrived and it will enable remarkable gains in productivity and developer experience.  Unfortunately, we still have local dependencies and in the current state things are not optimized for use over the internet. Step debugging was accomplished, but some work remains for embedded cloud development to compete with a local development environment. With this in mind, a future blog post will show we actually can be effective developers when using this solution with a virtualized QEMU target.

To do this proper we’d serve an MS DAP compatible debug server such as Probe.rs to the developers browser, and hook it up to the target board using webUSB. A challenge that exists, is the lack of open source microcontroller debuggers written in JavaScript or WebAssembly.  The translation from C code to WebAssembly is not straightforward and can be error-prone. However, valid translators of Rust to WebAssembly do exist, and Probe.rs is an open-source debugger written in Rust.  We also need to convince Microsoft to push this PR forward.

Stay tuned for a future post about how to build, run, and debug Golioth examples with QEMU in less than 10 clicks.