Firmware

Embedded Firmware Development: Best Practices and Modern Workflow

October 10, 202514 min minutes to read
7 minutes to read

Table of Contents

Embedded Firmware Fundamentals

Firmware is software that runs directly on hardware, without a full operating system intermediary. It's the "heart" of any electronic device, from smartwatches to industrial machines.

Differences from Traditional Software

Limited Resources

  • RAM: KB not GB (typical 4KB - 512KB)
  • Flash: MB not GB (typical 32KB - 2MB)
  • CPU: MHz not GHz (typical 8MHz - 240MHz)

Real-Time Constraints

  • Response in microseconds, not milliseconds
  • Determinism: same input = same timing output
  • Strict deadlines for control

Direct Hardware Interaction

  • Peripheral registers
  • Hardware interrupts
  • DMA (Direct Memory Access)
  • Low-level communication (SPI, I2C, UART)

Where Firmware Runs

  • Microcontrollers (STM32, ESP32, nRF52)
  • FPGA/CPLD
  • DSP (Digital Signal Processors)
  • SoC (System on Chip)

Choosing the Right Microcontroller

Popular Families

STM32 (STMicroelectronics)

  • ARM Cortex-M0 through M7
  • Vast ecosystem (HAL, CubeMX)
  • Price: €1-15 per chip
  • Use: Industrial, medical, consumer

ESP32 (Espressif)

  • Dual-core, integrated WiFi + Bluetooth
  • FreeRTOS included
  • Price: €2-5
  • Use: IoT, connected devices

nRF52 (Nordic Semiconductor)

  • BLE optimized, ultra-low power
  • Mature SDK for wireless
  • Price: €3-8
  • Use: Wearables, beacons, sensors

PIC/AVR (Microchip)

  • Simple, 8-bit, entry-level
  • Free toolchain
  • Price: €0.50-3
  • Use: Simple applications, hobby

Selection Criteria

  1. Required Peripherals - ADC, DAC, timers, communications
  2. Power Consumption - Battery life requirements
  3. Memory - Sufficient Flash and RAM for application
  4. Ecosystem - Documentation, examples, community
  5. Availability - Stable supply chain

Professional Development Setup

Compiler and Toolchain

ARM GCC (free)

  • arm-none-eabi-gcc
  • Production quality
  • Used in industry

IAR Embedded Workbench (commercial)

  • Superior optimizations
  • Technical support
  • Required for some certifications

Keil MDK (commercial)

  • Popular for ARM
  • Excellent integrated debugger

IDEs

VS Code + Extensions

  • PlatformIO: Multi-platform, library management
  • Cortex-Debug: GDB frontend
  • C/C++ IntelliSense

STM32CubeIDE

  • Free for STM32
  • Graphical peripheral configurator
  • Integrated debugger

Eclipse-based

  • MCUXpresso (NXP)
  • Simplicity Studio (Silicon Labs)

Debugging Hardware

ST-Link V2/V3

  • For STM32
  • Price: €5-25

J-Link (Segger)

  • Universal ARM
  • Excellent performance
  • Price: €50-500

Logic Analyzer

  • Saleae Logic for protocol debug
  • Essential for SPI, I2C, UART issues

Firmware Code Structure

Bare-Metal vs RTOS

Bare-Metal (super-loop)

int main(void) {
    init_hardware();
    while(1) {
        task1();
        task2();
        task3();
    }
}
  • Pro: Simple, minimal overhead, deterministic
  • Con: Hard to scale, manual timing
  • Use: Simple applications, minimal resources

RTOS (FreeRTOS, Zephyr, etc.)

void task1(void *params) {
    while(1) {
        // Do work
        vTaskDelay(100);
    }
}
  • Pro: Real multitasking, timing abstraction
  • Con: Memory overhead, complexity
  • Use: Complex applications, multiple features

Layered Architecture

┌─────────────────────────┐
│     Application         │
├─────────────────────────┤
│     Middleware          │  (Protocols, File systems)
├─────────────────────────┤
│     RTOS / Scheduler    │
├─────────────────────────┤
│     HAL / Drivers       │  (Hardware Abstraction)
├─────────────────────────┤
│     Hardware            │  (MCU, Peripherals)
└─────────────────────────┘

Drivers and Communications

GPIO (General Purpose I/O)

Typical Configuration:

  • Direction: Input / Output
  • Mode: Push-pull / Open-drain
  • Pull: Up / Down / None
  • Speed: Low / Medium / High

Best Practices:

  • Define pins in dedicated header
  • Wrapper functions for clarity
  • Debouncing for buttons (software or hardware)

Serial Communications

UART

  • Simple, point-to-point
  • Typical baudrate: 9600 - 115200
  • Use: Debug console, modems

SPI (Serial Peripheral Interface)

  • Full duplex, master-slave
  • Speeds: MHz
  • Use: Display, flash, fast sensors

I2C (Inter-Integrated Circuit)

  • Multi-master, multi-slave
  • Bus addressing
  • Use: Sensors, EEPROM, RTC

