embedUR

Taking a Zephyr Device to Production: Managing the Realities of Scale

Taking a Zephyr Device to Production: Managing the Realities of Scale

Taking a Zephyr Device to Production: Managing the Realities of Scale

Prototyping on an evaluation kit is an understood process. Silicon vendors provide great documentation, and getting an out-of-the-box development board to read an environmental sensor over I2C is usually just an afternoon’s work. The primary engineering friction does not happen at your desk; it emerges when you stop building a single device and start trying to deploy a production fleet.

When you scale a hardware product, the engineering challenges change at every order of magnitude. What works fine for 10 units on a test bench often becomes incredibly fragile at 100. By the time you hit 1,000 units, small inefficiencies start hitting your balance sheet, and at 10,000 units, minor edge-case software bugs become daily field failures.   

Zephyr RTOS provides an excellent foundation for managing this transition, especially if you are working in connected or multi-platform environments. But Zephyr itself is highly complex, and achieving long-term field reliability requires designing your firmware around the entire product lifecycle from day one. Doing that successfully means understanding the exact trade-offs, configuration traps, and architectural shifts you will face at every stage of growth.

This always  inadvertently brings on the crucial Buy vs Build Decision for engineering leadership when it comes to RTOS, so, give us a read when you’re done.

Phase 1: Hardware Abstraction and Board Porting (1 – 10 Units)

The first step in designing a production-grade device is separating your application logic from the evaluation hardware. A common pitfall for development teams is writing their software directly inside a vendor-supplied sample project. This creates immediate technical debt, tying your application code directly to specific, non-portable silicon features.

A clean Zephyr workflow relies on the Devicetree (DT) and Kconfig systems to decouple your software from the physical silicon. This structure minimizes how much hardware change propagates up into your application layer, allowing your core features to remain stable even when the underlying platform shifts.

To do this right, you need a disciplined approach to your early-stage architecture:

i) Maintain Out-of-Tree Board Directories

Avoid modifying the default Zephyr source tree directly. Keep your custom board definitions, pin-mux configurations, and base Devicetree files entirely in an independent, version-controlled repository. By setting your ZEPHYR_EXTRA_MODULES CMake variable, you can pull your hardware definitions in cleanly at build time, keeping your codebase isolated and making future RTOS LTS migrations significantly less painful.

ii) Isolate Hardware Variations with Overlays

Use .overlay files to manage minor hardware variations or alternative component choices without altering your core application logic. For instance, changing an I2C temperature sensor from an internal pull-up configuration to an external hardware pull-up should only require changing a single bias-pull-up; property in your overlay, leaving your main code completely untouched.

iii) Utilize In-Tree Shells for Hardware Bring-Up

Zephyr includes native console shells for I2C, SPI, and GPIO. By enabling CONFIG_I2C_SHELL=y or CONFIG_GPIO_SHELL=y during initial hardware bring-up, you can use an interactive CLI over a debug console to poll physical registers, trigger pin logic, and validate physical bus health before you ever write a single line of your actual peripheral driver.

While this separation reduces the amount of application logic that needs to change when components shift, it is not a silver bullet. If you have to make a major microcontroller swap—like moving from an STM32 to an NXP i.MX RT because of supply chain issues—you are still going to face serious engineering friction. 

You will have to reconcile vendor HAL differences, manage vastly different clock trees, configure complex linker scripts for altered internal RAM configurations, and re-map your power states. What Devicetree actually does is isolate that friction to the hardware description layer, preventing a local hardware change from forcing a ground-up rewrite of your software architecture.

Phase 2: Secure Bootloaders and Remote Debugging (10 – 100 Units)

Moving from a handful of development boards to a pilot run of 100 units usually means placing your electronics inside a custom enclosure. The moment that housing is sealed, physical access changes completely. Your dedicated debugging pins disappear, meaning you can no longer simply attach a J-Link debugger to see why a device froze mid-operation.

At this point, you have to realize that your firmware update system is not just an isolated software feature. It actively shapes your memory architecture, your storage layout, and the overall operational behavior of your platform.

