Embedded software development – the engineering discipline that produces firmware and low-level software for microcontrollers and connected hardware products – is the layer that determines whether a hardware product performs reliably in the field or accumulates defects from the first production run. This guide is written for hardware startup founders, engineering managers and product owners evaluating embedded software development for the first time or selecting a partner to take on firmware work alongside an electronics design engagement. It covers the development process, key decisions, testing approaches and what to look for in a competent embedded software team.
TL;DR
- Embedded software development covers firmware architecture, peripheral driver development, RTOS integration, application logic, OTA update design and firmware testing – all running on resource-constrained hardware.
- Starting firmware development in parallel with hardware design is the single biggest factor in keeping embedded projects on schedule and reducing integration defects.
- RTOS selection is an early, high-stakes decision. Migrating from bare-metal to RTOS mid-project is disruptive. Choose based on your product’s concurrency and timing requirements, not convention.
- Firmware testing must happen on real hardware. Test frameworks that run on a host PC validate logic; they cannot validate timing, interrupt behaviour, or peripheral interactions on your specific PCB.
- The deliverables of an embedded software engagement should include firmware architecture documentation, test specifications, and a hardware bring-up protocol – not just source code.
- Zeus Design develops embedded software as part of an integrated electronics design engagement, so firmware and hardware decisions are co-owned by the same team from day one.
Why Hardware Teams Underestimate Embedded Software
Most hardware product companies underestimate embedded software development. Not because they are naive about technology – founders who have built physical products before understand that firmware is real work. The underestimation usually happens in scoping: treating firmware as something that starts after the hardware design is complete, sizing it as a small fraction of the electronics design effort, or assuming that an experienced web or mobile developer can pick it up with a short learning curve.
Each of these assumptions carries risk. Embedded development is constrained in ways that general software is not. Memory is measured in kilobytes, not gigabytes. Processing time is measured in clock cycles. Timing constraints are real and bounded – not aspirational. Debugging tools are more limited. And because embedded firmware runs on hardware that may still be changing, the development environment itself is unstable in ways that server-side or app development is not.
Hardware founders and product managers who understand what embedded software development actually involves are better positioned to scope engagements honestly, evaluate partner capability accurately, and avoid the most common mid-project surprises.
What Embedded Software Development Includes
The scope of an embedded software engagement for a typical connected hardware product covers five distinct areas:
Firmware Architecture
The first decision is whether the firmware runs bare-metal – a super-loop with interrupt service routines – or under a real-time operating system (RTOS). Bare-metal is appropriate for simple, single-function devices with predictable timing and limited peripheral complexity. RTOS-based designs are the right choice when the product needs to manage multiple concurrent tasks: polling sensors, managing a wireless connection, handling user input, and managing power modes simultaneously.
Common RTOS choices for resource-constrained microcontrollers include FreeRTOS – open-source and widely supported across MCU families – Zephyr (backed by the Linux Foundation), and Azure RTOS ThreadX. Each has different licensing, hardware support coverage, and community characteristics. The architecture decision should be made at the start of the project, not halfway through development.
Hardware Abstraction Layer
A well-designed hardware abstraction layer (HAL) separates hardware-specific peripheral code from the application logic above it. Instead of the application layer directly manipulating microcontroller registers, it calls a standardised API. The HAL handles the hardware details; application code stays portable.
This matters practically when supply chain constraints force a microcontroller substitution – a scenario that became common in 2022-2025 and has not disappeared. With a well-designed HAL, only the HAL implementation needs to change. Without one, substitution may require reworking the entire firmware codebase. For products with multi-year production lifespans or planned hardware variants, HAL design is not optional.
Peripheral Driver Development
Every peripheral requires a driver: initialisation, configuration, and data transfer handling. Wireless modules (Wi-Fi, Bluetooth, cellular, LPWAN), sensors (temperature, pressure, accelerometers, IMUs), power management ICs, displays, storage, and communication buses (I2C, SPI, UART, CAN, USB) all need production-quality driver implementations.
Vendor-supplied reference drivers are a starting point, not a finished implementation. They are written for evaluation boards under ideal conditions. Production drivers need adaptation for your specific hardware configuration, thermal operating range, error recovery conditions, and reliability requirements. Driver quality is a direct contributor to field failure rates.
Application Logic and State Management
Above the RTOS and drivers sits the application layer: the business logic that defines what the product actually does. For connected products, this typically includes sensor data processing, communication protocol handling, power state management, user interface logic, configuration management, and error recovery.
State machine design – how the device transitions between operating states and handles edge cases – is where firmware accumulates the most technical debt if not designed carefully from the start. A state machine that starts simple tends to grow as features are added, field feedback arrives, and edge cases surface. Designing clean transitions and explicit error handling up front is one of the more durable investments an experienced firmware team makes early in a project.
OTA Firmware Updates
Any connected device shipped at scale needs over-the-air (OTA) firmware update capability. A robust OTA implementation uses a dual-bank or A/B update scheme, verifies firmware integrity before committing a new image, and provides rollback capability for interrupted or failed updates. This is not complex firmware to write, but it requires deliberate design from the start. OTA designed as an afterthought typically requires reworking the flash memory layout, bootloader, and update state machine – all of which affect other parts of the firmware.

