Overview#

This overview helps you understand Pigweed and determine if Pigweed is a good fit for your project.

If you still have questions after reading this overview, please file a bug or talk to us on Discord. If you prefer email, DM one of the Discord admins (they’re all on the Pigweed team) and they’ll kick off an email thread for you.

What is Pigweed?#

Pigweed is essentially a modular platform for embedded development. By “modular” we mean that it’s possible to adopt only the parts that you need.

The following sections explain the main components of our platform in more detail. The best way to get a deeper understanding about what Pigweed provides is to try out the Tour of Pigweed and to study the Sense repo (the example project that the tour is based off).

Who is Pigweed’s target audience?#

Our mission is to help large embedded development teams create world-class products by increasing team velocity, project sustainability, and product robustness. Having lived through many of these projects, we know how overwhelmingly complex they can become. Pigweed is our ambitious attempt to create step change improvements in the state of the art of embedded device development.

Hobbyist projects are also welcome to adopt Pigweed, but many hobbyists find Pigweed to be too complex for their needs. Large embedded development teams, on the other hand, understand that this “complexity” is what it takes to ship world-class products at scale. See A note on complexity, or, why is Sense so complicated? for further discussion.

Note

In this overview, a client is a team that uses Pigweed in one or more of their projects.

Pigweed’s platform#

These are the main components of our platform.

Embedded development libraries#

Our Modules enable you to use modern software development best practices without compromising performance. They are:

  • Heavily optimized for resource-constrained hardware.

  • Battle-tested in millions of consumer devices.

  • Deployed in extreme, high-stakes environments e.g. satellites.

  • Designed to work portably on both your development host (via host-side simulation) and a wide variety of embedded hardware systems.

Build system integrations#

We make it easy to integrate our modules into most of the build systems that are popular among large embedded development teams.

Full support:

Partial support:

  • GN. Pigweed has extensive support for GN, because GN was Pigweed’s primary build system for many years. However, Pigweed’s support for GN is expected to relatively decline over the coming years as we focus more on Bazel.

  • CMake. We support integrating Pigweed modules into existing CMake projects. We don’t recommend starting new projects with CMake and can’t offer extensive support for new projects that choose CMake.

  • Zephyr. Although technically CMake-derived, there is an ongoing effort to make Pigweed work seamlessly within Zephyr projects.

No support:

  • Make.

  • Buck2.

  • Meson.

  • PlatformIO.

Development environment#

Our Bazel-based development environment reduces new teammate onboarding time and eliminates the works on my machine problem. Onboarding time speeds up because we dramatically simplify the setup of cross-compilation toolchains and complex tools like libusb. The “works on my machine” problem is eliminated because of Bazel’s strong hermeticity guarantees. Building your entire project becomes a literal two-step process:

  1. Clone the repo.

  2. Run bazelisk build //...

If your project uses one of our other supported build systems, pw_env_setup can help speed up onboarding and increase the reproducibility of builds, but the hermeticity guarantees aren’t as strong as what Bazel provides.

Supported operating systems#

We have robust support for Linux and macOS. We also support Windows, but it has more sharp edges.

Rapid, portable firmware development#

Pigweed has extensive support for host-side simulation and testing. Many Pigweed clients structure their projects in a hardware-agnostic way that allows them to simulate and test most core business logic on their development hosts. By the time the product hardware is ready, the only remaining task is to implement hardware-specific wrappers around the hardware-agnostic core logic. Benefits of this approach:

  • Your software team can remain productive while they’re waiting on prototypes from hardware teams.

  • Unit tests are fast and reliable enough to run after every code iteration.

  • It becomes possible to thoroughly test your software against modern code analysis tools like ASan, TSan, MSan, and fuzzers. These tools usually don’t work correctly in on-device embedded contexts.

Product lifecycle tooling#

Bringing a product to mass production requires a lot more than just good firmware. Rather than reimplementing common concerns from scratch for each new project, Pigweed provides a solid foundation that you can reuse and extend with much higher velocity across all your projects.

Examples:

  • pw_console: An interactive console that can be extended and customized.

  • Factory-at-your-desk workflows: Lightweight testing scripts that combine manual testing and automated testing. Useful for small-scale manufacturing runs or for ensuring that all teammates follow a precise, reproducible testing workflow.

  • pw_bloat: Tools for generating size reports.

  • pw_console: Utilities for creating custom CLI tools.

  • pw_web: A library for creating custom web apps that can communicate with your embedded devices.

Typical new project journey#

Here is the typical journey for starting a new project with Pigweed. We’ll assume that you also need to integrate a vendor SDK such as Espressif’s ESP-IDF, STMicroelectronics’s STM32Cube, or Raspberry Pi’s C/C++ SDK.

The following sections assume that you’ll be using Bazel in your new project.

1. Fork the Sense repo#

The first step is to fork Sense, the example project that’s used in the Tour of Pigweed. It’s a working example of an extensive Pigweed integration. You can remove any parts that you don’t need.

2. Create Bazel files for vendor SDKs and other dependencies#

