A sensor-device team needs more than a firmware binary. It needs to explain which source, dependencies and toolchain produced that binary, which behaviors were tested, and how to investigate a failure on the board.
This is an illustrative engineering use case, not a report of a completed customer deployment. See the engineering scenario for its problem, approach and intended outcomes.
The product scenario
Consider an environmental monitor that samples a sensor, filters readings and activates an alarm above a configured threshold. Engineers also need to read status and investigate faults during development.
Pigweed provides reusable embedded libraries and development tools. Bazel describes build dependencies, platform selection and executable targets. Together they can connect portable application code, board integration and developer tooling in one project. This requires explicit configuration: choosing Bazel does not automatically make an arbitrary compiler or external script hermetic.
Separate logic from hardware
Keep the filter and alarm state machine independent of the physical sensor driver. Supply synthetic readings to the same logic in host tests; connect a real driver on the board.
| Component | Host validation | Device validation |
|---|---|---|
| Filtering and thresholds | Known values, boundaries and invalid samples | Real sampling rate and sensor behavior |
| Alarm state machine | Trigger, reset, snooze and repeated events | Button debounce and visible output |
| Sensor adapter | Fake readings and injected errors | Bus timing, disconnects and recovery |
| Diagnostic interface | Message and command handling | Transport stability and reconnects |
Host execution does not reproduce every hardware behavior. Interrupt timing, power transitions, peripheral interactions and electrical faults require device testing.
A practical engineering sequence
- Establish a baseline. Record the source revision, board model and acceptance criteria. Start from Pigweed's official Bazel quickstart for a minimal project, or Sense for a broader worked example.
- Control the build inputs. Pin the Bazel version, dependency revisions and toolchains. Review module lockfiles and platform configuration. Compare clean developer and CI builds under the same declared configuration.
- Test portable behavior first. Use pw_unit_test to check threshold equality, noisy readings, invalid data and alarm transitions. Make expected state changes explicit.
- Build for the board. Select the intended target platform and drivers. Inspect image size and memory usage against project limits.
- Flash locally. Use a project-defined flashing target dependent on the intended firmware artifact. Device selection and USB permissions remain host responsibilities.
- Inspect and exercise the device. Configure pw_console for logs and pw_rpc for supported diagnostic commands. RPC requires integration and a suitable transport; it does not appear automatically.
- Retain release evidence. Archive firmware hashes, source revision, dependency state, toolchain identity, test results and board verification records.
What the Bazel graph contributes
A flashing target can depend on a firmware target, which depends on application code, board support and the selected toolchain. Running the flashing target can therefore build an out-of-date firmware dependency before invoking the flashing tool.
Compilation and host tests can run in CI. Flashing and hardware tests need controlled access to a physical device, with board identity, exclusive ownership, timeouts and recovery procedures. Do not treat flashing as a cacheable compilation action or send a USB-dependent action to an ordinary remote worker.
Actual Bazel labels and platform flags belong to the selected repository revision. Follow its documented targets rather than copying labels from another project.
Suggested acceptance gates
- A clean checkout builds using the declared dependencies and toolchain.
- Host tests catch incorrect threshold boundaries and alarm transitions.
- The firmware fits the board's flash and RAM budgets.
- Device tests cover sensor failure, reset, reconnect and recovery.
- The firmware installed on the board can be matched to a recorded artifact.
- A second engineer can repeat the workflow from the runbook.
Measure clean and incremental build duration, host-test duration and hardware-test reliability before setting improvement targets. No performance gain is claimed here without a measured baseline.
Learn from the official Sense example
Pigweed Sense demonstrates an illustrative air-quality monitor with a host port, device firmware, tests and development tooling. It is a teaching example rather than a commercial product or a turnkey industrial design.
The current tutorial supports Linux or macOS hosts and Pico 1 or Pico 2 boards; its prerequisites exclude the W variants. Some host exercises work without hardware, while flashing and peripheral checks require the relevant equipment. Check the current prerequisites and known issues before arranging a lab.
Where this approach fits
This workflow is useful when an embedded C++ team needs shared build inputs, portable testable logic and structured device diagnostics. Teams with an established vendor SDK can evaluate selected Pigweed modules incrementally. They should assess integration effort, driver support and build-system changes before committing to a migration.
Pigweed does not remove the need for board bring-up, secure firmware design, production provisioning or domain-specific certification.
Official references
- Pigweed overview
- Bazel quickstart source
- Sense walkthrough and architecture
- Sense prerequisites and hardware support
- Pigweed Bazel toolchain integrations
Technical references reviewed on 23 October 2026.