Key Development Decisions
RTOS vs. Bare-Metal
The RTOS decision is the highest-stakes early choice in embedded software development. An RTOS adds code size, scheduling overhead, and architectural complexity. It also makes concurrent task management tractable as the product’s feature set grows. The right choice depends on:
- How many concurrent activities the firmware must manage simultaneously
- Whether any activities have hard real-time deadlines that cannot be missed
- How much flash and RAM the target microcontroller provides
- The likely feature roadmap over the product’s commercial lifetime
A detailed technical comparison of RTOS and bare-metal architectures – covering scheduling models, priority inversion, and deadline analysis – is available from the ACL Digital embedded architecture guide. As a practical rule: if there is any doubt about whether bare-metal will handle the concurrency requirements, default to RTOS. Migrating from bare-metal to RTOS mid-project is possible but disruptive.
Microcontroller Selection
Firmware architecture is constrained by the microcontroller. Clock speed, RAM, flash, peripheral set, and the quality of vendor SDK and community support all affect what is practical to implement. Microcontroller selection happens in the electronics design phase, but it should involve the firmware team. A component that is easier to route on the PCB may be significantly harder to write reliable firmware for – or may lack the peripheral set the firmware needs. Firmware requirements should be an input to component selection, not an afterthought.
The ARM Developer documentation covers the Cortex-M architecture series, which underpins the majority of microcontrollers used in connected hardware products today.
Security Requirements
Security-by-design is increasingly mandatory for connected products. The EU Cyber Resilience Act, effective from 2027, requires secure boot, authenticated OTA firmware updates, and documented vulnerability management for connected products sold in Europe. At the firmware level, this means cryptographic integrity verification in the bootloader, encrypted update channels, secure credential storage, and a minimal network attack surface.
The OWASP Firmware Security Testing Methodology provides a practical framework for evaluating firmware security posture across the full stack. Treating security as a firmware architecture requirement from the start is far less expensive than retrofitting it after product launch.
The Embedded Software Development Workflow
A structured embedded software development engagement for a connected hardware product follows this sequence:
Architecture Definition
The firmware team reviews the hardware architecture, component datasheets, and product requirements before writing any code. Firmware architecture, RTOS selection, HAL design, and peripheral driver scope are defined. A firmware architecture document is produced. This phase is most effective when it overlaps with electronics design – so hardware decisions can be informed by firmware constraints and vice versa.
Parallel Development with Electronics Design
Firmware development begins while electronics design and PCB layout are in progress. Peripheral drivers are developed and validated against vendor evaluation kits or development boards. Application logic and state machines are implemented and tested in simulation. This parallel-track approach is the most important structural decision in an embedded software engagement. Waiting for first prototype hardware before starting firmware development wastes hardware iteration cycles and extends the schedule by weeks or months. See the Zeus Design guide on electronics design from concept to production for more on how these phases interact.
Hardware Bring-Up
When first-article prototype boards arrive, firmware is loaded and hardware functionality is validated systematically: power rails, clocks, communication buses, peripheral interfaces. Hardware bring-up reveals hardware bugs – some require PCB respins, others can be worked around in firmware. An experienced firmware team distinguishes between the two quickly, which reduces the number of hardware iterations needed before the design stabilises.
Integration and System Testing
With hardware validated, integration testing begins. Communication protocols between firmware and cloud backend are exercised. Mobile app connectivity is tested against real firmware. Sensor calibration, power budget measurements, and reliability testing happen at this stage. This is also when OTA update flows are validated end-to-end on real devices.
Production Firmware Preparation
Final firmware preparation for production includes stripping debug builds, setting production device credentials and certificates, configuring factory test modes, and preparing the OTA update infrastructure for the first production release. Production firmware is a distinct deliverable from development firmware – it requires its own validation pass.
Testing Embedded Firmware
Embedded firmware testing is harder than general software testing for a specific reason: the most important bugs are hardware-dependent. Test frameworks that run on a host PC – such as Unity or CppUTest – can validate firmware logic, state machine transitions, and protocol handling in isolation. They cannot validate timing behaviour on a specific microcontroller, interrupt latency on a specific PCB, or the behaviour of a peripheral driver against real silicon.
A practical embedded testing approach combines several layers:
- Unit testing on host – logic validation without hardware dependency. Most valuable for state machine, protocol, and data processing layers. Runs fast and catches regressions early in development.
- Hardware-in-the-loop (HIL) testing – firmware runs on real hardware and a test harness drives inputs and validates outputs. Catches hardware-dependent bugs that host-based tests miss entirely. This layer is not optional for production-quality firmware.
- Boundary condition testing – stress testing peripheral behaviour at the edges of specified operating conditions: low supply voltage, maximum data rates, worst-case operating temperature, and simultaneous peripheral activity.
- OTA update failure injection – deliberate interruption during OTA updates (power loss mid-flash, connectivity drop, partial write) to validate that rollback and recovery work correctly on real devices.
- Long-run soak testing – running devices continuously for days or weeks to surface intermittent timing issues, memory leaks, stack overflows, and peripheral hang conditions that do not appear in short-run tests.
Further reading on modern embedded testing approaches and firmware development best practices is available from Dojo Five’s embedded firmware guide, which covers test-driven development applied to embedded systems in practical detail.
An embedded software engagement that delivers only source code without test specifications and hardware-validated test results is delivering a partial product. The test plan should document what was tested, how it was tested, and against what pass/fail criteria – so production operations teams know what the firmware has been validated to do.
Common Mistakes to Avoid
Starting Firmware After Hardware Is Done
The most expensive embedded software mistake is treating firmware as a post-hardware activity. Every hardware iteration cycle wasted on “nothing to run firmware against yet” extends the schedule. Starting firmware development on vendor development boards in parallel with electronics design is the standard approach for experienced embedded teams.
Underestimating Peripheral Driver Complexity
Reference peripheral drivers from microcontroller vendors are written for evaluation boards, not production products. They skip error recovery, assume ideal operating conditions, and are not optimised for the specific hardware configuration. Production-quality driver development takes longer than reference driver adaptation. Scoping it as a simple porting exercise leads to schedule overruns.
Treating OTA as an Add-On
Designing OTA update capability after the rest of firmware is complete typically requires architectural rework: flash memory layout, bootloader design, and update state machine all need to account for OTA from the beginning. OTA is a firmware architecture constraint, not a feature to add later.
Writing Firmware Tightly Coupled to Hardware
Firmware written without a hardware abstraction layer becomes difficult to maintain when hardware changes. Component substitutions, PCB revisions, and product variants all require firmware changes that a well-designed HAL would have confined to a single abstraction layer. The cost of writing a HAL upfront is far lower than refactoring a tightly coupled codebase under time pressure during a component shortage.
Relying on Host-Based Testing Alone
Host-based unit tests provide useful early feedback on firmware logic, but they give false confidence in reliability if hardware-in-the-loop testing is not done. The bugs that cause production field failures are typically timing-dependent, interrupt-handling, or power sequencing issues – none of which host tests can catch.
Zeus Design’s Approach to Embedded Software Development
Zeus Design develops embedded software as part of an integrated engagement alongside electronics design, PCB layout, and hardware bring-up – not as a standalone deliverable handed off from a separate team. The embedded software development capability at Zeus Design covers firmware architecture definition, HAL design, peripheral driver development, RTOS configuration and task design, application logic implementation, OTA update design, firmware test planning, and hardware bring-up support.
Because the firmware team works alongside the electronics design team, hardware decisions are informed by firmware constraints from day one. Microcontroller selection, peripheral configuration, and power management design all benefit from firmware requirements being in the room during the electronics design phase. The result is fewer integration surprises when prototype hardware arrives and a shorter path from first prototype to production-quality firmware.
For products that also need a mobile app or cloud backend, Zeus Design’s mobile app development and cloud development capabilities cover the full software stack above the firmware layer. When firmware and app are developed by the same team, the communication protocol between device and app is co-designed rather than negotiated between separate teams after the fact.
How firmware connects to IoT hardware design, cloud integration, and mobile apps is covered in the Zeus Design guide on IoT development: hardware, firmware and cloud.
How Embedded Software Connects to Related Services
Embedded software development in a hardware product context connects to:
- Electronics design – the hardware architecture, component selection, and circuit design decisions that the firmware must work within. See Zeus Design’s electronics design service.
- Circuit board design and PCB layout – hardware bring-up issues often trace back to PCB layout decisions: power plane noise, signal integrity on high-speed buses, or incorrect decoupling. See circuit board design.
- Rapid prototyping – faster hardware iteration means more firmware validation cycles before production. See rapid electronics prototyping.
- Mobile app development – for products with companion apps, the BLE or Wi-Fi communication protocol between firmware and app must be co-designed. Developing them separately increases integration complexity and testing overhead.
- Test jig development – production test jigs exercise firmware functionality. Test jig design requires the firmware team’s input on what test modes, interfaces, and diagnostic outputs the firmware supports.
FAQs
What does embedded software development involve for a hardware product?
Embedded software development for a hardware product covers firmware architecture, hardware abstraction layer design, peripheral driver development, real-time operating system integration, application logic, OTA firmware update implementation, and firmware testing. The scope is larger than most product teams initially estimate, particularly for connected IoT products where wireless connectivity, security, and cloud integration add significant firmware complexity. For context on how embedded software fits into the broader product development process, see the Zeus Design electronics design service.
What is the difference between firmware and embedded software?
Firmware refers specifically to software stored in non-volatile memory (such as flash) on a device – it is persistent and runs from power-on. Embedded software is a broader term that includes firmware plus any other software running on the embedded processor: real-time operating system, middleware, and application logic. In most product development contexts the terms are used interchangeably, and the practical scope of an embedded software engagement covers all of these layers.
When should an embedded product use an RTOS?
An RTOS is appropriate when a product needs to manage multiple concurrent tasks with different timing requirements – for example, reading sensors at fixed intervals while managing a wireless connection and handling user input. Simple single-function devices with predictable, sequential behaviour can often use bare-metal architectures. The decision should be made early in firmware architecture definition, as migrating from bare-metal to RTOS mid-project is disruptive and time-consuming. When in doubt, default to RTOS for any product with wireless connectivity.
How long does embedded software development take?
Embedded software development timelines are consistently underestimated because the work is tightly coupled to hardware that is still being designed. Peripheral drivers require real hardware to validate against. Timing behaviour changes when moving from vendor evaluation boards to custom PCBs. Debug tooling for embedded systems is less mature than for general software. And firmware defects on real hardware can be difficult to reproduce systematically. Teams that budget for hardware-firmware co-development iteration time – and start firmware development in parallel with electronics design – are better positioned than those that plan firmware as a sequential phase after hardware.
What deliverables should I expect from an embedded software engagement?
A production-quality embedded software engagement should deliver: firmware architecture documentation (RTOS choice, HAL design, state machine definitions), source code in a version-controlled repository with a build system, peripheral driver documentation, a firmware test plan with hardware-in-the-loop test results, OTA update design documentation, and hardware bring-up notes. Source code alone is not sufficient documentation for an embedded system that a team will need to maintain and update over its product lifetime.
How does embedded firmware testing differ from general software testing?
The key difference is hardware dependency. Many firmware defects – timing issues, interrupt handling bugs, peripheral driver failures, power sequencing problems – only manifest on real hardware under specific operating conditions. Host-based test frameworks like Unity or CppUTest are valuable for testing logic in isolation, but they cannot substitute for hardware-in-the-loop testing. Production firmware should be validated with a test approach that includes both host-based and hardware-based test layers, plus long-run soak testing to surface intermittent issues.
What security requirements apply to connected product firmware in 2026?
The EU Cyber Resilience Act (CRA), effective from 2027, requires security-by-design for connected products sold in Europe – including cryptographic secure boot, authenticated OTA firmware updates, and documented vulnerability management processes. Australian and US regulators are introducing similar requirements for specific categories including medical devices and industrial control systems. Products being designed now that will ship in 2026-2027 should treat security as a firmware architecture requirement from the start. The OWASP Firmware Security Testing Methodology provides a practical framework for evaluating firmware security coverage.
Conclusion
Embedded software development for hardware products spans firmware architecture, HAL design, peripheral drivers, application logic, OTA updates, and a testing regime that must run on real hardware to be valid. The quality and structure of each layer affects product reliability, maintenance cost, and compliance readiness across the product’s full lifetime. Getting those foundations right requires starting firmware development in parallel with electronics design – not as a sequential phase that begins when the hardware is done.
Zeus Design develops embedded software alongside electronics design, PCB layout, and hardware bring-up. Firmware architecture decisions are shaped by hardware constraints, and hardware decisions are shaped by firmware requirements, from the first week of the project. For Australian hardware product teams building connected devices, that integrated approach reduces the integration risk that causes the most common embedded project delays.
If you are planning a connected hardware product and want to understand what embedded software development means for your specific use case, start with a conversation about your requirements and constraints.





0 Comments