Raspberry Pi & Embedded Linux

There's a threshold in embedded work where a microcontroller stops being the right tool: you need a filesystem, a TLS stack, a camera pipeline, a display framework, a database, or the ability to run Python or Node.js. Above that line you want a system-on-chip running Linux, and the Raspberry Pi is the most common way to get there — a cheap board with mature software, excellent documentation, and, in the Compute Module form, a genuine path to a commercial product.

What you gain is enormous: package managers, standard networking, containers, and every library ever written for Linux. What you give up is determinism, instant boot, and microamp sleep. A Pi boots in seconds, not microseconds, and its scheduler makes no timing promises. The other thing you gain — and this is where hobby projects and products diverge — is a filesystem that corrupts when you cut power to it, which is why almost everything below is about making a general-purpose OS behave like an appliance.

TL;DR

Quick Example

A production-shaped service: GPIO via libgpiod, graceful shutdown, and systemd supervision.

The systemd unit is doing as much work as the code: restart on crash, ordering after the network, a non-root user, memory limits, and filesystem isolation. On an appliance, that's the difference between a device that self-heals and one that needs a power cycle.

Choosing Hardware

For anything commercial, the Compute Module is the answer: it has a documented long-term availability commitment, onboard eMMC (far more reliable than an SD card), and a carrier board you design for your enclosure and connectors. Building a product around a standard Pi means designing around a board layout you don't control.

Alternatives worth knowing: BeagleBone (industrial heritage, PRU coprocessors for real-time I/O), NVIDIA Jetson (GPU-accelerated inference at the edge), Rockchip and Allwinner boards (cheaper, weaker software support), and i.MX 8 (the long-lifecycle industrial standard). Software maturity and supply commitments should weigh heavily — the Pi's advantage is as much ecosystem as silicon.

Core Concepts

Storage and power loss

⚠️ Warning: Cutting power to a Raspberry Pi with a writable ext4 root filesystem will eventually corrupt it. Not might — will, given enough cycles. This is the single most common cause of field failures in Pi-based products, and it is entirely preventable.

The fix is a read-only root with a writable overlay:

Beyond that: use eMMC or industrial-grade SD cards rather than consumer ones (which have far lower write endurance), move logs to tmpfs or ship them off-device, and add a supercapacitor or a small UPS if clean shutdown genuinely matters.

GPIO from userspace

