Easy Raspberry Pi Pico Microcontroller C / C++ Programming on Windows

Pi Pico
Reading Time: 6 minutes

This tutorial covers setting up a pretty painless Raspberry Pi Pico C / C++ SDK development workflow on Windows using the Windows Subsystem for Linux (WSL) and Visual Studio Code (VS Code) with IntelliSense code completion!

With the Raspberry Pi Pico microcontroller being so new the current C / C++ SDK development process on Windows is a bit cumbersome. This tutorial should hopefully give you some ideas on how to go about programming the Raspberry Pi Pico the easy way with WSL and VS Code.

Note: This is not a beginner tutorial and assumes some minimal development experience.

The Raspberry Pi Pico is an exciting new microcontroller board launched on January 21, 2021. It’s based on the RP2040 microcontroller (by the Raspberry Pi Foundation) sporting a dual-core ARM Cortex-M0+ running at 133 MHz. The most exciting feature is the Programmable I/O, or PIO, that has 8 independent processors (simple state machines). This is huge for robotics where there’s a need to ingest real-time sensor data in the background while performing other tasks. Keep an eye out for my tutorial on reading multiple DC motor quadrature encoders at the same time without messing with lots of timers and interrupts using the PIO!

Prerequisites

  1. Enable Windows Subsystem for Linux and install the latest Ubuntu image (20); follow the “Manual Installation” steps. WSL is a built-in feature of Windows 10 and brings most of the power of developing on a Linux machine natively into Windows! Be sure to install Windows Terminal for an even better experience (instructions towards the end of the link above).
  2. Install Visual Studio Code and install the following extensions: Remote – WSL, C/C++, and CMake Tools. You can search for these extensions by name directly in VS Code.

Configure WSL

Setup Script

If you are in a bit of a rush I’ve created a setup script that will perform all the WSL configuration tasks for you. Just open up WSL, run the following commands, then skip to setting up Visual Studio Code!

cd ~
git clone https://github.com/74ls04/pico-wsl-setup.git
cd pico-wsl-setup
./pico_wsl_setup.sh

This script will install the SDK in ~/pico and also installs a few Pico extras from the Raspberry Pi Pico repos.

Install Dependencies

Note: I’m using Ubuntu 18 for this demo but if you’re starting from scratch use 20 to avoid issues with CMake compatibility.

First, open up the WSL Ubuntu terminal and go to the home directory.

cd ~

Then install the required build dependencies

sudo apt update
sudo apt install git cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential

That’s all there is for dependencies!

Install the Raspberry Pi Pico C / C++ SDK

While still in the home directory create a directory called pico and go into the pico directory

mkdir pico
cd pico

After that clone the SDK and 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

The git submodule command basically pulls in a separate Raspberry Pi repository from https://github.com/raspberrypi/tinyusb.git and downloads those files.

Here is what all the commands look like after execution.

Raspberry Pi Pico Toolchain

Configure and Build with Visual Studio Code

Now we’re going to configure VS Code and build the following “blink” example.

#include "pico/stdlib.h"

int main() {
    const uint LED_PIN = 25;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    while (true) {
        gpio_put(LED_PIN, 1);
        sleep_ms(250);
        gpio_put(LED_PIN, 0);
        sleep_ms(250);
    }
}

So far you should have the following directories:

~/pico
~/pico/pico-sdk
~/pico/pico-examples

Move into the pico-examples directory

cd pico-examples

Now here is where the integration of VS Code and WSL really shines. Open VS Code into this directory

code .

This command will launch VS Code and automatically link it to the WSL instance. You should see a green connection label in the bottom left. This process also creates a hidden .vscode sub-directory that will hold the VS Code configuration for this workspace.

If this is your first time using VS Code with WSL follow these quick instructions to make sure the three extensions mentioned at the top are also installed in WSL. At this point you may see a notification asking if you would like to configure the project — click on “Not now” as we need to set up a few things first.

Configure CMake Extension

Click the gear icon in the bottom left and select Settings.

Expand the Extensions tree, select CMake Tools configuration, and then click Add Item under “Cmake: Build Environment” to add the SDK path as shown below. If you followed the directory structure in this tutorial your PICO_SDK_PATH will be /home/$USER/pico/pico-sdk where $USER is your WSL username. In this case my tutorial username is “main.”

Raspberry Pi Pico SDK Path
Configure IntelliSense (Code Completions)

Open the Command Palette, Ctrl+Shift+P, and start typing “C/C++” then select C/C++: Edit Configurations (JSON).

This will create the following file:

 /home/$USER/pico/pico-examples/.vscode/c_cpp_properties.json

Change the file to match the following settings. Keep in mind that these settings are purely for code-completion and have nothing to do with the actual compiling.

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "/home/$USER/projects/pico/pico-sdk/**",
                "/usr/lib/gcc/arm-none-eabi/**"
            ],
            "defines": [],
            "compilerPath": "arm-none-eabi-gcc",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "gcc-arm",
            "configurationProvider": "ms-vscode.cmake-tools"
        }
    ],
    "version": 4
}