i) Establish Alternative Logging Backends

Physical UART ports consume valuable pins and power budgets. Zephyr allows you to route logs away from UART to Segger Real-Time Transfer (RTT) via CONFIG_LOG_BACKEND_RTT=y during lab optimization. 

For enclosed production units, you can redirect those logs to internal RAM circular buffers via CONFIG_LOG_BACKEND_RAM=y, preserving trace statements that can survive soft crashes and be extracted later via your diagnostic interfaces.

ii) Harden MCUboot Production Keys Early

Teams frequently make the mistake of leaving the default, publicly accessible development keys (root-rsa-2048.pem) active in their repository during pilot runs. A secure workflow requires generating private cryptographic signing keys using imgtool and establishing an automated build pipeline that injects the public key into the bootloader while keeping the private key locked down in a secure CI/CD environment.

iii) Configure Asymmetric Dual-Slot Upgrades

Your flash memory layouts must be carefully budgeted for rollback protection. By choosing a dual-slot flash layout over a single-slot configuration, you trade away half of your available internal flash space, but you gain an ironclad safety net. 

If an over-the-air (OTA) update fails its image signature verification, encounters a hardware glitch during flash layout swaps, or fails to call boot_write_img_confirmed() within a specified window on its first boot, MCUboot will automatically swap the active partition back to the previous working slot. This prevents a bad update from rendering your pilot units completely unrecoverable in the field.

Phase 3: Optimizing Power, Payloads, and Unit Economics (100 – 1000 Units)

At 1,000 units, firmware efficiency transitions from an optimization preference to a direct operational cost. If your devices run on batteries or communicate over cellular networks, inefficient resource management will actively impact both your battery lifecycle metrics and your recurring data fees.

i) Implement Active Power Management

Relying on manual sleep loops or basic delay functions often leaves internal peripherals active. You need to dive into Zephyr’s native device runtime power management framework (CONFIG_PM_DEVICE_RUNTIME=y). 

When configured correctly, the operating system coordinates peripheral clock gating, manages internal flash low-power states, and drops the core MCU into designated sleep modes whenever your software threads enter an idle state. 

However, implementing this requires deep driver-level integrity. Your custom drivers must explicitly implement the pm_device_action_cb_t callback. If a single custom SPI peripheral driver fails to release its clock lock when it goes idle, the entire SoC may be prevented from entering its deep sleep state, quietly draining milliamp-hours from your batteries out in the field.

ii) Optimize Payloads for Bandwidth Constraints

JSON payloads are text-heavy and increasingly expensive in bandwidth-constrained or cellular deployments. They require more packets, which extends transmission time and increases power consumption. 

Utilizing binary serialization formats like CBOR (Concise Binary Object Representation) via Zephyr’s built-in zcbor library, or Protocol Buffers (protobuf), maps your data directly to packed C structures. 

Compressing a 250-byte JSON telemetry payload into a 45-byte CBOR binary stream directly slashes your network overhead, turning cellular usage into a manageable, predictable line item.

iii) Enforce Unified Revision Management

Hardware engineering is iterative, and deployments at this scale often involve managing multiple physical PCB revisions simultaneously. Zephyr’s board revision subsystem helps you handle this diversity without forcing you to split your codebase. 

By exposing a set of hardware ID pins using a simple resistor strap network read via GPIO or an ADC channel at boot, a single compiled firmware binary can query the hardware variant. 

Zephyr can then dynamically route pins or adjust driver behavior at boot time using conditional initialization logic, ensuring your software team doesn’t end up maintaining three parallel code repositories for three minor PCB tweaks.

Phase 4: Fleet Resilience and Remote Diagnostics (10,000+ Units)

When a deployment scales past 10,000 devices, human intervention becomes highly difficult. You can no longer think about or manage individual units; you have to look at patterns and manage the fleet by tracking statistical exceptions and anomalies. A firmware edge case that occurs only once every few thousand hours of runtime transitions from a rare event into a daily operational problem.

