In my previous blog post I wrote briefly about the new Raspberry Pi Pico and mentioned that I would be attempting to get some Pico examples compiled and uploaded to the board.

I use VSCode on MacOS for most of my development work including Arduino C/C++ coding using PlatformIO. Seeing as support for the Arduino core on the Pico is not yet ready, PlatformIO is not going to work so that leaves the official Pico SDK and toolchain as detailed in their getting started guide

The place to start seems to be with the C/C++ Getting Started guide PDF document here

The documentation is supposed to be really good and plentiful, its one of the aspects people seem to be raving out and a quick glance over what's available shows that there is indeed a lot of documentation and sample code available already. I have no idea of the quality of the documentation, again it's supposed to be good, however my experience with the C/C++ getting started guide was not without issues.

To save others a bit of time getting started with C/C++ on the Pico using VSCode on MacOS, here is a condensed list of steps from the guide with modifications where needed.

Start at Chapter 2. The SDK

Skip chapter 1 as the quick-install bash script referred to is designed to be run on a Raspberry Pi, which is odd because how many developers are going to be using a Raspberry Pi as their dev machine?

Reading chapter 2 reveals that first task is to jump to the MacOS chapter 8.1, so follow the instructions for installing the toolchain in Chapter 8 up to "8.1.3. Building with CMake Tools" but just install the VSCode "CMake Tools" extension and stop there, don't follow the rest of 8.1.3, follow the instructions listed below instead:

Jump back to Chapter 2

Continue from "2.1. Get the SDK and examples"

Create a directory for your Pico projects as suggested, for example "Documents/Development/RaspberryPi/pico" Here is what I used instead of the Raspbian specific directory paths:

cd ~/
mkdir -p Documents/Development/RaspberryPi/pico
cd Documents/Development/RaspberryPi/pico
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

Skip "2.2. Install the Toolchain" as this has already been done in the first step using the MacOS specific instructions in Chapter 8.

Jump back to MacOS Chapter 8

"8.1.3. Building with CMake Tools" We already installed the "CMake Tools" extension so the next step in the instructions is to set the PICO_SDK_PATH environment variable in the settings.json file, this is where the official getting started guide did not work too well for me:

Correct instructions:

