blob: 6847653145a19ffd3169fe9e0c7408c6a4af0b0a [file] [log] [blame]
.. _target-raspberry-pi-pico:
================================
Raspberry Pi Pico with pw_system
================================
.. warning::
This target is in an early state and is under active development. Usability
is not very polished, and many features/configuration options that work in
upstream Pi Pico CMake build have not yet been ported to the GN build.
This target configuration uses :ref:`pw_system<module-pw_system>` on top of
FreeRTOS and the `Raspberry Pi Pico SDK
<https://github.com/raspberrypi/pico-sdk>`_ HAL rather than a from-the-ground-up
baremetal approach.
-----
Setup
-----
To use this target, Pigweed must be set up to use FreeRTOS and the Pico SDK
HAL. The supported repositories can be downloaded via ``pw package``, and then
the build must be manually configured to point to the locations the repositories
were downloaded to.
.. code-block:: sh
pw package install freertos
pw package install pico_sdk
gn gen out --export-compile-commands --args="
dir_pw_third_party_freertos=\"//environment/packages/freertos\"
PICO_SRC_DIR=\"//environment/packages/pico_sdk\"
"
.. tip::
Instead of the ``gn gen out`` with args set on the command line above you can
run:
.. code-block:: sh
gn args out
Then add the following lines to that text file:
.. code-block::
dir_pw_third_party_freertos = getenv("PW_PACKAGE_ROOT") + "/freertos"
PICO_SRC_DIR = getenv("PW_PACKAGE_ROOT") + "/pico_sdk"
Linux
=====
On linux, you may need to update your udev rules at
``/etc/udev/rules.d/49-pico.rules`` to include the following:
.. code-block:: none
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0003", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0003", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", MODE:="0666"
--------
Building
--------
The Pi Pico is configured to output logs and test results over USB serial at a
baud rate of 115200.
Once the pico SDK is configured, the Pi Pico will build as part of the default
GN build:
.. code-block:: sh
ninja -C out
--------
Flashing
--------
Flashing the Pi Pico is two easy steps:
#. While holding the button on the Pi Pico, connect the Pico to your computer
via the micro USB port.
#. Copy the desired UF2 firmware image to the RPI-RP2 volume that enumerated
when you connected the Pico.
------------------
Running unit tests
------------------
Unlike most other targets in Pigweed, the RP2040 uses RPC-based unit testing.
This makes it easier to fully automate on-device tests in a scalable and
maintainable way.
Step 1: Start test server
=========================
To allow Ninja to properly serialize tests to run on device, Ninja will send
test requests to a server running in the background. The first step is to launch
this server. By default, the script will attempt to automatically detect an
attached Pi Pico running an application with USB serial enabled, then using
it for testing. To override this behavior, provide a custom server configuration
file with ``--server-config``.
.. code-block:: sh
$ python -m rp2040_utils.unit_test_server
.. tip::
If the server can't find any attached devices, ensure your Pi Pico is
already running an application that utilizes USB serial.
.. Warning::
If you connect or disconnect any boards, you'll need to restart the test
server for hardware changes to take effect.
Step 2: Configure GN
====================
By default, this hardware target has incremental testing disabled. Enabling the
``pw_targets_ENABLE_RP2040_TEST_RUNNER`` build arg tells GN to send requests to
a running ``rp2040_utils.unit_test_server``.
.. code-block:: sh
$ gn args out
# Modify and save the args file to use pw_target_runner.
pw_targets_ENABLE_RP2040_TEST_RUNNER = true
Step 3: Build changes
=====================
Now, whenever you run ``ninja -C out pi_pico``, all tests affected by changes
since the last build will be rebuilt and then run on the attached device.
Alternatively, you may use ``pw watch`` to set up Pigweed to trigger
builds/tests whenever changes to source files are detected.
-----------------------------------------
Building and running the demo application
-----------------------------------------
This target has an associated demo application that can be built and then
flashed to a device with the following commands:
Build
=====
.. code-block:: sh
ninja -C out pw_system_demo
Flash
=====
- Using a uf2 file:
Copy to ``out/rp2040.size_optimized/obj/pw_system/system_example.uf2``
your Pico when it is in USB bootloader mode. Hold down the BOOTSEL button when
plugging in the pico and it will appear as a mass storage device.
- Using a Pico Probe and openocd:
This requires installing the Raspberry Pi foundation's OpenOCD fork for the
Pico probe. More details including how to connect the two Pico boards is
available in ``Appendix A: Using Picoprobe`` of the `Getting started with
Raspberry Pi Pico
<https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf>`_
guide.
**Install RaspberryPi's OpenOCD Fork:**
.. code-block:: sh
git clone https://github.com/raspberrypi/openocd.git \
--branch picoprobe \
--depth=1 \
--no-single-branch \
openocd-picoprobe
cd openocd-picoprobe
./bootstrap
./configure --enable-picoprobe --prefix=$HOME/apps/openocd --disable-werror
make -j2
make install
**Setup udev rules (Linux only):**
.. code-block:: sh
cat <<EOF > 49-picoprobe.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000[43a]", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000[43a]", MODE:="0666"
EOF
sudo cp 49-picoprobe.rules /usr/lib/udev/rules.d/49-picoprobe.rules
sudo udevadm control --reload-rules
**Flash the Pico:**
.. code-block:: sh
~/apps/openocd/bin/openocd -f ~/apps/openocd/share/openocd/scripts/interface/picoprobe.cfg -f ~/apps/openocd/share/openocd/scripts/target/rp2040.cfg -c 'program out/rp2040.size_optimized/obj/pw_system/bin/system_example.elf verify reset exit'
Connect with pw_console
=======================
Once the board has been flashed, you can connect to it and send RPC commands
via the Pigweed console:
.. code-block:: sh
pw-system-console -d /dev/{ttyX} -b 115200 \
--proto-globs pw_rpc/echo.proto \
--token-databases \
out/rp2040.size_optimized/obj/pw_system/bin/system_example.elf
Replace ``{ttyX}`` with the appropriate device on your machine. On Linux this
may look like ``ttyACM0``, and on a Mac it may look like ``cu.usbmodem***``.
When the console opens, try sending an Echo RPC request. You should get back
the same message you sent to the device.
.. code-block:: pycon
>>> device.rpcs.pw.rpc.EchoService.Echo(msg="Hello, Pigweed!")
(Status.OK, pw.rpc.EchoMessage(msg='Hello, Pigweed!'))
You can also try out our thread snapshot RPC service, which should return a
stack usage overview of all running threads on the device in Host Logs.
.. code-block:: pycon
>>> device.snapshot_peak_stack_usage()
Example output:
.. code-block::
20220826 09:47:22 INF PendingRpc(channel=1, method=pw.thread.ThreadSnapshotService.GetPeakStackUsage) completed: Status.OK
20220826 09:47:22 INF Thread State
20220826 09:47:22 INF 5 threads running.
20220826 09:47:22 INF
20220826 09:47:22 INF Thread (UNKNOWN): IDLE
20220826 09:47:22 INF Est CPU usage: unknown
20220826 09:47:22 INF Stack info
20220826 09:47:22 INF Current usage: 0x20002da0 - 0x???????? (size unknown)
20220826 09:47:22 INF Est peak usage: 390 bytes, 76.77%
20220826 09:47:22 INF Stack limits: 0x20002da0 - 0x20002ba4 (508 bytes)
20220826 09:47:22 INF
20220826 09:47:22 INF ...
You are now up and running!
.. seealso::
The :ref:`module-pw_console`
:bdg-ref-primary-line:`module-pw_console-user_guide` for more info on using
the the pw_console UI.