You are on page 1of 131

Raspberry Pi Pico Guide

A Complete Newbie to Expert Guide to


Master the Use of Raspberry Pi Pico to the
Max!

Tobi Wealth
Copyright 2021 © Tobi Wealth

All rights reserved. This book is copyright and no


part of it may be reproduced, distributed, or
transmitted in any form or by any means, including
photocopying, recording, or other electronic or
mechanical methods, without the prior written
permission of the publisher, except in the case of
brief quotations embodied in critical reviews and
certain other noncommercial uses permitted by
copyright law.

Printed in the United States of America Copyright


2021 © Tobi Wealth
Contents
Introduction ......................................................................................................1
CHAPTER ONE: QUICK PICO SETUP ...................................................................2
Chapter 2: The Pico SDK ....................................................................................5
Chapter 3: Blinking a LED in C ...........................................................................8
Chapter 4: Saying “Hello World” in C ..............................................................17
Chapter 5: Debugging with SWD.....................................................................28
Chapter 6: Using Visual Studio Code...............................................................35
Chapter 7: Creating your own Project ............................................................45
Chapter 8: Building on other platforms ..........................................................59
Chapter 9: Using other Integrated Development Environments ....................79
Appendix A: Using Picoprobe ........................................................................101
Appendix B: Using Picotool ...........................................................................114
Introduction

The Raspberry pico is a new microcontroller board that is


powered by the new rp2040. The best thing about this processor is
the insanely detailed data sheet.

The raspberry pi pico is very useful for makers, hobbyist and


beginners, who want to use hardware and software, python or C++
to control things like stepper motors, temperature sensors, etc.

Another nice thing about the pico is that it has more speed, more
memory and it is a dual core micro controller and best of all, it is a
32 bit arm controller compared to the 8 bit of the arduino nano.

In this guide, you're going to learn how to use the raspberry pi


pico microcontroller like a Pro, even if you are a total beginner.

With that said, let's dive right in.

1
CHAPTER ONE: QUICK PICO SETUP

The installation steps in this Getting Started guide


can be skipped if you are only developing for
Raspberry Pi Pico on the Raspberry Pi 4B and the
Raspberry Pi 400. Just run the setup script and you
will be fine. Get the script by running the following
code:

First run this code sudo apt install git if you don’t
have Git installed.

Then you can easily make the script executable


with:

$ chmod +x pico_setup.sh

Thereafter, run it with

$ pico-setup/pico_setup.sh

Running this script does the following:


● Creates a directory pico
● Install the necessary dependencies required.