i) Decouple Configuration via the Settings Subsystem

Hard-coding your runtime variables is a massive liability at this stage. Zephyr’s native settings subsystem (CONFIG_SETTINGS=y) provides a structured key-value store backed by flash filesystems like NVS (Non-Volatile Storage) or LittleFS. 

This allows you to adjust operational thresholds, cellular APNs, or sensor calibration values via remote commands without risk of data corruption during sudden power drops, completely avoiding the need to deploy a risky full firmware update just to change a variable.

ii) Design Thread-Aware Subsystem Recovery

Simple watchdog resets that simply cycle the entire processor are sometimes insufficient for large, complex deployments. If an I2C bus experiences a noise spike and locks up due to a missing clock pulse, forcing a hard reset of the entire chip might disrupt a critical monitoring loop. By configuring Zephyr’s hardware watchdog API (CONFIG_WATCHDOG=y) to monitor individual, critical software threads via fallback task loops, you can isolate failures. 

If a cellular communication thread freezes, the watchdog handler can catch the specific thread timeout, execute a localized hardware pin-reset on the cellular modem, and re-initialize the network stack while your primary application logic continues running completely uninterrupted.

iii) Automate Coredumps for Remote Diagnostics

When an unrecoverable kernel panic does happen, debugging becomes significantly slower and less deterministic without real runtime visibility. Zephyr’s coredump subsystem (CONFIG_COREDUMP=y) can be configured to capture a snapshot of the CPU registers, stack pointers, and active memory blocks to an internal flash partition the exact microsecond a crash occurs. 

Upon a safe recovery boot, the system can offload this hex payload to your cloud backend. Your engineering team can then process the binary against an unstripped ELF binary map, outputting a precise GDB stack trace that shows your developers the exact line of C code that caused the failure.

Bridging the Production Gap: Why Infrastructure Matters

The customer-facing features of your product represent only a small portion of the actual engineering required for a long-term production deployment. True platform maturity lives entirely within the unglamorous infrastructure layers: the bootloaders, the memory domains, the power state machines, and the automated validation toolchains.

The difficult part of long-term sustainment is maintaining predictability while the platform keeps changing underneath your product. Engineering groups are often highly effective at product innovation, but navigating the nuances of Devicetree constraints, managing data cache alignment on high-performance MCUs, or debugging complex thread interactions can introduce severe schedule slippage. This friction point represents a distinct execution gap, and managing it carefully is critical to moving smoothly from a validated bench prototype to a reliable commercial asset as shown in our related post – Mastering the Zephyr Perimeter.

High-performing organizations address this complexity by recognizing that no single team can easily master every layer of a modern embedded ecosystem. Instead of stretching application developers thin across low-level infrastructure tasks, they separate development concerns. Internal teams remain focused on product-level value and customer requirements, while they leverage external embedded expertise to build, optimize, and maintain the underlying firmware foundation.

This is where teams often bring in embedUR. We function as an extension of your engineering group, resolving the complex hardware-software interactions that can stall commercial deployments, and providing the architectural depth required to move a device from the lab to the field with confidence.

Our Areas of Focus:

a) Custom Board Porting: We build clean, out-of-tree Board Support Packages (BSPs) and driver architectures tailored to your hardware, ensuring smooth future RTOS migration paths.

b) Performance Optimization: We configure advanced MCU features, optimize memory caches, and implement Zero-Latency Interrupts (ZLI) to guarantee deterministic performance.

c) Production Infrastructure: We design secure MCUboot setups, establish robust factory provisioning pipelines, and build automated hardware-in-the-loop (HIL) testing rigs.

Transitioning to a production-grade Zephyr architecture involves navigating real design trade-offs and operational complexities. By enforcing clear structural discipline early in development and collaborating with expert embedded partners to handle low-level infrastructure challenges, you can deliver an embedded product that is secure, predictable, and built to scale.

If low-level platform work is slowing product development, explore embedUR’s Zephyr engineering services or contact us to discuss your platform requirements.