17 posts tagged elixir, newest first.
Certificates and mTLS are the easy part. The hard part is identity over a device's whole life: first enrolment, rotation, power loss mid-rotation, and a gateway that was offline for two years.
Scenes, graphs, components and drivers on an STM32MP157F-DK2 — then the four gotchas that compile cleanly and fail on the device: the required assets module, the child spec that is a plain list, the missing input: style that made every button inert, and text_align: :center not working.
An afternoon spent finding where a Nerves target's Erlang version is really decided — and discovering it is encoded in the filename of a patch inside a dependency I had never opened. Plus the Kconfig default that will silently move you to OTP 29 the moment you bump.
Between an Elixir process and a lit pixel on the DK2 there is an LTDC, a MIPI DSI host, an OTM8009A panel and a Goodix touch controller. I spent a day preparing to enable the Vivante GC NanoUltra, then read scenic_driver_local's source and found it renders in software to /dev/fb0.
An hour spent trying to open a window that was never going to be drawn, then the realisation that a Scenic graph is just data. Walking it and rendering to SVG found two layout bugs in a minute that had survived 49 tests and a review.
Counting down by subtracting the tick interval drifts on an embedded board. Deriving the remaining time from a monotonic deadline instead makes it drift-free by construction — and injecting the clock turns a 25-minute test into a map update. It also caught a real race.
I built this blog to parse every post at compile time, wrote up why it was the right call, and then reversed it three weeks later. Both of my premises were false. Here is what replaced it, and how it keeps every property the compile-time version actually earned.
Four packaging bugs between a Nerves system that builds and a firmware that flashes — plus the kconfig hang that looks exactly like a working build.
Why I wrote a custom Nerves base image file by file for a CompuLab IOT-DIN-IMX8PLUS instead of forking a sibling board's system.
Before I show you the first build attempt (and its failures), I need to clear up something that confused me at first.
On a desktop PC, when you plug in a USB device or install a PCI graphics card, the operating system discovers it automatically. PCI has enumeration.
I've been using Nerves for years, and for most of that time the boot process was a black box. Plug in power, wait a few seconds, get an IEx prompt. Magic.
I've been using Nerves for a while now. Raspberry Pi, BeagleBone — the usual suspects. You pull in the official system, write your Elixir code, burn firmware,…
The signed Nerves firmware boots. And a finding that deleted an open task: enabling CONFIG_IMX_HAB wires an automatic fail-closed authentication gate into booti itself, for every kernel boot, with no bootcmd changes at all. Plus a fleet gotcha about who can SSH in.
Wiring signing into the build, and a correction worth more than the wiring: I planned to point fwup.conf at signed artifacts, and that was the wrong layer entirely — the signed bootloader is not in the .fw file at all.
Three real bugs blocked the first three attempts: a nerves package version whose error message points nowhere near the cause, a missing .tool-versions, and the same SPL SRAM overflow track A hit. Plus the arm64 header field that is at offset 0x10, not 0x4.
The first series proved HAB secure boot on a disposable lab unit running stock Linux. This one carries it into a real Nerves system — in a fork, so the build that runs in the field is never at risk. Same board, different starting point, and several things that do not transfer.