Firmware that is built to last
Embedded software runs inside devices with tight limits on memory, processing power and energy, often for many years without anyone touching it. It has to start reliably, recover from errors on its own and keep working when sensors fail or connections drop.
We write firmware for microcontrollers such as ESP32, STM32 and Nordic nRF series, using bare-metal code, FreeRTOS or Zephyr, and application software for embedded Linux on Raspberry Pi, NXP i.MX and similar platforms built with Yocto or Buildroot.
Problems we solve
- Firmware that only one engineer understands
- Devices that hang and need a manual reset in the field
- Batteries draining far faster than the specification
- No automated tests, so every change risks breaking something
- Firmware updates that can brick devices if power is lost
What’s included
Microcontroller firmware
C, C++ and Rust on ARM Cortex-M, ESP32 and nRF platforms.
RTOS development
FreeRTOS and Zephyr tasks, timing and memory management.
Embedded Linux
Yocto or Buildroot images, services and secure boot.
Drivers & protocols
Sensors, displays and buses: I2C, SPI, UART, CAN, Modbus.
Low-power design
Sleep modes and duty cycling to extend battery life.
Bootloaders & OTA
Dual-bank updates with signature checks and rollback.
Our engineering practices
- Hardware abstraction layers so business logic can be tested on a PC
- Unit tests and hardware-in-the-loop tests in continuous integration
- Static analysis and coding standards such as MISRA C where appropriate
- Watchdogs, brown-out handling and structured error logging
- Reproducible builds and version-tagged releases
-
Board bring-up1–3 weeks
Clocks, peripherals, power and debug interfaces working on your hardware.
-
Core firmware4–12 weeks
Drivers, application logic, connectivity and power management.
-
Validation2–6 weeks
Environmental, power, long-duration and update testing.
-
Production supportOngoing
Manufacturing test firmware, provisioning and field updates.
Choosing the right platform
| Platform | Strengths | Typical use |
|---|---|---|
| Bare-metal MCU | Lowest power and cost, deterministic | Simple sensors and controllers |
| RTOS (FreeRTOS, Zephyr) | Multitasking with small footprint | Connected devices with several concurrent jobs |
| Embedded Linux | Rich networking, UI and software ecosystem | Gateways, HMIs, devices with displays or cameras |
Rust is increasingly attractive for new embedded projects because it prevents whole classes of memory bugs at compile time. We recommend it where toolchain support for your microcontroller is mature, and C or C++ where existing code, certified libraries or team skills make them the safer choice.
Timeline and budget
| Scope | Typical timeline | Typical budget (USD) |
|---|---|---|
| Firmware for a simple sensor device | 6–10 weeks | $20k – $50k |
| Complex connected device or embedded Linux product | 3–8 months | $60k – $200k |
Typical ranges to help you plan. Your written estimate comes after a free discovery call.
Taking over existing firmware
Many projects start with firmware written by a former employee or contractor, with little documentation and no tests. Rewriting from scratch is rarely the best first step. We usually begin with a short audit and then stabilise the code base step by step:
-
Audit1–2 weeks
Build the code reproducibly, map modules, identify risks and document how the device works.
-
Safety net2–4 weeks
Add logging, watchdogs and tests around the most critical behaviour.
-
Fix & refactorOngoing
Fix field issues and refactor the riskiest modules behind the new tests.
-
Update path2–4 weeks
Introduce or repair a safe over-the-air update mechanism.
Once there is a safe update path and a test harness, the firmware can be improved continuously instead of being frozen out of fear of breaking devices in the field.
What embedded projects usually involve
Embedded work rarely starts from a blank page. Most projects begin with a hardware design that is already partly decided, a component shortlist shaped by cost and supply, and a deadline tied to a manufacturing run. The firmware has to fit that reality: limited flash and RAM, a specific microcontroller family, power budgets measured in microamps and peripherals that behave slightly differently from their datasheets.
A typical scope covers board bring-up and drivers, the application logic, communication stacks (Bluetooth Low Energy, Wi-Fi, LTE-M, LoRaWAN or wired buses such as CAN, Modbus and RS-485), power management, secure boot and over-the-air updates, and the manufacturing test firmware used on the production line. Each of these is a distinct piece of work with its own risks, and we estimate them separately so you can see where effort goes.
Bare metal, RTOS or embedded Linux?
| Approach | Strengths | Trade-offs | Typical use |
|---|---|---|---|
| Bare metal (super-loop) | Smallest footprint, fully predictable | Gets hard to manage as features grow | Simple sensors, very low-cost devices |
| RTOS (Zephyr, FreeRTOS) | Tasks, timing guarantees, mature networking stacks | More memory; needs discipline with concurrency | Connected devices, wearables, controllers |
| Embedded Linux (Yocto, Buildroot) | Full networking, file systems, rich libraries | Higher power and cost; longer boot; larger attack surface | Gateways, HMIs, camera and edge AI devices |
A rule of thumb rather than a strict boundary — some products combine a Linux processor with a microcontroller for real-time tasks.
We recommend the simplest option that comfortably meets today’s requirements and the features on your roadmap. Moving from bare metal to an RTOS mid-project is expensive, so we look at the two-year feature list before deciding.
From prototype to production
-
Requirements & hardware review1–2 weeks
Confirm features, power budget, connectivity and update strategy; review schematics for firmware-relevant issues before boards are ordered.
-
Board bring-up1–3 weeks
Clocks, pins, drivers and a test harness proving each peripheral works on real boards.
-
Feature developmentIterative
Application logic and communication stacks in short iterations, tested on hardware-in-the-loop rigs.
-
Security & updates
Secure boot, signed images, key storage and a recoverable over-the-air update path.
-
Manufacturing support
Production test firmware, device provisioning and documentation for the factory.
Hardware revisions are normal. We keep a hardware abstraction layer so a new board revision or a substituted component changes a driver, not the whole application.
Testing firmware without guesswork
- Unit tests on the host for logic that does not touch hardware, run on every commit.
- Hardware-in-the-loop rigs that power-cycle devices, inject sensor values and check outputs automatically.
- Long-running soak tests to expose memory leaks, watchdog resets and timing drift that only appear after days.
- Power profiling with a current analyser to confirm battery-life estimates in each operating mode.
- Update and rollback tests, including interrupted downloads and power loss mid-update.
Pitfalls we help you avoid
- No way to update firmware once devices are in the field
- Debug ports left open on production units
- Shared default credentials or keys across every device
- Battery estimates based on datasheet figures rather than measured current
- Component end-of-life notices discovered after launch
- Firmware that only one engineer understands, with no documentation or tests
Embedded firmware is one part of a connected product. See IoT & embedded development for the full picture, including the companion apps and cloud platform.
Documentation you receive
- Architecture overview and module responsibilities
- Build, flash and debugging instructions for new engineers
- Memory and power budgets with measured figures
- Update and provisioning procedures for manufacturing and the field
Related services
Part of our IoT & embedded development services. Pair it with IoT apps and manufacturing software.
This page is part of IoT & Embedded Development Services — see the full overview for related services, approach and pricing.