Replace $USER with your WSL username under “includePath”!

Raspberry Pi Pico Intellisense

Close VS Code and relaunch it again from the terminal with

code .

This time when CMake asks whether you’d like to configure the project select “Yes” and wait for it to finish configuring.

Configure Compiler and Build

Tell VS Code which compiler to use by clicking the “No Kit Selected” text at the bottom

Raspberry Pi Pico Compiler Select

Then selecting GCC for arm-none-eabi... If using Ubuntu 20 your compiler version will be different since I’m using 18.

Raspberry Pi Pico Compiler Menu

Open up the “blink.c” example file using the explorer menu on the left, CTRL+SHIFT+E. You should see no errors highlighted in the file and code hints should be working as well.

Raspberry Pi Pico Code Completion

Tell CMake which project to build by clicking on [all] at the bottom

Raspberry Pi Pico Project Select

Then scroll until you see “blink.”

Raspberry Pi Pico Project Select Menu

You should now see [blink] instead of [all]. Click on “Build” to build the project!

Raspberry Pi Pico Build Select

VS Code will automatically create a build directory and spit out the project binaries into that directory.

Raspberry Pi Pico Build

Keep in mind this built the debug configuration, you can change it to release by clicking on CMake: [Debug]: Ready at the bottom.

Upload to Raspberry Pi Pico

Uploading the binary to the Pico is just a matter of dragging the .uf2 file into the folder that opens when you plug in the Pico while holding down the BOOTSEL button.

The file to transfer is:

/home/main/pico/pico-examples/build/blink/blink.uf2

To open the directory you can either right clock on the directory name in VS Code then click “Reveal in Explorer” or just type

explorer.exe .

in the WSL terminal to open that directory in Windows Explorer. That’s one of the most useful WSL commands!

Plug in the Raspberry Pi Pico while holding down the BOOTSEL button and then drag over the .uf2 file to the Pico folder.

Raspberry Pi Pico Upload

It will automatically disconnect after transferring and immediately start running the program!

Raspberry Pi Pico

It’s also pretty easy to configure VS Code to automatically move the file after building but for the sake of keeping this short I’ll save that for another time.

More to come!

This should hopefully give you an idea of how the current development process is for the Raspberry Pi Pico. My goal is to create another robotics-focused Pico tutorial in the coming months starting from scratch and using the PIO — maybe in conjunction with a Raspberry Pi!

Feel free to ask any questions or offer suggestions in the comments!

Updated: 2/11/2021

14 thoughts on “Easy Raspberry Pi Pico Microcontroller C / C++ Programming on Windows”

      1. Thanks – this seems to be resolved by changing the cmake generator to: Unix Makefiles.

        The problem I have now is if I create a new folder within the pico-examples subfolder and put my code files in it, the folder does not appear in the build list and my project is ignored – it won’t compile!?

        1. Aah – sorted – have to add a line to the root CMakeLists.txt….

          add_subdirectory(myprojname)

          Turbo Pascal was so much simpler!

  1. Amazing work, thank you! I’d managed to get a compiler working in WSL by myself, but hadn’t known about VS Code linking to WSL, along with auto completion.

    This is going to make my Pico dev (and other projects like my hobby OS) *so* much easier!

    1. I’m glad this was helpful! The integration between VS Code and WSL is quite powerful.

      You can also connect VS Code to a Raspberry Pi (any Linux OS really) and edit code directly on the Pi via VS Code.

  2. I’m hesitant to use this approach (WSL2) because I don’t think it will support GDB debugging with OpenOCD. WSL2 still doesn’t natively support access to USB devices.

    Have you managed to get OpenOCD working?

    1. I haven’t had a chance to try that out yet but you’re right, WSL doesn’t play well with USB. I think, though, it’s just a matter of time until they get that figured out since it’s too big of a feature to not have.

  3. Thanks for writing this up!, I spent a whole day yesterday trying to get the toolchain to work on Windows unsuccessfully. Your tutorial had me up and running in an hour, tops.

  4. Overall, I found this tutorial EXCELLENT. I was a bit confused when installing VS Code (do I install it in Windows or Ubuntu, then, later, understood the link between Windows and Ubuntu. I also had a bit of confusion when configuring CMake (didn’t understand that I needed to select the extension first before I saw the correct configuration to modify). That is probably because I am not a seasoned VS Code developer. I got past those hurdles and am now successfully completing and downloading code. So, thank you so much for the excellent tutorial.

    1. It’s definitely a bit of an involved process if you’re not used to the workflow – glad you were able to get it working!

  5. One question. Once you build the blink example, how do you then select another project? For example, I2C_scan. I opened the c file, but how do you get VS Code to select [bus_scan] and then compile? Thanks.

    1. You can select it from the blue bar at the bottom. Clicking on the name of the active project there will bring up a list of all the detected ones in your directory and you can select from there.

Leave a Reply

Your email address will not be published. Required fields are marked *