Workflows for Elixir Nerves
June 27, 2022, by Jason Johnson
It’s true, we’re still going through a chip shortage, but I’m telling you now is the best time to get started with Nerves. There are more developer experience paths, better documentation, and better target device support than ever before.
At FullSteam Labs, we see tremendous potential in Elixir Nerves for creating new technologies that solve real-world environmental and sustainability issues. Nerves enables fast paced development cycles for firmware and hardware teams to develop scalable, fault tolerant, connected IoT solutions.
In this post, we will explore an array of options for working with Nerves in various contexts. For our purposes, workflows include connecting to, interfacing with, and loading firmware updates to a Nerves target device.
Here’s a brief overview of all the options available for working with Nerves:
I’ve chosen to cover only a subset of these that I find to be the most productive in this post: Serial Cable, WiFi, iEx, Hotswap, OTP, Livebook, NervesHub. Without further ado, let’s explore some of the pathways you could choose from for your own Nerves workflow.
Working with a serial cable allows you to open a direct console connection to the Nerves target through a terminal emulator like screen. One of the most popular hardware options for working with Nerves is the FTDI cable.
This workflow is particularly useful during early development and for debugging new hardware or development boards.
The best part about working with a serial cable is that you get to see console output immediately. As a bonus, getting up and running with a serial cable requires no networking!
However, there are some drawbacks to this approach: this approach includes wires, TX and RX connections can be easily confused, the console experience (often) lacks a scrollbar, and these cables are not always available when you need them.
There are a LOT of ways your Nerves target can be configured to use WiFi. Vintage Net provides support for all the common and some rather uncommon WiFi configurations.
The best use cases for WiFi include hobby projects, prototyping, and commercial use (although LTE is often preferred over WiFi).
The benefits of using WiFi include no wires (obviously, but hooray!), it’s commonly available, the Vintage Net package makes configuration a breeze, and Vintage Net Wizard provides a tool to help you get up and running with zero firmware configuration (in case that’s what you’re looking for).
However, even with Vintage Net’s help, wireless networking may present confusing situations and depending on your network connection, firmware size, and the current resource load on the target device over the air (OTA) updates may take longer than simply burning and swapping the SD card.
Nerves makes it easy to establish an iEx session with the target over ssh, which opens up the world of REPL-driven development. It’s a fantastic way to debug, inspect, and run code from the runtime environment.
The best time to use iEx as part of your Nerves workflow is always. It’s an indispensable tool that most of the other development workflows are steeped in.
The Nerves team has pared down the base Linux system significantly, but they’ve provided the essentials for working at the command line (like cd, dmesg, grep, ls, ping, etc) in a package called Toolshed that’s included by default in remote iEx sessions. In order to update code you’re working on, you can copy and paste modules and functions directly into iEx to redefine that code in memory.
While it’s great to be able to redefine code in memory with iEx copy pasta, be warned that you could code yourself into a corner so to speak.
Sign up here to get tools, tips, and insights delivered to your inbox.
This magical package provides OTA module hotswapping to update application code in memory. It’s not well known, but it’s my personal favorite for developing Nerves projects: kentaro/mix_tasks_upload_hotswap.
The most appropriate use cases for this workflow include project development, library development, and hardware hacking.
The benefits include, again, no wires, a very tight feedback loop (with compile-time checks), relatively easy setup, and the potential to combine with OTP for quick iteration on supervision trees and other hard to test app functions (read more about this below).
There are however, a few important drawbacks to be aware of:
- Changing module definitions in memory may present confusing situations.
- All modules are replaced each time without checking which changed.
- Doesn’t support changes to mix.exs or configuration files.
- Doesn’t support changes to project dependencies.
Ah yes, OTP, that special blend of powerful abstractions rolled into a small set of battle-tested Erlang libraries. Although OTP isn’t specifically a “workflow” for Nerves, it can be used in combination with module hot swapping or iEx to achieve an incredible developer experience.
With supervision trees and GenServers, it’s commonly necessary to debug issues with a fresh startup after making changes. When using mix_tasks_upload_hotswap with OTP primitives, you can update your project code without restarting the target device and instantly load it by restarting GenServers and/or Supervisors in place. This is especially useful in a scenario where you’re trying to tweak the startup sequence on a Nerves target that requires complex initialization, registration, or provisioning tasks.
Oh, did you expect to read about drawbacks to OTP? Better luck next time…
Elixir Livebook is a library for managing live, interactive, and collaborative code notebooks. Nerves distributes pre-built firmware releases that run Livebook along with some demo notebooks on any supported Nerves target.
Common use cases for this workflow include experimenting with new hardware, creating documentation and guides, onboarding developers, and demos!
There are many benefits to this workflow, but first and foremost, it’s a live journal that runs on Nerves! It provides a tight feedback loop for working with reproducible, collaborative code notebooks. Livebook also opens up new possibilities for displaying data through libraries like Kino, automated workflows for database queries, and machine learning.
Since Livebook is designed for code editing and execution, there are some important security considerations, most notably that notebooks are not sandboxed. In production mode, a security token is required to access Livebook, but that doesn’t mean you can’t make a mess. However, if you’re careful about how you use and deploy Livebooks, you should be fine. One last thing to be aware of is that you may end up overwriting your notebooks by burning new firmware to the SD card.
The official NervesHub documentation describes the project as “An open-source firmware updates server”. However, there’s SO much more to it, including a CLI tool, a certificate authority server, a device updates server, an API server, and a web front end.
NervesHub can be installed on AWS with a terraform script or run as separate services on another platform (although this is arguably the most difficult option).
Now that the community version of NervesHub has been sunset (March 2022), the most common use cases for this workflow include commercial IoT companies. However, I’d like to see a community version of NervesHub or NervesHub Lite resurface at some point in the future.
Some of the most useful benefits of working with NervesHub include: OTA updates (obviously), management of products and devices within your fleet, the concept of deployments for controlling what firmware gets loaded to devices and when, and tags (which can be helpful when managing larger numbers of products and/or devices).
While NervesHub is certainly amazing, it’s not for the faint of heart. Since the community hosted version is no longer available and it’s challenging to configure the self-hosted NervesHub, there’s a non-trivial time, learning, and capital investment needed to access the power of NervesHub.
That concludes our tour of the top Nerves workflow options available today. Hopefully, it’s clear now that there are many ways to approach your work with Nerves, each offering different benefits and drawbacks given the situation. Working with multiple workflows in combination and switching between different workflows is a good idea, especially while the focus of your work moves from hardware support and configuration to firmware development of business logic.
Have you already tried all of these techniques in your work? Are there others you’d like us to make a mention of? I encourage you to experiment with some new workflows the next time you get into a Nerves codebase. Reach out and share your experience with Elixir Nerves