Capstone: Production Firmware System
This capstone turns the embedded-firmware handbook into a complete production design exercise. You will specify firmware for a connected sensor-controller and produce evidence that it can be built, tested, updated, and debugged in the field.
Learning Objectives
By the end of this exercise, you should be able to design firmware architecture, define task timing, write driver boundaries, handle faults, manage power, plan tests, and describe a secure update flow.
Prerequisites
You should already understand requirements, toolchains, startup, linker scripts, drivers, interrupts, schedulers, RTOS basics, communication stacks, filesystems, watchdogs, power management, testing, debugging, bootloaders, and updates.
Concrete Task
Design firmware for a battery-backed environmental monitor with:
- temperature and humidity sensor over I2C;
0 Vto10 Vanalog input sampled by ADC;- relay output for alarm control;
- RS-485 Modbus RTU port;
- BLE service for configuration;
- SPI NOR flash event log;
- RTC wake every minute;
- watchdog and reset reason logging;
- OTA or service-port firmware update;
- sleep current below
100 uAwhen external power is absent.
Produce a Markdown firmware design package.
Required Implementation
1. Architecture
Draw the firmware blocks and ownership boundaries.
List each module, its public interface, and what it must not access directly.
2. Timing Plan
Create a timing table with period, deadline, worst-case execution time, priority, and failure action for sensor sampling, analog sampling, Modbus handling, BLE handling, logging, alarm update, watchdog health check, and sleep entry.
Use:
$$
CPU\ load = \frac{\sum C_i}{T_i}
$$
where C_i is execution time and T_i is period.
3. Driver and Data Model
Define C structs for latest measurements, alarm state, fault state, and persistent configuration. Include units in field names or comments.
typedef struct {
int16_t temperature_c_x100;
uint16_t humidity_rh_x100;
uint16_t analog_mv;
uint32_t timestamp_s;
} measurement_t;
4. Fault and Watchdog Policy
Specify at least six faults, their detection method, retry policy, safe output behavior, log record, and recovery action. Watchdog refresh must depend on health flags from critical tasks.
5. Power Management
Create active and sleep budgets. Include MCU sleep current, RTC, sensor shutdown, flash standby, RS-485 transceiver state, BLE state, pull resistors, and regulator quiescent current.
$$
I_{avg} = \frac{\sum I_i t_i}{\sum t_i}
$$
6. Update and Release Plan
Specify image header fields, signing method, version policy, rollback behavior, release artifact names, and manufacturing programming steps.
7. Test Plan
Include host unit tests, target integration tests, hardware-in-loop tests, power tests, fault injection, update interruption tests, and production smoke tests.
Expected Behavior
A strong submission connects every firmware decision to a requirement, defines clear module boundaries, handles faults without unsafe outputs, proves the sleep-current target, and includes a repeatable release and update process.
Verification Steps
- Confirm every external interface has a driver owner and test plan.
- Check timing table CPU load and deadlines.
- Verify watchdog refresh is gated by health checks.
- Confirm relay defaults off during reset, fault, and update.
- Recalculate average current and compare with
100 uAsleep target. - Confirm update failure returns to a valid image or recovery mode.
- Ensure logs include timestamp, reset reason, build ID, and fault code.
- Build from a clean checkout and record artifact hashes.
Common Failure Symptoms
- Missed Modbus replies: low priority communication task, long flash writes, or disabled interrupts.
- High sleep current: GPIO back-powering, BLE not shut down, pull resistor leakage, or debugger attached.
- Watchdog resets during OTA: watchdog policy not adjusted for long verified operations.
- Relay flickers at boot: unsafe GPIO default or missing hardware pulldown.
- Corrupt logs: flash writes interrupted without records, CRC, or wear strategy.
Debugging Guidance
Start with reset reason and build ID. Use a logic analyzer for I2C, SPI, UART, and RS-485 timing. Use a current profiler for sleep transitions. Add fault injection hooks for sensor timeout, flash write failure, bad image signature, brownout, and watchdog hang. Compare release and debug builds because timing and power can differ.
Extension Challenge
Add a second product variant without BLE and with a faster 10 Hz analog sampling mode. Update timing, memory, communication, power budget, build configuration, CI matrix, and release artifacts.
Concise Explained Solution
A good solution separates bootloader, application, drivers, services, fault manager, power manager, and communication modules. The scheduler runs periodic measurement and communication work while the power manager enters sleep after all tasks are idle. The watchdog is refreshed only after sensor, communication, logging, and control health flags are current. The relay is off by default and during faults. Logs include reset reason, build ID, timestamp, and fault code. Updates use signed images with a pending-confirmed boot flow and rollback. CI builds every variant, runs host tests, stores map files and hashes, and triggers hardware smoke tests before release.
Summary
The capstone is complete when the firmware design package shows architecture, timing, data ownership, fault handling, power management, testing, secure update behavior, and release evidence that another engineer could implement and verify.
Further Reading
- MCU reference manual sections on reset, clocks, watchdog, low power, flash, and debug.
- MCUboot documentation for signed updates and rollback.
- Memfault guides on observability, watchdogs, coredumps, and OTA reliability.