Next, add Bazel support for your vendor SDK as needed. For some SDKs, the SDK may already have support in the Bazel developer ecosystem. For example, the Raspberry Pi C/C++ SDK directly supports Bazel and can be downloaded from the Bazel Central Registry. For other vendor SDKs, you may need to create BUILD.bazel files or package the vendor SDK into a Bazel module. We encourage you to publish the Bazel module to the Bazel Central Registry so that the entire Bazel developer ecosystem can benefit from and improve on your work.

In general, you’ll also use Bazel modules system to pull in other dependencies as needed. Make sure to check the Bazel Central Registry to see if someone else has already provided a module for your dependency.

3. Create Pigweed wrappers around vendor SDKs#

Next, create Pigweed wrappers that invoke your vendor SDK as needed. The primary interfaces for most Pigweed modules are hardware-agnostic. Sometimes, an implementation for a particular vendor SDK already exists in Upstream Pigweed. If an implementation already exists in Upstream Pigweed, you’re welcome to use that. Otherwise, you’ll need to implement the wrapper yourself. See pw_spi for an example of a hardware-agnostic module and pw_spi backends for a list of implementations. We encourage Pigweed clients to contribute their general-purpose implementations for popular vendor SDKs to Upstream Pigweed so that the whole Pigweed community can benefit from them and improve them. But that is totally optional. You can of course keep your implementations private, if needed.

4. Set up device builds#

The last step is to set up toolchains and other tools so that your project can be built for and flashed onto your particular hardware. In general, the cross-compilation toolchain is usually set up as a Bazel platform. See //targets/rp2/BUILD.bazel from the Sense repo for an example.

Supported technologies#

This section provides more detail about how much (or little) we support specific build systems, programming languages, etc.

Build system support#

See Build system integrations above.

Drivers and peripherals#

Our driver and peripheral APIs are essentially C++ abstract classes that use the non-virtual interface pattern. Examples:

If an implementation exists in Upstream Pigweed you are welcome to use that. Visit the docs for the module that provides the generic API (e.g. pw_spi) and then navigate to that module’s “backends” or “implementations” section (e.g. pw_spi backends) to determine what implementations are already available.

Vendor SDKs#

The level of effort required to integrate your vendor SDK into a Bazel-based Pigweed project depends on:

  • The availability of the vendor SDK as a Bazel dependency. Ideally, the vendor SDK is already available as a Bazel module in the Bazel Central Registry (BCR). If not, check if Upstream Pigweed has a target that makes it easy to pull the vendor SDK into your project. E.g. //third_party/stm32cube/BUILD.bazel provides a target to pull STM32Cube into a project. Otherwise, you’ll need to set up a new Bazel module yourself or create a solution similar to the STM32Cube BUILD.bazel file.

  • The availability of Pigweed wrappers around the vendor SDK. As mentioned in 3. Create Pigweed wrappers around vendor SDKs, the primary interfaces for most Pigweed modules are hardware-agnostic. The implementation of that module for a particular vendor is usually handled in a separate module. If an implementation already exists in Upstream Pigweed, you’re welcome to use that. Otherwise, you’ll need to roll your own implementation.

The following vendor SDKs are already well supported:

  • Raspberry Pi Pico C/C++ SDK

  • MCUXpresso

  • STM32Cube

Bluetooth#

Multiple Pigweed modules provide Bluetooth-related functionality:

  • pw_bluetooth_sapphire: A full central/peripheral-certified Bluetooth stack that has been deployed on millions of consumer devices. It’s an AP-sized Bluetooth stack that’s been made portable but isn’t yet extensively size-optimized.

  • pw_bluetooth: A BLE-only API that provides a generic interface for Bluetooth that can be implemented by different stacks. pw_bluetooth_sapphire implements this stack but there are also wrappers for other stacks. Not all of these other wrappers are public yet.

  • pw_bluetooth_proxy: Enables proxying Bluetooth packets and rerouting L2CAP channels to low-power islands.

Language support#

C++#

Pigweed has an extensive collection of C++ libraries. See Modules. All Pigweed code requires C++17 and is fully compatible with C++20. We expect to support C++ indefinitely.

Rust#

Pigweed incrementally adds Rust support for any given module based on client needs. We plan on growing our Rust support extensively over the next few years. We expect to support Rust (alongside C++) indefinitely.

Python#

Python is Pigweed’s primary language for scripting tasks. Some Pigweed modules, such as pw_console, can be extended with custom scripts. These scripts almost always must be written in Python.

Pigweed officially supports Python 3.10 and 3.11. Moving forward, Pigweed will follow Python’s official supported versions. Pigweed will drop support for Python versions as they reach end-of-life.

Other languages#

Support for other languages are added on a case-by-case basis, depending on client needs.

Next steps#

  • The best way to get a deeper understanding about what Pigweed provides is to try out the Tour of Pigweed and to study the Sense (the example project that the tour is based off).

  • If you still have questions, please file a bug or talk to us on Discord. If you prefer email, DM one of the Discord admins (they’re all on the Pigweed team) and they’ll kick off an email thread for you.