2
● Download the pico-sdk, pico-examples, pico-
extras, and pico-playground repositories
● Creates the paths for the following;
Pico_SDk_path, Pico_Examples_Path, and
Pico_Playground_Path inside your `/. Bashrc.
● Prototype the blink and hello_world examples in
Pico_examples/build/blink and pico-
examples/build/hello-world.
● Download the build protocol. Once you are done,
copy it to /usr/local/bin.
● Download and build picoprobe
● Download and compile OpenOCD – this is to
create support for debugging.
● Download and install Visual Studio Code.
● Install the necessary Visual Studio Code
extensions.

Configure your Raspberry Pi UART to use with the


Raspberry Pi Pico. When everything is setup, reboot
your Raspberry Pi to have it all together. After
rebooting the system, the UART changes and
reconfigurations take effect.

$ sudo reboot

3
Open the Visual Studio Code in the “Programming”
menu using the instructions from Section 6.2

4
Chapter 2: The Pico SDK

Important:

The following instructions0assume that you


are using a Raspberry Pi0Pico and some
details may differ if you0are using a different
RP2040-basedboard. They also assume you
are using0Raspberry Pi OS running on a
Raspberry Pi4, or an equivalent0Debian-based
Linux distribution0running on another
platform.

The RP2040 microcontroller on the Raspberry Pi was


designed to be compatible with the Raspberry Pi
Pico. The components on the board supports C/C
++ SDK, including an official MicroPython port. This
book takes you by the hand to build, install and use
the SDK toolchain, and generally starting out with
the SDK.

2.1. Get the Pico SDK and examples

Check the Pico-examples repository


(https://github.com/raspberrypi/pico-examples) for
examples on applications written with the pico-sdk
5
(https://github.com/raspberrypi/pico-sdk). Create a
pico directory to store your pico related checkouts
as you clone the repositories. Check /home/pi/pico
for instructions to create a pico directory.

$ cd ~/

$ mkdir pico

$ cd pico

Thereafter, clone the pico-sdk and pico-examples git


repositories

$ git clone -b master https://github.com/raspberrypi/pico-sdk.git

$ cd pico-sdk

$ git submodule update --init

$ cd ..

$ git clone -b master https://github.com/raspberrypi/pico-examples.git

WARNING

If you don’t initialised the tinyusb submodule in


your pico-sdk checkout and USB CDC serial, as well
as other USB example code, and functions, it won’t
work, since the SDK won’t come with no USB
functionality.

6
2.2. Install the Toolchain

You may have to install extra tools to build the


applications shown in pico-examples. One of them is
CMake, a project-building and a cross-platform tool
to build software, including the GNU Embedded
Toolchain for Arm. Find and install these tools
through apt directly from the command line. If you
had installed an earlier tool, it is ignored by apt.

$ sudo apt update

$ sudo apt install cmake gcc-arm-none-eabi build-essential①

1. To compile pioasm, elf2uf2, you need native gcc


and g++.

7
Chapter 3: Blinking a LED in C

Switching on a LED and turning it off is a typical


software program for hardware. This program is one
that is initiated in a new programming environment.
Learning to flash the LED is the first step of the
journey. In this chapter, you will learn to blink the
LED on-board the Raspberry Pi Pico attached to pin
25 of the RP2040.

3.1. Building “Blink”

Use the command directory to access pico-examples


from the earlier pico directory created to create a
build directory.

8
$ cd pico-examples

$ mkdir build

$ cd build

Let us assume that you cloned pico-sdk and pico-


examples repositories and position them beside
each other, create the PICO_SDK_PATH:

$ export PICO_SDK_PATH=../../pico-sdk

Also, prepare your cmake build directory with the


cmake .

$ cmake ..

Using PICO_SDK_PATH from environment ('../../pico-sdk')

PICO_SDK_PATH is /home/pi/pico/pico-sdk

-- Build files have been written to: /home/pi/pico/pico-examples/build

Note

Cmake will default to a Release build0with0compiler optimisations enabled and


debugging information removed. To0build a0debug version, runcmake -
DCMAKE_BUILD_TYPE=Debug...

9
There is an area prepared by CMake for the pico-
examples tree. It is this0place that you will build its
example applications0by typing make. Although we
are only changing0directory into the blink directory
as we are only0building blink before going ahead
with typing make

Tip

Invoking makewith -j4 will run four make0jobs in parallel to speed it up. A
Raspberry Pi 4 has 4 cores so-j4is a0reasonable number.

$ cd blink

$ make -j4 Scanning dependencies of target ELF2UF2Build

Scanning dependencies of target boot_stage2_original

[ 0%] Creating directories for 'ELF2UF2Build'

. [100%] Linking CXX executable blink.elf [100%] Built target blink

Now we have built the following:

● Blink. Elf, that the debugger will use.

10
● Blink uf2 that can be superimposed into the
RP2040 USB Mass Storage Device.

The binary prompts the microprocessor to blink the


on-board LED of the Raspberry Pi Pico connected to
GPIO25 of RP2040.

3.2. Load and run “Blink”

Mount software to load it on your RP2040 board,


which is the simplest method to load software as a
Mass Storage Device. With this simple action, you
can drag a file on the board to make the flash
happen. Connect your Raspberry Pi Pico to your
Raspberry Pi with a micro-USB cable. First hold
down the BOOTSEL button to change it into the USB
Mass Storage Mode.

Note

Loading code via the USB Mass Storage0method is great if you know
your program is going to work first0time, but if you are developing
anything new it is likely you will0want to debug it.

So you can also load your software on0to RP2040 using the Serial Wire
Debug interface, see Chapter 5. As well0as loading software this allows
you to; set breakpoints, inspect0variables, and inspect memory contents.

11
3.2.1. From the Desktop

The Raspberry Pi Pico will mount by itself on the


Raspberry Pi Desktop as a USB Mass Storage
Device. Once it has mounted, Drag-and-drop blink
uf2 on the Mass Storage Device. RP2040 rboots,
and unmounts as a Mass Storage Device.
Immediately the flash code begins to run.

If you are not following0these instructions on a Raspberry Pi Pico,


you may not have0a BOOTSEL button, seeFigure 1. If this is the case,
you should0check if there is some other way grounding the
flashCSpin, such as a jumper, to tell RP2040 to0enter the BOOTSEL
mode on boot. If there is no0such method, you can load code using
the Serial Wire Debug interface.

fig 1

3.2.2. Using the command line

12
The only way to manually mount0the mass storage
device is when you0are logged in via ssh:

$ dmesg | tail

[ 371.973555] sd 0:0:0:0: [sda] Attached SCSI removable


disk

$ sudo mkdir -p /mnt/pico

$ sudo mount /dev/sda1 /mnt/pico

If you checked the /mnt/pico directory and see


some files in there, it means one thing, that your
USB Mass Storage Device has been mounted
successfully.

Copy the blink. Uf2 on your RP2040:

$ ls /mnt/pico/

INDEX.HTM INFO_UF2.TXT

sudo cp blink.uf2 /mnt/pico


13
sudo sync

Since your code is still running, although RP2040 is


no longer a USB Mass Storage Device, and to keep
your programming environment decluttered, go
ahead to unmount.

sudo umount /mnt/pico

Note

Removing power from the board does0not remove the code. When the
board is reattached to power the0code you have just loaded will begin
running again. If you want to0remove the code from the board, and
upload new code, press and0hold the BOOT SEL switch when applying
power to put the board0into Mass Storage mode.

3.2.3. Aside: Other Boards

If you didn’t go with the instructions on a Raspberry


Pi Pico, this may mean you don’t have a BOOTSEL
button (as designed in Figure 1).

It also means your board may have another option


of loading code, which we assume the board
supplier should have clearly documented:

14
• The SWD interface is being exposed in most
boards, (Chapter 5) and this can reset the board
and have the code loaded without you pressing any
button.

• There are different ways to take down the flash CS


pin (and that is exactly how the BOOTSEL button
works on the PI Pico. And this includes a pair of
jumper pins which you can easily short together.

• A few boards will come with a reset button, but


without BOOTSEL, and may come with some code in
flash to detect a doublepress of the0reset button
and enter the bootloader in this way.

In all cases you0should consult the documentation


for the specific board you are using, 0which should
describe the best way to load firmware0onto that
board.

3.2.4. Aside: 0Hands-free Flash


Programming

To enter BOOTSEL mode on your0Raspberry Pi Pico,


and load code over USB, 0you need to hold the
BOOTSEL button

15
down, and then reset the0board in some way. You
can do this by0unplugging and plugging0the USB
connector, or adding

an external button to pull0the RUN pin to ground.

You can also use the0SWD port (Chapter 5) to reset


the board, load0code and set the processors
running, and0this works0even if your code has
crashed, so0there is no need to manually reset the
board0or press any buttons. Once you are all set

up with building programs, 0and you have tried the


Hello World example in0the next chapter (Chapter
4), setting up SWD is a good0next step.

If you are on a Raspberry0Pi, you can set up SWD


by running the0pico-setup script (Chapter 1), and
connecting 3 wires from your0Pi to the Pico as
shown in Chapter 5. A0USB to SWD debug probe
can also be used, for0example Appendix A shows
how one0Pico can be0used to access the SWD port
of a second Pico0via the first Pico’s USB port.

16
Chapter 4: Saying “Hello World” in C

Developers and eager programmers like to create


and use a serial port once they learn to toggle the
LED on and off, eventually learning to be interactive
with the “Hello World” feedback.

4.1. Serial input and output on Raspberry Pi


Pico

The default Raspberry Pi Pico0UART TX pin0(out from Raspberry Pi Pico) is


pin GP0, and the UART RX pin0 (in0to Raspberry Pi Pico) is pin GP1. The
default UART pins are0configured on a per-board basis using board
configuration files. The Raspberry Pi Pico0configuration0can be found in

17
https://github.com/raspberrypi/pico
sdk/tree/master/src/boards/include/boards/pico.h. The0Pico0SDK
defaults to a board name of0Raspberry Pi Pico if no other board is
specified.

Althouh stdio and printf will run the default


Raspberry Pi Pico UART0, you can direct your stdin
(serial input) and stdout (serial output) to a serial
UART or USB CDC (USB serial) Important

The Pico SDK controls its own build system with


CMake from the pico_stdlib interface library to sum
up pertinent source files for particular actions.

Use the CMAke directory to change the path of


stdout, with output channeled to UART or USB CDC

18
1. Allow printf output through USB CDC (USB
serial).
2. Disallow printf output through UART.

The destination for stdio from UART to USB can be


changed without altering the C source code.

19
4.2. Create “Hello World”

Change hello_world directory and place it within the


pico-example tree, hust like the “Blink” example.
Run make

These lines of codes will create two separate


examples of programs in the hello_world/serial/ and
hello_world/usb/ directories.

Apart from other targets that we have, we have


created this path;

● Serial/hello_serial.elf, that the debugger uses.


● Serial/hello_serial.uf2 that can be dragged on
RP2040 USB Mass Storage Device (UART serial
binary).
20
● Usb/hello_usb.elf, that is used by the
debugger.
● Usb/hello_usb.uf2, that can be dragged on the
RP2040 USB Mass Storage Device (USB serial
Binary). Hello_serial channels stdio to UART0
on GP0 and GP1 pins; hello_usb channels stdio
to USB CDC serial.

4.3. Flash and Run “Hello World”

With a micro USB cable, connect your Raspberry Pi


Pico to your Raspberry Pi. Long-press the BOOTSEL
button to change it into the USB Mass Storage
Mode. Release the BOOTSEL button after it is
connected, although connection should be automatic
on the Raspberry Pi Desktop. You can drag-and-
drop the hello_serial.uf2 or hello_usb.uf2 on the
Mass Storage Device.

Immediately RP2040 reboots and unmounts as a


Mass Storage Device, and the flash code begins to
run. The text is invisible at the moment although
the “Hello World” line of code is running. Connect
your host computer to the standard UART on the
Raspberry Pi Pico to see what comes out.
21
4.4. see “Hello World” USB output

With the hello_usb.uf2 binary dropped where it is


supposed to be, the “Hello World” text goes to the
USB serial.

The text installs minicom once your Raspberry Pi


Pico is connected to your Raspberry Pi through the
USB.

$ sudo apt install minicom

Select and open the serial port:

22
There you go! Hello, world! Is printed boldly on the
console.

Tip

4.5. See “Hello World” UART output

If you dragged and dropped the hello_usb.uf2


binary, the “Hello World” text is channeled to UART0
on GP0 and GP1 pins. First, before you can see any
text displayed, enable UART serial communications
on the Raspberry Pi host. Run the raspi-config.

Select Interfacing Options > Serial and click “No”


when you are prompted; “Would you like a login
shell to be accessible over serial?” select “Yes” once
this prompt; “Would you like the serial port

23
hardware to be enabled?” check out the picture
below to see what happens.

Tap “Yes” with the raspi-config. Reboot your


Raspberry Pi to allow the serial port functionality.
Wire the Raspberry Pi and the Raspberry Pi Pico
together with the following mapping:

Raspberry Pi Raspberry Pi Pico

GND (Pin 14) GND (Pin 3)

GPIO15 (UART_RX0, GP0 (UART0_TX, Pin


Pin 10) 1)

GPIO14 (UART_TX0, GP1 (UART0_RX, Pin

24
Pin 8) 2)

With the boards joined together, now it is time to


install minicom,

That is if you have not done so already:

Open the serial port:

25
Once you toggle the power to Raspberry Pi Pico,
Hello world stares at you from the console’s screen.

Tip

To exit minicom, useCTRL-Afollowed byX.

4.6. Powering the board

If you don’t want to power the board through the


USB, you can connect the Raspberry Pi’s pin to the
Raspberry Pi Pico VSYS pin through a diode. Under
normal conditions, the diode is a Schottky diode.

26
Connecting the 5V pin on Raspberry Pi to the
Raspberry Pi Pico VBUS pin is practical but not
recommended.

If you go ahead with it, the Micro USB becomes


useless. Although, there is an exception using the
Raspberry Pi Pico in USB host mode where the 5V is
connected to the VBUS pin.

The 3.3V pin is an OUTPUT pin that cannot be


converted to a power source for your Raspberry Pi
Pico. Note that it should NEVER be connected to a
power source.

27
Chapter 5: Debugging with SWD

Important

These instructions assume that you0are using a Raspberry Pi Pico, details


may differ if you are using an0alternative RP2040-based board.

There is a SWD (Single Wire Debug) port which


interacts with binary programs0on the RP2040. If
you want to use this0special feature, it requires a
special debug version of your binary program and
the installation of extra tools.

5.1. Create “Hello World” debug version

Create “Hello World” debug version using the


CMAKE_BUILD_TYPE=Debug like the one shown
below,

28
5.2. Installing OpenOCD

OpenOCD is a debug translator that let a host


system load, run, and debug software on RP2040,
including greater interaction with hardware
registers. Using several hardware interfaces on the
RP2040 SWD port, direct bitbanging on Raspberry Pi
GPIOs is one of the hardware features of OpenOCD,
among others.

But there is a basic configuration to the hardware


connection, and that is having SWDIO on Pi GPIO
24, and SWCLK on GPIO 25. The good thing is that
the configuration can be wired to a Raspberry Pi
Pico following the Mapping below.

Alternatively, to get the signal integrity that you


want, wiring the SWD port through a breadboard or
indirect methods only reduce the signal integrity.
Wiring the SWD port directly to the Raspberry Pi
ensures that your codes are loaded on the
connection smoothly.
29
Another important wiring is the ground wire (0v),
especially a direct connection between the two, and
not relying or going with another ground route.

Note: To debug, Raspberry Pi Pico is powered,


among other means by USB. The OpenOCD branch
is created to work closely with the SWD support.

These instructions assume you want to build openocd


in/home/pi/pico/openocd

Note

$ cd ~/pico

$ sudo apt install automake autoconf build-essential


texinfo libtool libftdi-dev libusb-1.0-0- dev

$ git clone https://github.com/raspberrypi/openocd.git --


recursive --branch rp2040 --depth=1

$ cd openocd
$ ./bootstrap

$ ./configure --enable-ftdi --enable-sysfsgpio --enable-


bcm2835gpio

$ make -j4

$ sudo make install

5.3. Installing GDB

Install gdb-multiarch

30
$ sudo apt install gdb-multiarch

5.4. Use GDB and OpenOCD to debug Hello


World

The chip can be attached to OpenOCD to make sure


your Raspberry Pi 4 and Raspberry Pi Pico are wired
together perfectly. This is done through the
raspberrypi-swd interface.

$ openocd -f interface/raspberrypi-swd.cfg -f target/rp2040.cfg

Below is what your output looks like

... Info : rp2040.core0: hardware has 4 breakpoints, 2 watchpoints

Info : rp2040.core1: hardware has 4 breakpoints, 2 watchpoints

: starting gdb server for rp2040.core0 on 3333

Info : Listening on port 3333 for gdb connections

Warning

If you see an error likeInfo : DAP init failedthen your Raspberry Pi Pico is either
powered off, wired incorrectly, or has signal integrity issues. Try different
GPIO jumper cables.

$ cd ~/pico/pico-examples/build/hello_world

$ gdb-multiarch hello_world.elf

31
Leave this OpenOCD terminal open. First, open
another terminal where you attach a gdb extension
to OpenOCD. Go to the “Hello World” example
earlier and introduce gdb into the command line.

Use the line of code below to connect GDB to Open


OCD

(gdb) target remote0localhost:3333

Tip

You can create a.gdbinitfile so you don’t0have to typetarget remote


localhost:3333every time. Do this0withecho "target remote
localhost:3333" > ~/.gdbinit. However, this0interferes with debugging in
VSCode (Chapter 6).

Load hello_world.elf into flash

(gdb) load

Loading section .boot2, size 0x100 lma 0x10000000

Loading section .text, size 0x22d0 lma 0x10000100

Loading section .rodata, size 0x4a0 lma 0x100023d0

Loading section .ARM.exidx, size 0x8 lma 0x10002870

Loading section .data, size 0xb94 lma 0x10002878

Start address 0x10000104, load size 13324

32
Transfer rate: 31 KB/sec, 2664 bytes/write.

And get the code running.

If any error shows up that is the0same Error finishing flash operation or Error
erasing flash with vFlashErase packet in GDB as0you attempt to load the
binary onto the0Raspberry Pi Pico0via OpenOCD then there is likely poor
signal integrity between the0Raspberry Pi and the Raspberry Pi Pico.

If you are not directly0connecting the SWD connection0between the two


boards, see Figure 7, you should try to do that. 0Alternatively you can try
reducing the value0of adapter_khz in0the raspberrypi-swd.cfg configuration
file, trying halving it until you see a successful0connection between the
boards. As we’re bitbanging between0the0boards timing is marginal, so poor
signal integrity0may cause errors.

Before running the executable, you may set a


breakpoint at main() with the line of code below:

Once you hit the breakpoint and before you


proceed, run the continue line of code:

33
To leave the gdb mode, run the line of code below:

34
Chapter 6: Using Visual Studio Code

The popular open-source editor developed by


Microsoft is the best Integrated Development
Environment (IDE) to get a graphical feedback as
you edit and debug your lines of code on the
Raspberry Pi 4.

6.1. Installing Visual Studio Code

Important

These installation instructions rely on0you already having downloaded and


installed the command line0toolchain, see Chapter 3, as well as
downloading and building0both OpenOCD and GDB and configuring them
for command line0debugging, see Chapter 5.

Get the ARM versions of Visual Studio Code from


https://code.visualstudio.com/ Download for your
Raspberry Pi. Download the ARM.deb file for a 32-
bit operating system like the basic Raspberry Pi Os.
For a 64-bit operating system, download the ARM
64 .deb file. When the download is completed, click
on the .deb package twice using the instructions to
complete installation.

35
Use the .deb package on the command line .cd to a
folder path the file was downloaded, install with
dpkg -i<downloaded file name. deb>

After installation has been completed, install


necessary extensions to debug Raspberry Pi Pico:

code --install-extension marus25.cortex-debug

code --install-extension ms-vscode.cmake-tools

code --install-extension ms-vscode.cpptools

Launch Visual Studio Code from a terminal window:

$ export PICO_SDK_PATH=/home/pi/pico/pico-sdk

$ code

Set the PICO_SDK_PATH to allow Visual Studio


Code discover the Pico SDk

6.2. Loading a Project

Go to the Explorer toolbar ( Ctrl + Shift + E), click


Open Folder and go to /home/pi/pico-examples in
the file popup. These are the steps to optn the pico-
examples folder. Click “OK” to load the Folder into
VSCode.

36
There is a popup close to the base of the vscode
window. If you do not see it, that means CMake

Tools extension is not installed on your computer. If


everything looks good, hit “Yes” to configure the
project. You will be requested to use a compiler
from a prompt.

Choose GCC for arm-none-eabi on the drop-down


menu.

Tip

If you miss the popups that close0after a few seconds, configure the
compiler through the “No0Kit Selected” in the blue bottom of the VScode.

37
Do one of these things; click on the “Build” button
to build the examples in the pico-examples folder
just below the blue bottom bar, or tap where you
see “[all]” in the blue bottom bar.

The second alternative gives you a drop down to


select a project. At the moment, type in
“hello_world” and choose the “Hello World”
executable. By choosing this option, VScode runs
the “Hello World” example saving you and the
compiler time.

Tip

You can toggle between building "Debug"0and "Release" executables by


clicking on where it says "CMake: [Debug]: 0Ready" in the blue bottom bar.
The default is to build a "Debug"0enabled executable ready for SWD
debugging.

Tap on the “Build” button, the one with the cog


wheel symbol at the base of the blue bar on the
window. The build directory is created where you
can run CMake like we did earlier in Section 3.1,
before going to the build itself.

38
The projects below have been created just like what
we did from the command line the other time
among other things

● Hello_world.elf that is used by the debugger


● Hello_world.uf2 that can be dragged on the
RP2040 USB Mass Storage Device.

39
6.3. Debugging a Project

OpenOCD will launch by itself because the Pico-


examples has a debug configuration that also
attaches GDB and the application that CMake has
been configured to create. Copy this file (launch-
raspberrypi-swd.json) directly into the pico-
examples/.vscode directory as launch.json. there is
another file of importance, which is the settings.json
file that you should copy. Settings.json gets rid of
options that may increase your confusion from the
CMake plugin (which includes a broken Debug and
Run buttons that superimpose the Pico binary on a
host).

$ cd ~/pico/pico-examples

$ mkdir .vscode

$ cp ide/vscode/launch-raspberrypi-swd.json .vscode/launch.json

$ cp ide/vscode/launch-raspberrypi-swd.json .vscode/settings.jso

1{

2 "version": "0.2.0",

3 "configurations": [

4 {

5 "name": "Pico Debug",

40
6 "cwd": "${workspaceRoot}",

7 "executable": "${command:cmake.launchTargetPath}",

8 "request": "launch",

9 "type": "cortex-debug",

10 "servertype": "openocd",

11 // This may need to be arm-none-eabi-gdb depending on your system

12 "gdbPath" : "gdb-multiarch",

13 "device": "RP2040",

14 "configFiles": [

15 "interface/raspberrypi-swd.cfg",

16 "target/rp2040.cfg"

17 ],

18 "svdFile": "$
{env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",

19 "runToMain": true,

20 // Work around for stopping at main on restart

21 "postRestartCommands": [

22 "break main",

23 "continue"

24 ]

41
25 }

26 ]

27 }

Note

You may have to amend thegdbpathin launch.json if your gdb is calledarm-none-eabi-


gdbinstead ofgdb-multiarch

6.3.1. Running “Hello World” on the Raspberry

Pi Pico

Ensure that the example "Hello World" code has been as a Debug binary (CMAKE_BUILD_TYPE=Debug).

Important

Press Ctrl + Shift + D to go to the Debug toolbar


where you click the small green arrow which is the
play button at the top of the window pane to load
your code on the Raspberry Pi Pico and debug.

42
Now that the code is loaded and displayed on your
Raspberry Pi Pico, the source code for “Hello World”
should also be displayed on the upper pane of the
window. The code runs and go to the first
breakpoint which is enabled by the runToMain
directive found int the Launch.json file. Tap the
small blue arrow or the play button above the
source code window to Continue (F5) and get the
code working.

43
Tip

If you switch to the "Terminal" tab in the0bottom right-hand


pane, below thehello_world.ccode, you can0use this to
openminicominside VSCode to see the0UART output from the
"Hello World" example0by typing,

$ minicom -b 115200 -o -D /dev/serial0

at the terminal prompt as0we did before, seeSection 4.5.

44
Chapter 7: Creating your own Project

First create a directory to save your experimental


project somewhere beside the pico-sdk directory.

Create a test.c file in the directory

45
1. The line of code above enables serial output via
the USB.
2. The second one allows serial output via the
UART.

Once you are done, copy the


pico_sdk_import.cmake file from the external folder
in pico-sdk installation directory to the project’s
folder.

$ cp ../pico-sdk/external/pico_sdk_import.cmake .

46
Here is what everything looks like

$ mkdir build
$ cd build

$ export PICO_SDK_PATH=../../pico-sdk

$ cmake ..

$ make

Using the earlier “Hello World” example, we can


now build it as a prototype.

The new project will create different files. The


important files are displayed in the table below.

File extension Description

.bin Raw binary dump of the


program code and data

.elf The full program output,


possibly including debug
information

.uf2 The program code and


data in a UF2 form that
you can drag-and-drop on
to the RP2040 board
when it is mounted as a

47
USB drive

.dis A disassembly of the


compiled binary

.hex Hexdump of the compiled


binary

.map A map file to accompany


the .elf file describing
where the linker has
arranged segments in
memory

Note

UF2 (USB Flashing Format) is a file0format, developed by Microsoft, that is


used for flashing the RP2040 board over USB. More0details can be found on
theMicrosoft UF2 Specification Repo

48
Note

To build a binary to run in SRAM,0rather than0Flash memory you can


either setup your cmake build0with-DPICO_NO_FLASH=1or you can add
pico_set_binary_type(TARGET_NAMEno_flash)to control it on a per binary basis in your
CMakeLists.txt file. You can0download0the RAM binary to RP2040 via UF2.
For example, if there is no flash0chip on your board, you can download a
binary that runs0on the0on-chip RAM using UF2 as it simply specifies
the0addresses of where0data goes. Note you can only download
into0RAM or FLASH,notboth.

7.1. debugging your project

Using the same “Hello World” example, use a similar


approach to debug your project from the command
line. First, connect your Raspberry Pi Pico and the
Raspberry Pi Pico.

49
Use the CMAKE_BUILD_TYPE=Debug to create a
debug version of your project.

$ cd ~/pico/test

$ rmdirbuild

$ mkdirbuild

$ cd build

$ export PICO_SDK_PATH=../../pico-sdk

$ cmake -DCMAKE_BUILD_TYPE=Debug ..

$ make

Open a terminal window to attach the OpenOCD


with the raspberrypi-swd interface.

$ openocd -f interface/raspberrypi-swd.cfg -f
target/rp2040.cfg

50
Leave the OpenOCD terminal open. Open another
terminal window to implement the gdb-multiarch
function with the command line below:

$ cd ~/pico/test/build

$ gdb-multiarch test.elf

Connect GDB to OpenOCD and tap the test.elf


binary extension to load into flash.

(gdb) target remote localhost:3333

(gdb) load

Allow it run.

(gdb) monitor reset init

(gdb) continue

7.2. Working in Visual Code

You may have to check Chapter 6 for instructions


about configuring the Visual Studio Code
environment to load a new project as opposed to
loading directly from the command line. This one is
a great option for those that like to write and build
code in a development environment.
51
If you are interested in debugging and loading your
code onto the Raspberry Pi Pico from the Visual
Studio Code, you must create a launch.json file for
your project. Use the launch-raspberrypi-swd.json
example in Chapter 6 for this one. First, copy it into
your project directory as .vcode/launch.json.

7.3. Automating project creation

To automate your project to create a “clone” project


which is side-by-side with your creative efforts, just
use the automation feature which requires cloning
the project script directly from its Git repository

$ git clone https://github.com/raspberrypi/pico-project-


generator.git

The clone is then presented in a graphical mode:

$ cd pico-project-generator

$ ./pico_project.py --gui

This script displays a GUI interface that provides a


visual feedback as you configure your project.

52
From here, include specific features to your project
by identifying them from the check boxes on the
GUI. The build system automatically includes the
right code to the project you are creating, including
a basic example of the code describing how the
feature can be used. There are several options
available that also describes functionality such as
the one below:

53
Console Options Description

Console over UART Enable a0serial


console over
the0UART. This is the
default.

Console over USB Enable a0console over


the USB. 0Thedevice
will act as a0USB
serial port. This0can
be used in addition to
or instead0of the
UART0option, but note
that0when enabled
other0USB
functionality is
not0possible.

Code Options Description

Add examples for Pico Example0code will be


library generated for some
of the0standard

54
library features
that0by default are in
the0build, for
example, 0UART
support and HW
dividers.

Run from RAM Usually, the0build


creates a0binary that
will be0installed to
the flash0memory.
This forces the
binary0to work
directly0from RAM

Advanced Brings up0a table


allowing0selection
of specific0board
build options. These
options0alter the
way the0features
work, and should
be0used with

55
caution.

Build Options Description

Run Build Once the project has


been created, build it.
This will0produce files
ready0for download to
the Raspberry Pi Pico.

Overwrite Project If a
project0already
exists in the
specified folder,
0overwrite it with
the0new project.
This will overwrite
any changes
you0may have
made.

Create VSCode Project As well as0the CMake


files, also0create the

56
appropriate Visual
Studio0Code project
files.

7.3.1. Project generation from the command


line

The script below allows you to create your project


straight from the command line

$ export PICO_SDK_PATH="/home/pi/pico/pico-
sdk"
$ ./pico_project.py --feature spi --feature
i2c --project vscode test

To add specific library code to the build, use the -


feature options. There is an example code that
demonstrates the use of the feature options. From
here, you may include several features stretching
the limit of RP2040 storage capacity.

Also, have a list of all available features using the -


list option of the script. The command line example
shown above includes a support for the I2C and SPI
interfaces.

57
One feature that let you know that your -project
option feature is successful is the creation of
.vscode/launch.json, .vscode/c_cpp_properties.json,
and .vscode/settings.json files apart from the
normal CMake project files.

Once the feature files and other necessary files have


been created, you can start building your project
from the command line

$ cd test/build

$ cmake ..
$ make

Or from the Visual Studio Code directly. Use the -


help option to see a list of command line
permutations that become useful using the
graphical mode.

58
Chapter 8: Building on other

platforms

Apart from the major platform, which is the


Raspberry Pi on the RP2040, there are other
platforms such as Apple macOS and Microsoft
Windows, that are open to developers to create and
build projects.

8.1. Building on Apple macOS

Building projects using codes on macOS for RP2040


is an experience akin to that on Linux.

8.1.1. Installing the Toolchain

To install, you have to download and install


Homebrew. If you already have it, you can skip this
stage.

$ /bin/bash -c "$(curl -fsSL

https://raw.githubusercontent.com/Homebrew/install/master
/install.sh)"

59
Install the toolchain

$ brew install cmake

$ brew tap ArmMbed/homebrew-formulae


$ brew install arm-none-eabi-gcc

Raspberry Pi has made every other thing simple as


long as you can use its instructions to build code for
the RP2040. With the toolchain now installed, you
will discover that there are not dissimilarities
between macOS and Linux. Check Section 2.1 and
use the instructions there to get the Pico SDK and
create the “Blink” example.

8.1.2. Using Visual Studio Code

You will find Visual Studio Code for macOS, Linux,


and Microsoft Windows as it is largely a cross
platform environment. Check and download the
macOS version that is available, unzip and drag it to
your Applications Folder. Go to Applications and tap
the icon to launch the Visual Studio Code.

60
8.1.3. Building with CMake Tools

Launch the Visual Studio Code environment and


install the CMake Tools extension. Tap the Extension
icon placed in the toolbar on the left, or use CMD +
SHIFT + X. search for “CMake Tools” and tap on the
list to install your preference.

After installing the extension, now it is time to


create the PICO_SDK_PATH variable. Go to the
pico-examples directory to create a. vscode
directory and add a file settings.json which instructs
CMake Tools the location of the Pico SDK.

{ "cmake.environment": {

"PICO_SDK_PATH":"../../pico-sdk" }, }

The next thing you want to do is to click on the Cog


Wheel located at the very bottom of the navigation
bar on the left-hand side of the interface. Then
choose "Settings".

When you’re in the settings pane, ensure you click


on click on "Extensions" as well as the "CMake
Tools configuration".

61
After that, scroll down to

"Cmake: Generator" and then enter "Unix


Makefiles" into the box

Based on your local setup, you are not actually


required to manually set the CMake generator to
"Unix Makefiles".

But, if you fail to do so, in few cases, Visual Studio


will default to ninja instead to make and this may
cause the build to fail.

If you’re in a situation where you need to manually


configure this variable, then you have to try taking
a possible step to point Visual Studio at the CMake
Tools extension plainly. You can do this if you add
the an additional line to your settings.json file,

{ "cmake.environment": {

"PICO_SDK_PATH": "../../pico-sdk" },

"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools" }

Return to the File menu and select “Add Folder to


Workspace…” go to the Pico-examples repo and tap
“Okay.”

62
Soon you will receive a prompt as the project loads
requesting to select a compiler. Tap “GCC for arm-
none-eabi” for your compiler.

Select the “Build” button, with the cog wheel symbol


in the blue bar of the window. Clicking this feature
creates the build directory allowing CMake to launch
like we did earlier before the build itself
commenced, see Figure 8.

This action produces ELF, bin, and Uf2 targets.


These targets are found in the hello_world directory
in the new build directory.

63
Drag-and-drop the uf2 binary on the RP2040 board
directly once your computer is linked to it with a
USB.

8.1.4. Saying “Hello World”

As long as you have stdio channeled to a USB CDC


(SERial) or UART0 on GP0 and GP1 pins, you can
build the Hello World example all the time. You
don’t even need a driver installation when building
with USB CDC as the target output because it is a
class compliant device. Run with a terminal
program, the likes of Serial or something similar to
connect to the USB serial port.

8.1.4.1. UART output

If you are connecting to the Raspberry Pi Pico UART


to check the output, although it is not necessary,
you may have to connect your Raspberry Pi Pico to
your Mac with a serial converter (USB to UART) an
example is the SparkFUn FTDI Basic board.

64
You may have to check the manufacturer’s website
for FTDI Chip Drivers if you are not using a recent
version of macOS such as Catalina, where the
drivers load up by itself automatically. To connect
the serial port once you are not running the
platform on the latest software, use a Terminal
program such as Serial or something similar. Don’t
forget that Serial includes driver support.

8.2. Building on MS Windows

Installing the toolchain is very unique on Microsoft


Windows; the installation is different to other
platforms.

65
Once you install the building code for RP2040, you
realize that it is similar to other platforms.

8.2.1. installing the Toolchain

The extra tools that you need to start building are;

● ARM GCC compiler


● CMake
● Build Tools for Visual Studio 2019
● Python 3
● Git

All you need is to download the executable installer


for these tools, and install the five packages on your
Windows machine.

8.2.1.1. Installing ARM GCC Compiler

66
Figure 14. ensure that you register the path to the
compiler when installing the required tools to your
Windows machine as an environment variable to be
accessed directly from the command line. Tick the
box to register the path to the ARM compiler during
installation to identify it as an environment variable
inside the Windows with the prompt displayed.

8.2.1.2. Installing CMake

Add CMake to the system PATH during installation


for all users once the installer requests you to do
so.

8.2.1.3. Installing Visual Studio Code

67
Wait for the prompt to install the C++ build tools
during the Build Tools for Visual Studio installation.

8.2.1.4. Installing Python 3

You will also need to add Python 3.7 to the system


PATH for all users once you receive the prompt from
their installers. Also, disable the MAX_PATH length
from the prompt displayed at the end of the Python
installation.

Select “Customize installation” when installing


Python and go through the “Optional Features” and

68
select “Install for all users” from “Advanced
Features.”

Note

You may have to make a symbolic link0so that the Makefile can find
Python 3. To do so typecmdin the Run0Window next to the Windows Menu
to open a Developer Command0Prompt Window but select "Run as
administrator" in the right0hand pane to open the window with
administrative privileges. Then0navigate toC:\Program Files\Python37and make a
symlink.

C:\Program Files\Python37> mklink python3.exe python.exe

Thisshouldno longer be necessary. However if0your build fails because


make can’t find your Python installation0you should add the symlink to
the executable. That may0resolve things.

8.2.1.5. Installing Git

Change the default editor from vim when you are


installing Git.

69
It is very important to tick the checkbox to allow Git
to be used from third-party tools, although you can
disallow this feature when you are not comfortable
with it. During Git installation, check the “Checkout
as is, commit as-is”, click the “Use Windows’ default
console window.” Also check the “Enable
experimental support for pseudo consoles” during
installation.

8.2.2. Getting the Pico SDK and examples

C:\Users\pico\Downloads> git clone -b master


https://github.com/raspberrypi/pico-sdk.git

C:\Users\pico\Downloads> cd pico-sdk

70
C:\Users\pico\Downloads\pico-sdk> git submodule update --init
C:\Users\pico\Downloads\pico-sdk> cd ..

C:\Users\pico\Downloads> git clone -b master


https://github.com/raspberrypi/pico-examples.git

8.2.3. Building “Hello World” from the


Command line

Launch a Developer Command Prompt Window on


the Windows Menu. First select Windows > Visual
Studio 2019 > Developer Command Prompt on the
menu.

Create the path to the Pico SDK with this line of


code:

C:\Users\pico\Downloads> setx PICO_SDK_PATH "..\..\pico-sdk"

Close your active Command Prompt Window. Open


another one where the environment variable is now
available in the right order. Go to the pico-examples
folder, and use the “Hello World” example to build.

C:\Users\pico\Downloads> cd pico-examples

C:\Users\pico\Downloads\pico-examples> mkdir build

C:\Users\pico\Downloads\pico-examples> cd build

71
C:\Users\pico\Downloads\pico-examples\build> cmake -G "NMake
Makefiles" ..

C:\Users\pico\Downloads\pico-examples\build> nmake

The line of command above will build the target and


produce the ELF, bin, and uf2 targets. These targets
are located in the hello_world directory in your build
directory. If your computer and RP2040 board are
connected via a USB, simply drag-and-drop the Uf2
binary on the RP2040 board.s

8.2.4. Building “Hello World” from Visual


Studio Code

After installing the toolchain, install Visual Studio


Code and build your awesome projects with the
coding environment rather than the command line.
Download and install Visual Studio Code for
Windows. Launch a Developer Command Prompt
Window from the Windows Menu once

Installation is completed. Select Windows > Visual


Studio 2019 > Developer Command Prompt on the
menu. And input this line:

C:> code

72
This line is entered once a prompt requesting it is
displayed. The environment variables in the right
order are opened in the Visual Studio Code allowing
the toolchain to be configured well.

If you start Visual Studio code by0clicking0on its desktop icon, or directly
from the Start Menu then0the build0environment will not be correctly
configured. Although this can be0done manually0later in the CMake Tools
Settings, the easiest way to0configure the VisualStudio Code environment
is just to0open it from a0Developer CommandPrompt Window where
these environmental0variables0are already set.

Warning

First the CMake Tools extension will be installed.


Select the Extension icon in the left-hand toolbar
using the CTRL + SHIFT + X to search for “CMake
Tools”. Choose from an entry in the list and tap the
install button.

Go over to the Cog wheel at the base of the


navigation bar on the left-side of the interface and
click “Settings”. Tap “Extensions” and the “CMake
Tools configuration”. Just below, you will find
Cmake: Configure Environment”.

73
Return to the File menu and select the “Open
Folder” towards pico-examples repo. Tap “Okay”
and wait for a prompt requesting the configuration
of your project. Once it appears, click “GCC for arm-
none-eabi” as the compiler.

74
Tap the “Build” button, the one with the cog wheel
in the blue bar. It creates a directory for your
projects, runs CMake and clones the project
examples, including “Hello World”.

The new directories contain ELF, bin, and uf2


targets that are available inside the hello_world
directly inside the fresh build directory. Drag-and-
drop the Uf2 binary on the RP2040 board that is
connected to your computer with the USB.

75
8.2.5. Flashing and Running “Hello World”

Use a micro-USB cable to connect the Raspberry Pi


Pico to your Raspberry Pi.

When doing this, hold down the BOOTSEL button to


mount it literally and change it into USB Mass
STORage Mode. The board now appears as an
external drive where you can now drag-and-drop
the uf2 binary on the external drive.

Soon the Raspberry Pi Pico reboots and unmount as


an external drive, and immediately runs the flash
code.

Just like what happened in Chapter 4, the Hello


world example can be built once you route the stdio
to USB CDC (Serial) or to UART0 on GP0 and GP1
pins. You do not require any driver installation
especially with USB CDC as the target output
because it is a class compliant device.

8.2.5.1. UART output

If you want to connect to the Raspberry Pi Pico


standard UART to check out its output, you must
connect your Raspberry Pi Pico to your Mac with a
76
USB to UART Serial converter, an example is the
SparkFun FTDI Basic board described in Figure 13.

There is no need or requesting to install drivers on a


recent Windows OS like Windows 10 because the
important drivers are already loaded. If not check
the website of the manufacturer for FTDI Chip
Drivers.

C:> chgport

COM4 = \Device\ProlificSerial10

COM5 = \Device\VCP0

77
If the drivers are not available, download and install
PuTTY. Run and choose “Serial”, enter 115,200 as
the baud rate when you tap the “Speed” box. Also
tick the serial port for your UART converter.

Use the hgport command to discover the UART


converter of your board.

You will get a list of active serial ports. Check COM5


for the USB to UART Serial converter.

If you have multiple serial devices0and0can’t figure out which one is your
UART to USB serial converter, try0unplugging0your cable, and
runningchgportagain to see which0COM0port disappears.

Note

Input the speed and port data, click the “Open”


button and there you will see the UART output that
leads from your Raspberry Pi Pico to your Terminal
window.

78
Chapter 9: Using other Integrated

Development Environments

The recommended IDE is Visual Studio Code,


although you can use other environments with the
RP2040 and the Raspberry Pi Pico

9.1. Using Eclipse

Eclipse is a great IDE that is available on x86 Linux,


Mac and Windows. As a multiplatform IDE, you will
find its 64-bit ARM systems, which is the latest
version online or in stores.

They really work with the Raspberry Pi 4/400 range,


particularly 4 GB and recent versions with the 64-bit
OS. The instructions here describe the technicalities
to set up Eclipse on a linux device to run with the
Raspberry Pi Pico. The instructions to set up the
Raspberry Pi Pico on another software platform are
generic, although similar with connection methods
to Raspberry Pi Pico varying a little bit.

Check Section 8.2 and Section 8.1 for more


information for connecting non-Linux platforms.

79
9.1.1. Setting up Eclipse for Pico on a Linux
machine

Requirements

Device must have a recent version of Linux


including a RAM capacity of 4 GB,

64-bit operating system

CMake 3.11 or recent

Note

At present the 64-bit0Raspberry Pi OS is0still in beta test. The latest


beta0version can be0found here
http://downloads.raspberrypi.org/raspios_arm64/images/.

Other 64-bit Linux distributions can0also be used but are untested, for
example, Ubuntu for Raspberry Pi. 0Please follow the usual procedure for
installing an operating0system image on to your SD card.

Allow the standard UART using the config.txt syntax


particularly for Raspberry Pi

Enable_uart=1

Also install OpenOCD and the SWD debug system.


Check chapter 5 for more instructions about this

80
9.1.1.1. Installing Eclipse and Eclipse plugins

With the instructions provided, install the recent


version of Eclipse with Embedded CDT. Although
running on an ARM platform requires installing an
AArch64, which is the 64-bit ARM version of Eclipse.
Go to the website
https://projects.eclipse.org/projects/iot.embed-
cdt/downloads to get and download your own
version.

Download and extract the right file compatible with


your system. Pick and return to the extraction
location where you run the “eclipse” executable.

./eclipse

The C/C++ development kit and the Embedded


development kit are both the Embedded CDT
version of Eclipse that are available with the
complete tools and environment to develop and
build projects on Raspberry Pi Pico.

81
9.1.1.2. Using Pico-examples

CMake is the standard build system for the Pico


environment. Although Eclipse does not use CMake
by default since it uses its own build system.

First, the pico-examples for CMake projects to an


Eclipse project.

● Create a new folder just like the pico-examples


folder; an example is pico-examples-eclipse.
● Change the directory to that folder.
● Create a path of the directory to the
PICO_SDK_PATH

Export PICO_SDK_PATH=< wherever>

Enter the syntax below in the command line:

cmake -G"Eclipse CDT4 - Unix Makefiles" -D


CMAKE_BUILD_TYPE=Debug ../pico-examples

the Eclipse project files in out Pico-examples-eclipse


folder are created having a source from the CMake
tree. Open project From File System option inside

82
the menu on the file can now be used to load your
new project files into Eclipse.

9.1.1.3. Building

Right click on the project directly from project


explorer and choose Build. The examples are now
generated.

9.1.1.4. OpenOCD

the example here uses the OpenOCD system to


communicate with the Raspberry Pi Pico. As part of
the pre-requisite, attach the 2-wire debug
connections from the host device to the Raspberry
Pi Pico. Use GPIo connections on your Raspberry Pi,
although you will require more hardware to create
this connection with a laptop or desktop device. An
alternative is using a second Raspberry Pi Pico, this
time running the Picoprobe software described in
Appendix A. find more information on the debug
connections in Chapter 5.

With OpenOCD installed and the right connection


successfully done, Eclipse then should be set up to
talk to OpenOCD once programs begin to run. There

83
is a GDB interface to Eclipse on OpenOCD, and it is
there that the debugging is done.

To create the OPenOCD system, choose Preferences


inside the Window menu. Tap on MCU arrow to see
more options and select Global OpenOCD path.

Type “openocd” to execute the program. Choose the


location or path of the system that you cloned the
Pico OpenOcD fork from Github to retrieve the
folder.

9.1.1.5. Creating a Run configuration

First set up a Run configuration to run or debug


code in Eclipse.

84
The configuration put in place the information that
you need to identify the code that you will run,
parameters, the debugger, source paths and SVD
information.

Tap Run configurations from the Eclipse Run menu.


Choose GDB OpenOCD Debugging to create a
debugger configuration. Choose the New
Configuration button.

9.1.1.5.1. Setting up the application to run

The pico-examples directory and building projects


create several executable programs, you must
select the one to run or debug all by yourself. Click
the Browse on the Main tab of the Run
85
configuration page to choose the C/C ++
applications that you want to run. You will find the
executables created by Eclipse in the sub folders of
the Eclipse project folder, like this example;

…/pico-examples-eclipse/<name of example
folder>/<optional name of example
subfolder>/executable.elf

The LED blink example will be found at;

…/pico-examples-eclipse/blink/blink.elf

86
9.1.1.5.2. Setting up the debugger

Because the OpenOCD is used to interact with the


Raspberry Pi Pico, it must be set up for the task

Click openocd in the Executable box and Actual


Executable box. The OpenOCD also needs to be set
up to use the Pico specific configuration, make the
changes to the Config options. It is also important
to change the path to another location where the
Pico version of OpenOCD is installed.

-f interface/raspberrypi-swd.cfg -f target/rp2040.cfg

The other options and settings on OpenOCD should


be left at default values. GDB remains the major
debugger. The GDB communicates with the
Raspberry Pi Pico directly from the OpenOCD
debugger. And the good thing is that, there is a
standard interface directly on the IDE.

The version of GDB is gdb-multiarch which should


be entered into the Executable name and the Actual
Executable fields.

87
9.1.1.5.3. setting the SVD plugin up

SVD views and creates peripheral registers on the


Pico board. You will find locations, descriptions, and
the SVD plugin for Eclipse to further integrate its
features and functionality inside the Eclipse IDE.
The SVD plugin is a default tool that comes with the
Embedded development plugins. Click the SVD path
tab on the Launch configuration, inputting the
location on the file system the location of the SVD
file itself. Check out the pico-sdk source tree for the
path.

88
···/pico-sdk/src/rp2040/hardware_regs/rp2040.svd

9.1.1.5.4. Running the debugger

Launch the program once the Run configuration has


been completed and saved. The Run button is at the
base of the dialog. Click Apply to make changes and
Close the dialog. Use the Run Menu and the Debug
option to run the application.

Eclipse goes into debug showing several debug and


source code windows, including Peripherals that
uses the SVD data to give access to peripheral
registers. What you see is the standard Eclipse
debugging session.

89
9.2. Using CLion

JetBrains created the multiplatform IDE called


CLion, which is available on Linux, Mac and
Windows. Because it is a commercial IDE, you will
find it being used by professional developers, or
folks that love the JetBrains IDEs. You can get free
versions as well as licensed versions.

The IDE runs on any Raspberry Pi, which means


that you will run CLion on your laptop or desktop. It
is very easy to set up projects with the intuitive
IDE, although setting up debug with the platform
has a low engagement as it is still new.

90
9.2.1. Setting up CLion

Get CLion from https://www.jetbrains.com/ clion/


and install it.

9.2.1.1. Setting up a project

Pico-example project is the one that we will use as


our example. Click Open*** to access the pico-
examples project from the File menu, scroll through
and pick the pico-examples project from the
directory.

Pay attention to the bottom of this picture as CLion


wanted to load the CMake project, which led to an
error of path specification PICO_SDK_PATH.

91
9.2.1.1.1. Configuring CMake Profiles

Tap the Settings*** from the File menu, scroll down


and choose “CMake below Build, Execution,
Deployment.

Put the environment variable PICO_SDK_PATH


below Environment as described above in the
picture or create the environment syntax as -
DPICO_SDK_PATH=xxx below CMake options:. Both
syntaxes are basic command line arguments and
environment variables to call CMake directly from
the command line. It is also the place to specify
CMake settings such as PICO_BOARD,
PICO_TOOLCHAIN_PATH etc.

92
Create several CMake profiles with their unique
settings, and perhaps include Release build by
pressing the + button, and input the
PICO_SDK_PATH once more. Press the copy button
two towards the right to fix the name and settings
of the build profile.

Once you click OK, the feedback that you get is


similar to the one in the image below. Pay attention
to the two tabs on both profiles (Debug and
Release) at the base of the window. Here, Release is
enabled. The CMake setup was also successful.

93
9.2.1.1.2. Running a build.

Experiment with one or more targets. First, go to


the drop-down selector within the toolbar and type
hello_usb; tap the tool icon on the left to build a
project like the one in the figure below. Similarly, go
ahead with a full build of all targets that you have in
mind using the Build menu.

94
Use the drop-down selector to choose the target
you wish to build and a CMake profile to use which
is Debug or Release.

In the figure above, you will notice hello_usb and


Debug in the status bar. They are the target and
CMake profile used to manage syntax highlighting in
the editor. It selected itself automatically because
you had earlier selected hello_usb. In the stdio.c
file, you can see the activity of an earlier user,
especially with setting PICO_STDIO_USB or
PICO_STDIO_UART that are not included in the
hello_usb settings.

95
Which is interesting, because build time per binary
configuration of libraries is one ubiquitous feature of
the Pico SDK.

9.2.1.1.3. Build Artifacts

You will find the build artifacts under cmake-build-


<profile> just below the project root in the figure
below. It is also the cmake-build-debug directory.

The uf2 file can be moved into any RP2040 device in


BOOTSEL mode, and the ELF is used for debugging.

9.3. other environments

Building environments for Pico are inexhaustible


that cannot be fully described here, although most

96
of them are compatible with the Pico SDK. You will
need a few things to ensure that your IDE and
Raspberry Pi Pico go together:

● CMake integration
● Allowing GDB support with other remote
settings.
● SVD is not necessary, although with it, reading
peripheral status becomes easier.
● Extra ARM embedded development plugin –
with these plugins available, support becomes
easier.

9.3.1. Using openocd-svd

This tool is a python GUI utility that let you access


peripheral registers of ARM MCUs through a
combination of OpenOCD and CMSIS-SVD.

Install its dependencies before installing the


openocd-svd program.

$ sudo apt install python3-pyqt5

$ pip3 install -U cmsus-svd

97
After installation, clone the openocd-svd git
repository.

$ cd ~/pico

$ git clone https://github.com/esynr3z/openocd-svd.git

Once your Raspberry Pi 4 and Raspberry Pi Pico are

wired together, fix the OpenOCD through the swd


and rp2040 configuration channels.

$ openocd -f interface/raspberrypi-swd.cfg -f target/rp2040.cfg

Leave the OpenOCD terminal open. Launch a new


terminal and attach a gdb instance to OpenOCD.

Go to your project and begin gdb

$ cd ~/pico/test

$ gdb-multiarch test.elf

Connect GDB to OPenOCD,

(gdb) target remote localhost:3333

Load it into flash and get it running.

(gdb)0 load

(gdb) 0monitor reset init

(gdb) 0continue

98
Once openocd and gdb are running, open a third
terminal window where you launch the openocd-svd
directing it to the SVD file in the Pico SDK.

$ python3 openocd_svd.py /home/pi/pico/pico-


sdk/src/rp2040/hardware_regs/rp2040.svd

Another openocd-svd window opens. Go to the File


menu and select the “Connect OpenOCD” to connect
through telnet to one of the running openocd target.

The telnet connection inspects the registers of the


running codes on your Raspberry Pi Pico, as shown
in the figure below.

99
100
Appendix A: Using Picoprobe

Debugging another Pi Pico with a Raspberry Pi Pico


sounds impractical, but it is very possible. Get an
application called picoprobe that simulates a
Raspberry Pi Pico as a USB > SWD and UART
converter. With this emulator program, Raspberry Pi
Pico can be used on other unsupported platforms
such as Windows, Mac, and Linux computers
without the GPIos pins.

101
A.1. Build OpenOCD

Create openocd terminals and enable the picoprobe


driver for picoprobe to work.

$ cd ~/pico

$ sudo apt install automake autoconf build-essential


texinfo libtool libftdi-dev libusb-1.0-0- dev

$ git clone https://github.com/raspberrypi/openocd.git --


branch picoprobe --depth=1

$ cd openocd

$ ./bootstrap

$ ./configure --enable-picoprobe①

$ make -j4

$ sudo make install

A.1.1. Linux

1. Use this syntax –enable-sysfsgpio -enable-


bcm2835gpio to enable btbanging SWD through
the GPIO pins, it is an extra option when you are
building on a Raspberry Pi.

A.1.2. Windows

We are going to use MSYS2 to make building


OpenOCD very convenient. MSYS2 is a huge
collection of tools and libraries that creates a
102
convenient building environment to install and run
native Windows software.

Check https://www.msys2.org/ to download and


run the installer.

First, update the package database and core system


packages using this script:

pacman -Syu

Your MYSYS2 may force-close, there is no need to


panic. Restart it and ensure that you picked the 64-
bit version before running:

pacman -Su

103
Install the necessary dependencies to complete the
update

pacman -S mingw-w64-x86_64-toolchain git make libtool


pkg-config autoconf automake texinfo mingw-w64-x86_64-libusb

Select all programs, especially the mingw-w64-


x86_64 toolchain during installation. Press enter
when you are done.

Close MSYS2 and launch its 64-bit version ensuring


that the environment notices the GCC.

104
$ git clone https://github.com/raspberrypi/openocd.git --branch picoprobe
--depth=1

$ cd openocd

$ ./bootstrap $ ./configure --enable-picoprobe --disable-werror ①

$ make -j4

Look out for disable-werror, since not every


program runs or compiles on Windows. Run
OpenOCD to see that it was built the right way.

It will produce error results a few times which is


fine. One reason is that there are no configuration
options in place.

A.1.3. Mac

105
Install brew if it is required

/bin/bash -c "$(curl -fsSL

https://raw.githubusercontent.com/Homebr
ew/install/master/install.sh)"

Install dependencies

brew install libtool automake libusb wget pkg-config gcc


texinfo①

1. There is one example of texinfo used with OSX in


the version below is required to create OpenOCD
documents.

$ cd ~/pico
$ git clone https://github.com/raspberrypi/openocd.git --
branch picoprobe --depth=1

$ cd openocd

$ export PATH="/usr/local/opt/texinfo/bin:$PATH"①

$ ./bootstrap

$ ./configure --enable-picoprobe --disable-werror②

$ make -j4

● Place a recent version of texinfo inside the


path.
106
● Expect to see disable-werror as the
configuration is not completely compiled on
OSX.
● Look for OpenOCD runs and expect some error
feedback since there are no configuration
feedbacks.

● A.2. Build and flash picoprobe


The build instructions assume that Linux is your
default OS. Similarly, you can get a UF2
picoprobe from rptl.io/pico-picoprobe.
$ cd ~/pico
$ git clone https://github.com/raspberrypi/openocd.git --branch
picoprobe --depth=1

$ cd openocd

$ export PATH="/usr/local/opt/texinfo/bin:$PATH"①

$ ./bootstrap

107
$ ./configure --enable-picoprobe --disable-werror②

$ make -j4

Select and Boot the Raspberry Pi Pico that you want


as a debugger pressing the BOOTSEL button and
picoprobe.uf2 dragged on the device.

Picoprobe Wiring

The wiring loom between both Pico boards is


described in this illustration above.

Pico A GND -> Pico B GND

Pico A GP2 -> Pico B SWCLK

108
Pico A GP3 -> Pico B SWDIO

Pico A GP4/UART1 TX -> Pico B GP1/UART0 RX

Pico A GP5/UART1 RX -> Pico B GP0/UART0 TX

To alternate between powering Pico A and Pico B,


do this wiring;

The least amount of connections to load and


run code through OpenOCD is GND, SWDIO, and
SWCLK.

If you want to connect UART wires, then you will likely


communicate with the right-hand Pico’s UART serial port
via the USB connection of the Pico’s left-hand.

Also, if you make use of the UART wires, you will be able
to communicate to any other UART serial device, like the
boot console on a Raspberry Pi.

Also, if you’d like to power Pico A from Pico B you can


choose to wire,

Pico A VSYS -> Pico B VSYS

Important

One slight caveat on the above image is that if Pico0B is a0USB Host then
you’d0want to hook VBUS up to0VBUS so it can0provide 5V instead of
VSYS to VSYS.

109
A.4. Install Picoprobe driver (only needed on
Windows)

There are two USB interfaces on the picoprobe:

1. A CDC UART serial port that works on


Windows without extra installation of drivers.
2. A vendor interface for SWD probe data that is
personalized to individuals and requires a
driver to work.

First, download and install http://zadig.akeo.ie.

Run Zadig and choose a Picoprobe, the second


interface from the dropdown box. Choose lilbusb-
win32 as the driver.

Click install driver

110
A.5. Using Picoprobe’s UART

A.5.1. Linux

sudo minicom -D /dev/ttyACM0 -b 115200

A.5.2. Windows

First, download and install PuTTY


https://www.chiark.greenend.org.uk/~sgtatham/pu
tty/latest.html

Select Device Manager and search Picoprobe’s COM


port number. For this example, the port number is
COM7.

111
Click PuTTTY. Choose Serial below connection type.
Type the name of your COM port and change its
speed’s number to 115200.

112
Click Open to begin the serial console as you are
getting ready to run your very first application.

brew install minicom

minicom -D /dev/tty.usbmodem1234561 -b 115200

A.5.3. Mac

A.6. Using Picoprobe with OpenOCD


src/openocd -f interface/picobrobe.cfg -f target/rp2040.cfg -s tcl

This syntax is the same on all platforms

Connect GDB like you normally would.

target remote localhost:3333

113
Appendix B: Using Picotool

You can embed information into Raspberry Pi Pico


binary and retrieve it later with a command line
utility known as picotool.

B.1. Getting picotool

You will find the picotool utility in another repository


apart from the usual Pico SDK. If you are running it
the first time, clone and build it with this pico-setup
script.

$ git clone -b master https://github.com/raspberrypi/picotool.git

$ cd picotool

Important:

When you want to build a a picotool on macOS you can decide to install
libusb with Homebrew,

$ brew install libusb pkg-config

But if you build via Microsoft Windows, you will need to download and install
a Windows binary of libusb right from the libusb.info site.

B.2. Building Picotool

Use these methods to build picotool:

$ mkdir build
114
$ cd build

$ export PICO_SDK_PATH=~/pico/pico-sdk

$ cmake ../

$ make

this syntax creates a picotool command-line binary


just inside the build/picotool directory.

Note

B.3. Using Picotool

There are several command-line help features on


the picotool binary.

115
Note

The majority of commands require an0RP2040 device in BOOTSEL0mode to


be connected.

Important

The information is accessible on devices connected


to the RP2040 in BOOTSEL mode, or from any point
such as a file. The file is either an ELF, a Uf2, or a
BIN document.

116
B.3.1. Display information

You don’t have to struggle with storing compact


information again with the Binary information
support on picotool. Tap the info command to read
this information.

117
For instance, connect your Raspberry Pi Pico to your
computer using the Mass Storage Mode – one way
to do this is to long-press the BOOTSEL button
before plugging the USB. After that, open a
Terminal window to type

$ sudo picotool info

Program Information

name: hello_world

features: stdout to UART

Alternatively,

Although you can get information on the pins with


the following syntax;
118
Use the tools on the binaries inside your local file
system like this;

B.3.2. Save the program

Directly save your program, a section of it, or the


whole flash from the device in a BIN file or a Uf2
file.

119
For example

120
B.4. Binary Information

Every binary information has a location that can be


tracked and data that can be used by the machine.
This is because, its broad application means that
anyone can embed any information, that is different
to ours, and it is the choice of the individual to add
descriptive tags to the data created.

B.4.1. Basic Information

This one is the go-to to use find your way on Pico.


Basic information are not limited to the following.

● Program name
● Program description
● Program version string
● Program build date
● Program URL
● Program end address.
● Program features – this is a list created from
individual strings in the binary. It is displayed
according to its channel or connectivity in the
SDK.

121
● Build attributes are concerned with similar
data in the strings that are pertinent to the
binary like the Debug Build.

B.4.2. Pins

If you cannot recall the RP2040 based board a


project or an executable is built, especially when it
is built on several boards with several pins either
broken or missing, use the pins to resolve and
launch any executable program.

You will find static or fixed pin assignments in


binary in very compact form:

$ picotool info --pins sprite_demo.elf

File sprite_demo.elf:

Fixed Pin Information

0-4: Red 0-4

6-10: Green 0-4

11-15: Blue 0-4

16: HSync

17: VSync

18: Display Enable

122
19: Pixel Clock

20: UART1 TX 21: UART1 RX

B.4.3. Adding Binary Information

You will see binary information declared as macros


in the program.

$ picotool info --pins sprite_demo.elf

File sprite_demo.elf:

Fixed Pin Information

0-4: Red 0-4

6-10: Green 0-4

11-15: Blue 0-4

16: HSync

17: VSync

18: Display Enable

19: Pixel Clock

20: UART1 TX

21: UART1 RX

Add one line in the setup_default_uart function:

123
Both pin numbers and the UART function are stored
and later parsed as their real names on picotool.
Use the bi_decl_if_func_used to include the binary
information that contains the function called.

Similarly, you will find a video code with the


following lines:

bi_decl_if_func_used(bi_pin_mask_with_name(0x1f<<
(PICO_SCANVIDEO_COLOR_PIN_BASE+
PICO_SCANVIDEO_DPI_PIXEL_RSHIFT),"Red 0-4"));

Details

Programs and functions have been developed to


judiciously use space, although you can disable the
space management feature with preprocessor
through PICO_NO_BINARY_INFO=1. Also, exclude
any SDK code using its preprocessor variable when
it inserts a binary information.

You will need:

#include "pico/binary_info.h"

You will find several bi___ macros in the headers


like these:

124
There are also the ones that use underlying macros,
e.g.
#definebi_program_url(url)BI_STRING(BINARY_INFO_TAG_RASPBERRY_PI,BINA
RY_INFO_ID_RP_PROGRAM_URL,url)

Use either bi_dec1 (bi_blah(***)) for regular


inclusion of the binary info, if that is what you want,
or bi_decl_if_func_used(bi_blah(***)) to remove
binary information when the enclosing function is
not part of the binary via the linker (think –gc-
sections).

An example is below,

125
If it is queried with picotool,

126
B.4.5. Setting common fields from CMake

Set fields from CMake directory of your current


project, for example,

Now, “foo” becomes the default.

Note

All of these are passed as command0line0arguments to the


compilation, so if you plan to0use quotes, newlines etc you
may0have better luck0defining it using bi_decl in the code.

127
128

You might also like