https://underjord.io/to-nerves-from-elixir.html
Underjord Underjord
---------------------------------------------------------------------
BlogServicesNewsletterYouTubePodcastsElixir Jobs
---------------------------------------------------------------------
To Nerves from Elixir
2024-08-30
Underjord is a tiny, wholesome team doing Elixir consulting and
contract work. If you like the writing you should really try the
code. See our services for more information.
I adore Nerves. I recently joined the core team. And I'll be doing my
best to help people get along with this lovely way to co-mingle
hardware and massively concurrent reliable software.
Getting started
Assuming you have a comfortable Elixir & Erlang installed,
preferrably the most recent. Most conveniently through asdf/mise, but
I don't judge. Instructions are lifted from the official docs but I
will try to keep it leaner as I assume you are comfortable with
Elixir.
Install deps for your OS:
MacOS + Homebrew
shell
brew install fwup squashfs coreutils xz pkg-config
Linux + Ubuntu/Debian
shell
sudo apt install build-essential automake autoconf git squashfs-tools ssh-askpass pkg-config curl libmnl-dev
Have a Raspberry Pi computer (not the Picos, those are
microcontrollers), with SD-card, available. It will assume a
Raspberry Pi Zero, ie. using rpi0 for referring to the target system.
You can replace that in any command with another supported system:
shell
# Install the Nerves tooling called nerves_bootstrap
mix archive.install hex nerves_bootstrap
# Use the Nerves tooling to create a new Elixir + Nerves project
mix nerves.new my_thing
# it will ask to install deps, you can yes, otherwise: mix deps.get
cd my_thing
export MIX_TARGET=rpi0
# Getting deps with the target set will fetch the base linux system
mix deps.get
mix firmware
mix burn
The mix burn should prompt you for which SD-card you want to flash
the firmware to.
Then start the device with that SD card in it. Give it power and it
should turn on. If you have it connected with a data-cable it should
show up via USB networking which is convenient. It should be
announcing as nerves.local and have picked out one of your SSH public
keys to embed in the firmware by default. Try ssh nerves.local to see
if it is up. If not you may have to adapt a bit further and set up
WiFi.
If you have networking the next update is still a mix firmware to
compile but the deploy becomes:
shell
mix upload nerves.local
That's ridiculous.
You can also update specific modules by just pasting them over the
ssh connection into IEx which is surprisingly practical.
Set up Wi-Fi
Top of the generally debunked hierarchy of needs is of course Wi-Fi.
You can edit config/target.exs to edit the config for hardware
devices. host.exs is for running the project locally on your
computer.
The networking libraries for Nerves are known as VintageNet and we
can configure the VintageNetWiFi technology like this by replacing
the default "wlan0" entry:
elixir config/target.exs
{"wlan0",
%{
type: VintageNetWiFi,
vintage_net_wifi: %{
networks: [
%{
key_mgmt: :wpa_psk,
ssid: "my_network_ssid",
psk: "a_passphrase_or_psk",
}
]
},
ipv4: %{method: :dhcp},
}
}
Re-burn the SD-card and with a little bit of time your Pi should
connect to your wireless network. If you have one of the larger Pis
and an ethernet cable that also works great.
Nerves Livebook
If you are a bit lost on what to do and inspiration hasn't sparked
immediately you can instead get some neat tutorials going from Nerves
Livebook. There you get pre-baked firmware with special environment
variables for setting up Wi-Fi. Note that it starts a bit slowly,
especially on something like a Pi Zero. So be patient. Follow the
instructions linked because they are friendly and practical.
Going further with Phoenix
The Nerves documentation has a part about UI where we show how to do
a so-called Poncho project (less bad than an umbrella project, but
it's still raining). Redwire Labs published their approach which I
know others have also done and dubbed it naked Phoenix. I like this
approach so if you want to integrate Phoenix. Try it.
All just Elixir *
If you've dealt with your fair share of Mix projects and Elixir
applications Nerves is fairly straightforward because you are just
building an Elixir thing. Thing can get a little bit spicier if you
need some special dependencies but usually that's actually fairly
simple. Either the library pulls it in for you or you need to install
packages via buildroot. It is more involved than you might be used to
for apt. Pretty much a slightly old-school Docker image situation.
The nuisance is the build time and that's the flip side of building a
tiny dense BEAM-centric linux from scratch instead of shipping Ubuntu
and hoping for the best. I can tell you I've had more luck reviving a
Nerves-project 2 years down the line than I've had when I've hacked
together something on top of Raspberry Pi OS.
There are some things that have fancy deps that aren't possible to
cross-compile or aren't ready for it. But I've seen most of Membrane
compile without issue. I've installed SQL Cipher as an encrypted
alternative to SQLite. There's some nuance there but it is the same
that lives in your Dockerfile plus a bit of architectural nuance.
You also get some cool stuff you usually don't poke at on a server.
VintageNet for wrangling network interfaces. NervesTime for both
Real-Time Clocks, ntpd and so on. The Nerves heart variant of the
Erlang heart. A/B firmware partitions and firmware validation.
Things that are more fun on-device than on your average server is
stuff like connecting a camera and using evision. I've added a Coral
TPU over USB and had some fun via tflite_elixir.
Find some devices to talk to, you now have a little server that can
pull down your calendar, parse it and control things based on that,
or based on a public RSS feed you like. There are so many possible
things. I have hacked on my Elgato Keylights and my Elgato StreamDeck
.
And you can get incredible mileage out of OTP functionality like
GenServers and the binary pattern matching to do things with
hardware. You really get to do the stuff Erlang was made for.
More Nerves
Things to read further on:
* NervesHub Really fancy firmware updates, including binary delta
updates, for Nerves devices. Me, Josh and the Nerves team are
making them cooler by the day. Includes nerves_hub_link and
nerves_hub_cli.
* NervesKey Opinionated abstractions on top of hardware encryption
using the ATECC608-series from Microchip. This gives your device
an identity and I've been doing stuff with it.
* Mobius On-device metrics, I want to look into this one and try to
combine it with Explorer in some neat fashion.
* Scenic Not currently the liveliest project but it does allow you
to make UI all in Elixir and is used in production.
* Sensors & peripherals There are many devices supported to be used
directly from Elixir that you can pick up off of Adafruit or
Pimoroni and just have fun with. I've implemented the Inky eInk
display and the VCNL4040 ambient light and proximity sensor.
exit
That's it for now. Try Nerves and let me know if you run into things
that feel confusing or weird about Nerves and I'm happy to try and
clarify, improve and generally help you succeed with Nerves.
I am reachable on email lars@underjord.io and on the fedi @lawik.
Underjord is a 4 people team doing Elixir consulting and contract
work. If you like the writing you should really try the code. See our
services for more information.
Note: Or try the videos on the YouTube channel.
---------------------------------------------------------------------
---------------------------------------------------------------------
Newsletter
I share my thoughts on building software sustainably and effectively
in my newsletter.
No tracking. No cost. And a sample to read before signing up.
I try to respect my reader's time and attention. The sign-up may fail
if you have your adblocker on. Because reasons.
Email [ ]
[ ] I agree to be emailed for the purposes of this newsletter
[*] I refuse to have my email activity tracked
Subscribe
I use Campaign Monitor and do my best to strangle the
tracking-features out of it. The form does use an arbitrary bit of JS
for the sign-up that I know little about. I've set this up so you
will be flagged for no tracking. We are in the EU, work along the
GDPR and tracking user data is a liability that I prefer to avoid.
RSS
I have a feed for your newsreader right here.
[ ]
Magic enabled