The guide seems to suggest using the recently introduced VSCode workspace feature, so first save an empty VSCode workspace file (File> Save Workspace As.." somewhere sensible such as in Documents/Development/RaspberryPi/pico/pico-workspace. Inside the Documents/Development/RaspberryPi/pico/ directory you should now have 3 directories pico-examples, pico-sdk, pico-workspace

Click on the Cog Wheel at the bottom of the navigation bar on the left-hand side of the interface and select "Settings".

Then in the Settings pane click on "Extensions" and then "CMake Tools configuration".

Use the search box to Search for "Cmake: Generator" make sure the “workspace” tab is selected and enter "Unix Makefiles" into the box.

Next search for “cmake.configureEnvironment” make sure the “workspace” tab is selected, click "Add Item" and enter "PICO_SDK_PATH" as the "Item name" and "../pico-sdk" as the "Item value", making sure that this path is valid for your particular folder structure, which it should be if the directories suggested above have been used. (Note that if not using a workspace, ie. if you have just opened the pico-examples directory from VSCode use i found that the path needed to be "../../pico-sdk" as instructed in the guide.

Next search for “cmake.environment” and create a new item using the same values as above, (i found that I needed to set both "cmake.environment" and "cmake.configureEnvironment")

Then as per the instructions, "go to the File menu and click on "Add Folder to Workspace..." and navigate to pico-examples repo and hit "Okay". The project will load and you’ll (probably) be prompted to choose a compiler, see Figure 12. Select "GCC for arm-none-eabi" for your compiler. "

If you now open the workspace file in a text editor it should now look like this:

{
    "folders": [
        {
            "path": "../pico-examples"
        }
    ],
    "settings": {
        "cmake.generator": "Unix Makefiles",
        "cmake.configureEnvironment": {
            "PICO_SDK_PATH": "../pico-sdk"
        },
        "cmake.environment": {
            "PICO_SDK_PATH": "../pico-sdk"
        }
    }
}

As per the instructions, "Finally go ahead and click on the "Build" button (with a cog wheel) in the blue bottom bar of the window. This will create the build directory and run CMake as we did by hand in Section 3.1, before starting the build itself, see Figure 8. This will produce ELF, bin, and uf2 targets, ..... The UF2 binary can be dragged-and-dropped directly onto a RP2040 board attached to your computer using USB."

Ok, so now we can plug In the Pico board and upload some compiled code, note that the build button defaults to "all", and so builds all of the examples. You can click the "all" button the the right of the build button to choose which example to build.

After plugging in you should see a new mass storage volume appear in Finder which contains a .htm and .txt file. To list these files from the Terminal: ls /Volumes/RPI-RP2
"INDEX.HTM INFO_UF2.TXT"

INFO_UF2.TXT contents:

UF2 Bootloader v1.0
Model: Raspberry Pi RP2
Board-ID: RPI-RP2

INDEX.HTM contents:

<html><head><meta http-equiv="refresh" content="0;URL='https://raspberrypi.com/device/RP2?version=E0C912D24340'"/></head><body>Redirecting to <a href='https://raspberrypi.com/device/RP2?version=E0C912D24340'>raspberrypi.com</a></body></html>

The files appear to be just placeholders to show that the mass storage volume is working.

Uploading the compiled binaries

So let's copy one of the compiled examples over to the pico, from the VSCode Terminal:
cp build/blink/blink.uf2 /Volumes/RPI-RP2
Upon completion of the file copy, the Pico immediately resets and runs the code, you should see the LED blinking and that the mass storage device has been disconnected (MacOS warns about “Disk not ejected properly”)

So there it is, it works but is not as seamless as using the Arduino IDE or PlatformIO in VSCode. Note that once some code has been initially uploaded, if you want to upload again you need to disconnect the Pico and hold down the "BOOTSEL" button while plugging it back in, this makes it run its bootloader code which makes the Pico act as a mass storage volume.

Building from Terminal

If you want to run the make and build commands from the command line as per Chapter 3 in the guide:

Open the VSCode Terminal, the prompt should already be in the pico-examples directory, so just cd into the build directory, export the PICO_SDK_PATH env variable and run cmake with the 2 dots.

cd build
export PICO_SDK_PATH=../../pico-sdk
cmake ..

-- Build files have been written to: /Users/chrisclaxton/Documents/Development/RaspberryPi/pico/pico-examples/build

To build just one of the examples, cd into it and run the make command from there.

cd blink
make -j4

Having to disconnect the board and plug it back in with the BOOTSEL button pressed to upload new code is going to be a bit of an annoyance, and not great for your USB sockets, but you could always solder on some header pins and plug it into a breadboard with a reset button to pull down the RUN pin. All that would then be required is to hold down the BOOTSEL button while briefly pressing the new reset button then release the BOOTSEL button.

Now that the build environment is up and running you can take advantage of the rest of the getting started guide from Chapter 3 onwards to learn the specifics of the Pico.

In my next post I will try out the debugging functionality using "Picoprobe" which allows one Pico board to act as a debugger to debug another Pico board via its SWD port. The instructions are listed in "Appendix A: Using Picoprobe"

Update: it soon broke!!

Note that before building the examples, I noticed that the C/C++ intellisense was not working, but at some point after the code had been built i noticed the intellisense was working and I could navigate to function definitions within the SDK. I deleted the build folder to double check this, and sure enough the intellisense stopped working, but now for some reason the CMake extension's build button in VSCode no longer worked, the error showed that it was looking for the pico-sdk in the wrong place:

[cmake] CMake Error at pico_sdk_import.cmake:52 (message):
[cmake]   Directory
[cmake]   '/Users/chrisclaxton/Documents/Development/RaspberryPi/pico/pico-examples/pico-sdk'
[cmake]   not found

This was odd as nothing had changed in the VSCode configuration, so I tried from building from terminal and found that it also failed with the same error. I then noticed a few files inside the build folder which looked like cache files, so I emptied them out and tried again from Terminal, this time I got a different error "SDK location was not specified. Please set PICO_SDK_PATH" so I went ahead and set it, but to make it work I had to specify one level further back up the path as is originally stated in the guide, which I suppose now makes sense as we are running cmake from within the build directory.

From within the build directory I ran these commands to make it work again:

rm -rf *
export PICO_SDK_PATH=../../pico-sdk
cmake ..
cd blink
make -j4

Ok, so command-line build from Terminal is working again, so I then tried the build button again and found that it still failed because its was still looking for the pico-sdk in the wrong place, so I then tried building from Terminal again (without emptying the build folder) but this now failed again, the only difference from before being that I had tried to build using the CMake extension's build button which failed. This suggests there is a bug or at least some undesirable behaviour in the build process where a bad SDK path is cached once and not updated on subsequent build attempts. This caching behaviour can be confirmed by opening a new terminal after a successful build, you can run cmake without having to export the PICO_SDK_PATH env variable, but if you empty the build directory, cmake fails unless you export the PICO_SDK_PATH env var.

Emptying the build directory did not fix the issue for the build button, to get the build button working again I created a settings.json file inside the .vscode directory inside the pico-examples directory using the 2-levels-up parent directory path as specified in the getting started guide.

{
    "cmake.generator": "Unix Makefiles",
    "cmake.configureEnvironment": {
        "PICO_SDK_PATH": "../../pico-sdk"
    },
    "cmake.environment": {
        "PICO_SDK_PATH": "../../pico-sdk"
    }
}

I haven't figured out yet why this happened, for some reason the settings specified in the workspace file stopped working despite the workspace definitely being open and after a few reloading attempts, so for now i will keep the settings out of the workspace file and use the traditional .vscode/settings.json file.

Previous Post