This target supports building Pigweed on a few Arduino cores.

See also

There are a few caveats when running Pigweed on top of the Arduino API. See pw_arduino_build for details.

Supported Boards

Currently only Teensy 4.x and 3.x boards are supported.


You must first install an Arduino core or let Pigweed know where you have cores installed using the pw_arduino_build_CORE_PATH build arg.

Installing Arduino Cores

The arduino_builder utility can install Arduino cores automatically. It’s recommended to install them to into third_party/arduino/cores/.

# Setup pigweed environment.
# Install an arduino core
arduino_builder install-core --prefix ./third_party/arduino/cores/ --core-name teensy


To build for this Pigweed target, simply build the top-level “arduino” Ninja target. You can set Arduino build options using gn args out or by running:

gn gen out --args='
  pw_arduino_build_MENU_OPTIONS=["menu.usb.serial", "menu.keys.en-us"]'

On a Windows machine it’s easier to run:

gn args out

That will open a text file where you can paste the args in:

pw_arduino_build_CORE_PATH = "//third_party/arduino/cores"
pw_arduino_build_CORE_NAME = "teensy"
pw_arduino_build_BOARD = "teensy40"
pw_arduino_build_MENU_OPTIONS = ["menu.usb.serial", "menu.keys.en-us"]

Save the file and close the text editor.

Then build with:

ninja -C out arduino

To see supported boards and Arduino menu options for a given core:

arduino_builder --arduino-package-path ./third_party/arduino/cores/teensy \
                --arduino-package-name teensy/avr \
Board Name  Description
teensy41    Teensy 4.1
teensy40    Teensy 4.0
teensy36    Teensy 3.6
teensy35    Teensy 3.5
teensy31    Teensy 3.2 / 3.1

You may wish to set different arduino build options in pw_arduino_build_MENU_OPTIONS. Run this to see what’s available for your core:

arduino_builder --arduino-package-path ./third_party/arduino/cores/teensy \
                --arduino-package-name teensy/avr \
                list-menu-options --board teensy40

That will show all menu options that can be added to gn args out.

All Options
menu.usb.serial             Serial
menu.usb.serial2            Dual Serial
menu.usb.serial3            Triple Serial
menu.usb.keyboard           Keyboard
menu.usb.touch              Keyboard + Touch Screen
menu.usb.hidtouch           Keyboard + Mouse + Touch Screen
menu.usb.hid                Keyboard + Mouse + Joystick
menu.usb.serialhid          Serial + Keyboard + Mouse + Joystick
menu.usb.midi               MIDI

Default Options
menu.usb.serial             Serial
menu.speed.600              600 MHz
menu.opt.o2std              Faster
menu.keys.en-us             US English


When working in upstream Pigweed, building this target will build all Pigweed modules’ unit tests. These tests can be run on-device in a few different ways.

Run a unit test

If using out as a build directory, tests will be located in out/arduino_debug/obj/[module name]/[test_name].elf.

Tests can be flashed and run using the arduino_unit_test_runner tool. Here is a sample bash script to run all tests on a Linux machine.

gn gen out --export-compile-commands \
            pw_arduino_build_MENU_OPTIONS=["menu.usb.serial", "menu.keys.en-us"]' && \
  ninja -C out arduino

for f in $(find out/arduino_debug/obj/ -iname "*.elf"); do
    arduino_unit_test_runner --verbose \
        --config-file ./out/arduino_debug/gen/arduino_builder_config.json \
        --upload-tool teensyloader \

Using the test server

Tests may also be run using the pw_arduino_use_test_server = true GN arg. The server must be run with an arduino_builder config file so it can locate the correct Arduino core, compiler path, and Arduino board used.

arduino_test_server --verbose \
    --config-file ./out/arduino_debug/gen/arduino_builder_config.json

Flashing Known Issues

Teensy Boards

By default Teensyduino uses the Teensy Loader Application which has a couple limitations:

  • Requires a GUI (or X11 on Linux).

  • Can only flash one board at a time.

GN Target Example

Here is an example pw_executable gn rule that includes some Teensyduino libraries.


_library_args = [
  rebase_path(arduino_core_library_path, root_build_dir),

pw_executable("my_app") {
  # All Library Sources
  _library_c_files = exec_script(
          arduino_show_command_args + _library_args + [
          "list lines")
  _library_cpp_files = exec_script(
          arduino_show_command_args + _library_args + [
          "list lines")

  sources = [ "" ] + _library_c_files + _library_cpp_files

  deps = [

  include_dirs = exec_script(arduino_builder_script,
                             arduino_show_command_args + _library_args +
                                 [ "--library-include-dirs" ],
                             "list lines")

  # Required for using Arduino.h and any Arduino API functions
  remove_configs = [ "$dir_pw_build:strict_warnings" ]
  deps += [ "$dir_pw_third_party/arduino:arduino_core_sources" ]