Zephyr quickstart#
This tutorial shows you how to set up a new C++-based Zephyr project that’s ready to use Pigweed. You’ll learn how to build and run the project’s app on native_sim as well as a physical Raspberry Pi Pico. The app uses pw_log and pw_string to log messages and Zephyr’s GPIO Driver API to blink an LED.
Prerequisites#
Disk space: After setting everything up, the project takes ~19GB of space. The project clones the Zephyr and Pigweed repos as well as their dependencies. It also downloads toolchains and sets up a hermetic development environment.
Operating systems: This tutorial has only been validated on Debian-based Linux and macOS. Windows support is a work in progress.
Setup#
Complete Pigweed’s First-time setup process.
Clone the starter repo.
git clone --recursive \ https://pigweed.googlesource.com/pigweed/quickstart/zephyr \ zephyr-quickstart
git clone --recursive \ https://pigweed.googlesource.com/pigweed/quickstart/zephyr \ zephyr-quickstart
This command downloads the main Pigweed and main Zephyr repos as Git submodules.
Change your working directory to the quickstart repo.
cd zephyr-quickstart
cd zephyr-quickstart
Bootstrap the repo.
source bootstrap.sh
source bootstrap.sh
Pigweed’s bootstrap workflow creates a hermetic development environment for you, including toolchain setup!
Tip
For subsequent development sessions, activate your development environment with the following command:
source activate.sh
source activate.sh
The activate script is faster than the bootstrap script. You only need to run the bootstrap script after updating your Zephyr or Pigweed submodules.
Initialize your West workspace using the manifest that came with the starter repo.
west init -l manifest
Update your West workspace.
west update
(Optional) Initialize pw_ide if you plan on working in VS Code.
pw_ide
provides code intelligence features and makes it easy to swap targets.pw ide sync
Build and run the app#
Native simulator#
Build the quickstart app for native_sim and run it:
export ZEPHYR_TOOLCHAIN_VARIANT=llvm && west build -p -b native_sim app -t run
You should see the app successfully build and then log messages to
stdout
:[00:00:00.000,000] <inf> pigweed: Hello, world! [00:00:00.000,000] <inf> pigweed: LED state: OFF [00:00:01.010,000] <inf> pigweed: LED state: ON [00:00:02.020,000] <inf> pigweed: LED state: OFF [00:00:03.030,000] <inf> pigweed: LED state: ON [00:00:04.040,000] <inf> pigweed: LED state: OFF
Important
When building for
native_sim
make sure thatZEPHYR_TOOLCHAIN_VARIANT
is set tollvm
. See fatal error: bits/c++config.h: No such file or directory.(Optional) Build and run an upstream Zephyr sample app:
west build -p -b native_sim third_party/zephyr/samples/basic/blinky -t run
Raspberry Pi Pico#
Build the quickstart app for Raspberry Pi Pico:
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr && west build -p -b rpi_pico app
Important
When building for physical boards make sure that
ZEPHYR_TOOLCHAIN_VARIANT
is set tozephyr
. See fatal error: bits/c++config.h: No such file or directory.Install the Pico SDK and picotool so that you can easily flash the quickstart app onto your Pico over USB without needing to manually put your Pico board into
BOOTSEL
mode:pw package install pico_sdk pw package install picotool
Add the following rules to
/etc/udev/rules.d/49-pico.rules
or/usr/lib/udev/rules.d/49-pico.rules
. Create the file if it doesn’t exist.# RaspberryPi Debug probe: https://github.com/raspberrypi/debugprobe SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000c", MODE:="0666" KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000c", MODE:="0666" # RaspberryPi Legacy Picoprobe (early Debug probe version) SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", MODE:="0666" KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", MODE:="0666" # RP2040 Bootloader mode SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0003", MODE:="0666" KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0003", MODE:="0666" # RP2040 USB Serial SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", MODE:="0666" KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", MODE:="0666" # RP2350 Bootloader mode SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000f", MODE:="0666" KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000f", MODE:="0666" # RP2350 USB Serial SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0009", MODE:="0666" KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0009", MODE:="0666"
Apply the rules:
sudo udevadm control --reload-rules sudo udevadm trigger
Flash the app onto your board:
picotool reboot -f -u && sleep 3 && picotool load -x ./build/zephyr/zephyr.elf
Troubleshooting#
fatal error: bits/c++config.h: No such file or directory
#
If you see a compilation error about not being able to find
<bits/c++config.h>
, make sure that your ZEPHYR_TOOLCHAIN_VARIANT
environment variable is correctly set:
Set it to
llvm
when building fornative_sim
.Set it to
zephyr
when building for physical boards.
Here’s an example of the error:
...
[2/109] Generating include/generated/version.h
-- Zephyr version: 3.6.99 (~/zephyr-quickstart/third_party/zephyr), build: v3.6.0-1976-g8a88cd4805b0
[10/109] Building CXX object modules/pigweed/pw_string/CMakeFiles/pw_string.to_string.dir/type_to_string.cc.obj
FAILED: modules/pigweed/pw_string/CMakeFiles/pw_string.to_string.dir/type_to_string.cc.obj
ccache /usr/bin/g++
...
-c ~/zephyr-quickstart/third_party/pigweed/pw_string/type_to_string.cc
In file included from ~/zephyr-quickstart/third_party/pigweed/pw_string/public/pw_string/type_to_string.h:20,
from ~/zephyr-quickstart/third_party/pigweed/pw_string/type_to_string.cc:15:
/usr/include/c++/13/cstdint:38:10: fatal error: bits/c++config.h: No such file or directory
38 | #include <bits/c++config.h>
| ^~~~~~~~~~~~~~~~~~
compilation terminated.
...
[12/109] Building CXX object modules/pigweed/pw_string/CMakeFiles/pw_string.builder.dir/string_builder.cc.obj
FAILED: modules/pigweed/pw_string/CMakeFiles/pw_string.builder.dir/string_builder.cc.obj
ccache /usr/bin/g++
...
-c ~/zephyr-quickstart/third_party/pigweed/pw_string/string_builder.cc
In file included from /usr/include/c++/13/algorithm:60,
from ~/zephyr-quickstart/third_party/pigweed/pw_string/public/pw_string/string_builder.h:21,
from ~/zephyr-quickstart/third_party/pigweed/pw_string/string_builder.cc:15:
/usr/include/c++/13/bits/stl_algobase.h:59:10: fatal error: bits/c++config.h: No such file or directory
59 | #include <bits/c++config.h>
| ^~~~~~~~~~~~~~~~~~
compilation terminated.
[15/109] Building C object zephyr/CMakeFiles/offsets.dir/arch/posix/core/offsets/offsets.c.obj
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: ~/zephyr-quickstart/environment/cipd/packages/cmake/bin/cmake
--build ~/zephyr-quickstart/build --target run