Interrupts

Golden Rules:

  • ISR as short as possible
  • Don't block in ISR (no printf, no malloc)
  • Flag + processing in main loop
  • Correct prioritization (NVIC for ARM)

Energy Consumption Optimization

Low-Power Modes

Sleep Modes (ARM Cortex-M)

  • Sleep: CPU stopped, peripherals active
  • Stop: Clock stopped, RAM retained
  • Standby: Almost everything off, wake from RTC/external

Typical Consumption:

  • Active: 10-50mA
  • Sleep: 1-5mA
  • Stop: 10-100µA
  • Standby: 1-5µA

Optimization Techniques

Clock Gating

  • Disable clock for unused peripherals
  • Significant consumption reduction

Voltage Scaling

  • Run at reduced voltage when speed not needed
  • Speed vs consumption trade-off

Duty Cycling

  • Periodic wake up, process, sleep
  • Example: Sensor reading every 10 seconds

Battery Life Calculation

Battery Capacity (mAh) / Average Consumption (mA) = Hours of autonomy

Example:
2000mAh / 0.5mA average = 4000 hours = 166 days

Considerations:

  • Battery self-discharge
  • Temperature variation
  • Battery aging

Firmware Validation

Debugging Techniques

Printf Debugging

  • Simple and effective for quick checks
  • Overhead: Can affect timing
  • Use: UART or ITM (ARM)

Breakpoints and Watch

  • Stop at code line
  • Variable inspection
  • Step through execution

Live Watch

  • Real-time variable visualization
  • No execution stop
  • Minimal overhead

Logic Analyzer

  • Digital signal capture
  • Protocol decoding
  • Essential for timing issues

Embedded Unit Testing

Frameworks:

  • Unity: Lightweight, popular
  • CppUTest: C/C++, mocking support
  • Google Test: For non-HW components

What We Test:

  • Pure functions (algorithms, parsers)
  • State machines
  • Protocol handlers

What We Don't Unit Test:

  • HAL directly (integration)
  • Timing dependent (system tests)

Hardware-in-the-Loop (HIL)

  • Automated testing on real hardware
  • Input stimulation, output verification
  • CI/CD for firmware

Remote Firmware Updates

Why OTA?

  • Fix bugs post-deployment
  • Add new features
  • Security patches
  • Avoid physical recall (expensive)

Bootloader Architecture

Dual-Bank (A/B):

┌────────────────┐
│  Bootloader    │ (Protected, rarely updated)
├────────────────┤
│  App Slot A    │ (Active)
├────────────────┤
│  App Slot B    │ (Update target)
└────────────────┘

Advantages:

  • Instant rollback if update fails
  • Background update
  • Zero downtime

OTA Security

Mandatory:

  • Digital firmware signature (ECDSA)
  • Transport encryption (TLS)
  • Integrity verification (SHA256)
  • Anti-rollback (version counter)

Optional:

  • Firmware encryption at rest
  • Secure boot chain
  • Hardware security module (HSM)

Practical Implementation

Popular Solutions:

  • ESP-IDF OTA (for ESP32)
  • MCUBoot (Zephyr, universal)
  • AWS IoT OTA
  • Azure IoT Device Update

Firmware Standards

Safety Standards

IEC 61508 (General Safety)

  • SIL levels (Safety Integrity Level)
  • Software requirements for safety-critical systems

ISO 26262 (Automotive)

  • ASIL levels (Automotive Safety Integrity Level)
  • From ASIL A to ASIL D (strictest)

IEC 62304 (Medical Devices)

  • Class A, B, C
  • Completely documented lifecycle

Common Requirements

Traceability

  • Requirements → Design → Code → Test
  • Every feature traceable to requirement

Code Coverage

  • Statement coverage: minimum 80%
  • Branch coverage: minimum 70%
  • MC/DC for safety-critical: 100%

Static Analysis

  • MISRA C: Rules for safe C
  • PC-lint, Polyspace: Tools
  • Zero warnings policy

Documentation

  • Software Requirements Specification
  • Software Design Description
  • Test Reports
  • Change History

Quality Firmware with Torcip

Professional firmware development requires experience, processes, and adequate tooling. Firmware quality determines product success.

Best Practices Recap

  • Modular and scalable architecture
  • RTOS for complex applications
  • Power management from the start
  • Automated testing where possible
  • OTA for lifecycle management
  • Complete documentation

Torcip Firmware Services

Complete Development:

  • Architecture and design
  • Implementation and testing
  • Documentation and transfer

Supported Platforms:

  • STM32 (all families)
  • ESP32/ESP8266
  • nRF52/nRF91
  • Custom silicon

Specialties:

  • BLE and wireless protocols
  • Motor control
  • Sensors and acquisition
  • IoT connectivity
  • Low-power optimization

Process:

  1. Specifications and architecture
  2. Development sprints
  3. Code review and testing
  4. Integration and validation
  5. Transfer and support

Contact us for a discussion about your firmware project and receive a free technical assessment.

Read more articles

Back to blog