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
- Use an MPU when you need an OS: filesystems, networking stacks, displays, cameras, or high-level languages.
- Compute Module is the production form factor; the standard board is for development and low volume.
- Power loss corrupts filesystems. A read-only root with a small writable overlay is the standard fix.
- Use libgpiod, not
/sys/class/gpio(deprecated) and not direct register access. - systemd manages your application: restart on failure, dependency ordering, resource limits.
- Enable the hardware watchdog — Linux can hang, and nobody is there to reboot it.
- Yocto or Buildroot for production images; Raspberry Pi OS is a development convenience.
- Linux is not real-time. Use
PREEMPT_RT, isolated cores, or a companion MCU for hard timing.
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:
chrt -f 80andmlockall()to get real-time priority and avoid paging — reduces jitter, doesn't bound it.PREEMPT_RTkernel — bounded latencies in the tens of microseconds, enough for most control loops.- Isolated cores (
isolcpus) with a dedicated thread — removes scheduler interference. - A companion MCU — an RP2040 or ESP32 handles the hard real-time work and talks to Linux over SPI or UART.
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
- Microcontrollers — The other side of the MCU/MPU decision
- Linux — The operating system underneath
- IoT Security — Hardening a device an attacker can hold
- OTA Firmware Updates — A/B rootfs updates and rollback
- ESP32 — A common companion MCU
- MQTT — Talking to a fleet backend
- Docker — Containers on embedded Linux
- Edge Computing — Running workloads on-device
- Command Line — The interface you'll live in