libgpiod gives you line ownership (two processes can't fight over a pin), edge events without polling, and a stable API. Note that GPIO numbering differs between Pi 4 and Pi 5 chips — hardcoding gpiochip0 is a portability bug across models.

For buses, use the kernel drivers rather than bit-banging: /dev/i2c-1 for I²C, /dev/spidev0.0 for SPI, and /dev/ttyAMA0 or /dev/ttyS0 for serial. Enable them with device tree overlays in /boot/firmware/config.txt.

Boot and services

The device tree describes hardware the kernel can't discover — which pins are I²C, which SPI device is attached, which display is connected. Overlays in config.txt (dtoverlay=spi0-1cs) enable peripherals without recompiling anything, and they're how you configure a custom carrier board.

Boot time matters for appliances. Disabling unused services, using a minimal image, skipping the rainbow splash, and cutting the bootloader delay commonly brings a 25-second boot under 10. systemd-analyze blame shows where the time goes.

The watchdog

Linux can hang — a kernel deadlock, memory exhaustion, a driver fault. The hardware watchdog reboots the board when systemd stops petting it, and per-service WatchdogSec catches an application that's alive but stuck. On a device nobody can reach, both are mandatory rather than optional.

Production images

Raspberry Pi OS is Debian: convenient for development, and a poor production artifact because it's large, contains hundreds of packages you don't ship deliberately, and drifts as you configure it by hand.

The rule that matters more than the choice: the image must be reproducible from source control. A device image assembled by someone SSHing in and running apt install cannot be rebuilt, audited, or updated safely.

Real-time on Linux

Standard Linux gives no timing guarantees — the scheduler, page faults, and interrupt latency all introduce jitter measured in milliseconds. Options, in increasing order of effort:

The last is the most common architecture in real products, and the most robust: Linux does connectivity, UI, and application logic; the MCU does anything with a deadline. It's also how you get a device that keeps controlling hardware safely while Linux reboots.

Best Practices

Make the root filesystem read-only

This one change eliminates the most common field failure mode. Keep persistent data on a separate small partition, and mount it with sync or use a journaled filesystem tolerant of power loss.

Never run the application as root

A compromised service running as root owns the device and, from there, the network it's on. Create a dedicated user, grant only the group membership needed for GPIO or serial access, and use systemd's hardening options.

Build images reproducibly

Yocto, Buildroot, or a scripted image build in CI. Manual configuration is unreproducible, unauditable, and impossible to update reliably across a fleet. This is the difference between a prototype and a product.

Design for OTA before shipping

Dual-partition A/B root filesystems with atomic switching and rollback — RAUC, SWUpdate, Mender, or OSTree. The principles are identical to MCU firmware updates, at a hundred times the image size.

Enable both watchdogs

Hardware watchdog for a hung kernel, systemd WatchdogSec for a hung application. A device that reboots itself out of a bad state is worth vastly more than one that requires a site visit.

Manage logs deliberately

Unbounded journald logs fill the disk and wear out the storage. Cap the journal size, use Storage=volatile on a read-only root, and ship logs off-device where you need them. See Log Aggregation.

Set a static or reserved network configuration

DHCP failures on a device with no screen are hard to diagnose. Use a static address or a DHCP reservation, add mDNS for discovery, and always provide a serial console fallback for field debugging.

Pin every version

Kernel, packages, container images, and application dependencies. apt upgrade on a deployed fleet is how identical devices become subtly different — and how a working device stops working overnight.

Common Mistakes

A writable root filesystem in the field

Using the deprecated sysfs GPIO interface

Running everything as root

Hand-configuring the production image

Expecting real-time behavior

No watchdog

FAQ

Raspberry Pi or a microcontroller?

Pi when you need a filesystem, a network stack with TLS, a display or camera pipeline, a database, or high-level languages. MCU when you need battery operation, deterministic timing, instant boot, or a unit cost under a few dollars. The split is stark: a Pi Zero draws roughly 100 mA idle where an ESP32 draws 10 µA asleep, which is four orders of magnitude. Many products use both.

Is a Raspberry Pi suitable for commercial products?

Yes, with the Compute Module and production discipline: read-only root, reproducible images, OTA, watchdogs, and industrial-grade storage. The CM has documented availability commitments, which is the thing that actually determines whether you can ship a product for years. The standard boards are development tools and low-volume solutions rather than product platforms.

SD card or eMMC?

eMMC for anything deployed. Consumer SD cards have limited write endurance and fail unpredictably; the Compute Module's eMMC option is far more reliable and not much more expensive. If SD is unavoidable, use an industrial-grade card rated for the write cycles you'll actually generate, and reduce writes with a read-only root.

Should I use containers on an embedded Linux device?

They help with dependency isolation, atomic application updates, and matching development to production — balena and Mender build their platforms around this. The costs are image size, memory overhead, and complexity that a single-application appliance may not need. A container per application on a device running two services is often more machinery than value; on a device running an application stack, it's usually worth it. See Docker.

How do I get low latency or real-time behavior?

In order of effort: real-time scheduling priority plus mlockall, then a PREEMPT_RT kernel, then isolated CPU cores, then a companion microcontroller. PREEMPT_RT gets you to tens of microseconds of worst-case latency, which covers most control loops. For hard guarantees — motor commutation, safety interlocks — put it on an MCU and treat Linux as the supervisor.

How do I secure a Linux IoT device?

The same fundamentals as a server plus the physical-access threat model: verified boot with signed kernel and initramfs, dm-verity on a read-only root, encrypted data partitions with hardware-backed keys, no default passwords, SSH key-only or disabled entirely, a minimal package set, unattended security updates or a controlled OTA path, and a disabled serial console in production. A Pi with a default password on a home network is a botnet node waiting to happen.

Related Topics

References