How to Create A Standalone Raspberry Pi Pico C/C++ Project in Windows and Build from Command-Line and VS Code

Learn how to create standalone C/C++ SDK projects for Raspberry Pi Pico board on Windows operating system. Build projects from command-line and VS Code.
How to Create a Standalone Raspberry Pi Pico C/C++ Project in Windows CIRCUITSTATE Featured Image
Build Raspberry Pi Pico projects on Windows

In our last post, we covered everything you need to know to get your Raspberry Pi Pico board running. If you have followed that tutorial correctly, you should now be able to compile any of the example programs provided by Raspberry Pi (pico-examples) or use the Arduino IDE to create projects. In this post, we will give you a detailed walkthrough of creating a standalone C/C++ project anywhere on your Windows system. You will be able to build the projects with different configurations and should be able to make use of the complete features of the VS Code IDE. This tutorial is going to be specific to the Windows operating system. This is because the official tutorials released by Raspberry Pi use a Linux environment for building and debugging. So if you are on a Linux system or even a Raspberry Pi board running Linux, you can simply follow the official tutorial to learn how to work with the SDK.

We are on a Windows system and we had to figure out a few things on our own to get things working. So will be sharing our experience working with the official C/C++ SDK for Raspberry Pi Pico. If you think there is a better way of doing the same or we made a mistake somewhere, please let us know.

This tutorial assumes that you have already installed the required tools in your system and they are working from a command-line interface. If not, please follow Chapter 9 of the official documentation or Shawn Hymel’s tutorial to install them in your system.

If you are new to the RP2040 microcontroller and want to learn more about it, we have an excellent getting-started tutorial on CIRCUITSTATE.

Getting-Started-with-Raspberry-Pi-Pico-Pinout-Schematic-and-Programming-Tutorial-CIRCUITSTATE-Featured-Image-01-2

Getting Started with Raspberry Pi Pico : RP2040 Microcontroller Board – Pinout, Schematic and Programming Tutorial

Learn how to set up the Raspberry Pi Pico RP2040 board on your computer and write and compile programs with C/C++ SDK and Arduino IDE.

We can develop embedded firmware for you

CIRCUITSTATE can develop embedded firmware for any microcontroller/microprocessor including 8051, PIC, AVR, ARM, STM32, ESP32, and RISC-V using industry-leading SDKs, frameworks, and tools. Contact us today to share your requirements.

Electronics Networking Vector Image

Create A Project from Scratch

Creating a new project from scratch is explained in Chapter 8 of the tutorial Getting started with Raspberry Pi Pico. It suggests you create a new directory called test alongside the pico-sdk directory. In our system, the pico-sdk folder is at C:\Pico\pico-sdk and we want to create a new project elsewhere. So we are going to create a new folder called Test inside D:\Home\Code\Pico-CPP.

Then you need to create a C source file containing the main function of the program. We will simply name this file as main.c. The contents of the file can be a simple blink program. We will use the blink program from the official examples.

/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "pico/stdlib.h"

int main() {
#ifndef PICO_DEFAULT_LED_PIN
#warning blink example requires a board with a regular LED
#else
    const uint LED_PIN = PICO_DEFAULT_LED_PIN;
    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);
    }
#endif
}
main.c

Next, you need to create a CMakeLists.txt file. This file tells the CMake about the properties of the project. In our case, the contents of the file are suggested to be,

cmake_minimum_required(VERSION 3.13)

include(pico_sdk_import.cmake)

project(test_project C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()

add_executable(main
  main.c
)

pico_enable_stdio_usb(main 1)
pico_enable_stdio_uart(main 1)

pico_add_extra_outputs(main)

target_link_libraries(main pico_stdlib)
CMakeLists.txt

Let’s break that down.

cmake_minimum_required(VERSION 3.13)
CMake

This specifies the minimum version of CMake to be used. If your CMake installation is older than what is specified, you will get an error.

What is CMake you ask. CMake is a tool for automating software building process. It is not a toolchain or compiler. Instead it generates files and configurations required for building softwares with so many dependencies and source files. All without depending on a compiler or toolchain. That means you can use CMake with so many toolchains and IDEs, which makes it a favorite tool of software developers.

include(pico_sdk_import.cmake)
CMake

This tells the CMake to use a .cmake file found in the project directory. We haven’t added this file yet, but we will shortly. The file will tell CMake everything about the Pico C/C++ SDK.

project(test_project C CXX ASM)
CMake

This specifies the project name as test_project and the languages we are going to use. We will use C, C++ and ASM files.

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
CMake

These two lines specify the language standards to use.

add_executable(main
  main.c
)
CMake

This is the name of the target that will be built from the source files given. Here, the build target is main, which means the target files will be named like main.elf, main.bin, main.hex etc. The main.c is our source file from which the target files will be built. More info can be found here.

pico_enable_stdio_usb(main 1)
pico_enable_stdio_uart(main 1)
CMake

These are two CMake directives that tell where to direct the output/input from standard input-output interfaces. For example, when you use the printf() function, you need to direct the output to a physical interface in order to see what you have printed. Pico SDK allows us to use either the USB or a UART port as the input-output interface. We can enable one at a time or enable both together. Change the literal value 1 to enable the output, or to 0 to disable the output. In this case, both are enabled and that means anything you print with printf() function will be printed to both USB and default UART.

pico_add_extra_outputs(main)
CMake

This tells the build system must also create additional output files such as elf, uf2 etc.

target_link_libraries(main pico_stdlib)
CMake

This brings in the standard library available in the SDK so that you can use the basic functionalities like GPIO. If you need more or a specific SDK feature, you must specify it this way.

Now we need to copy and paste the file called pico_sdk_import.cmake from the pico-sdk\external folder to the root of your project folder. We will now have three files in the root directory of our project.

Raspberry-Pi-Pico-C-CPP-SDK-Create-Project-From-Scratch-Files-CIRCUITSTATE-Electronics-01
Files created

Go ahead and create a folder called build. This will contain all the files generated by the build system. Having a dedicated build folder for your project is always a good idea. You are now ready to build your project.

Building with MinGW

You can go ahead with this step if you have already set up MinGW in your system and it is available in the Path variable. Now open the command prompt from the root directory of your project. In our system, we can simply right-click on the explorer window and open the Terminal application there. This is possible because we have the Terminal application integrated into the context menu. We are going to open the PowerShell in the Terminal application.

First, run the cd build command. This will simply change the active directory to build. You could also have opened the Terminal inside the build directory. Then run,

cmake -G "MinGW Makefiles" ..
Terminal

This tells the CMake that we would like to use MinGW as the generator and thus need MinGW style makefiles. The CMake will now generate the build tree inside the build folder. No binaries are generated in this step. You will get a similar output at the Terminal like below.

PS D:\Code\Pico-CPP\Test\build> cmake -G "MinGW Makefiles" ..
Using PICO_SDK_PATH from environment ('C:\Pico\pico-sdk')
PICO_SDK_PATH is C:/Pico/pico-sdk
Defaulting PICO_PLATFORM to rp2040 since not specified.
Defaulting PICO platform compiler to pico_arm_gcc since not specified.
-- Defaulting build type to 'Release' since not specified.
PICO compiler is pico_arm_gcc
-- The C compiler identification is GNU 11.2.1
-- The CXX compiler identification is GNU 11.2.1
-- The ASM compiler identification is GNU
-- Found assembler: C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/11.2 2022.02/bin/arm-none-eabi-gcc.exe
Build type is Release
Defaulting PICO target board to pico since not specified.
Using board configuration from C:/Pico/pico-sdk/src/boards/include/boards/pico.h
-- Found Python3: C:/Users/Vishnu Mohanan/AppData/Local/Programs/Python/Python39/python.exe (found version "3.9.6") found components: Interpreter
TinyUSB available at C:/Pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; enabling build support for USB.
cyw43-driver available at C:/Pico/pico-sdk/lib/cyw43-driver
lwIP available at C:/Pico/pico-sdk/lib/lwip
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Code/Pico-CPP/Test/build
PS D:\Code\Pico-CPP\Test\build>
Terminal

The command was executed successfully and we can see all the new files and folders generated by CMake. Next, we need to actually build the project. The official SDK documentation uses make command in a Linux environment. It simply invokes the default GNU make and everything works flawlessly. But in Windows, you need extra stuff to get it done and that’s why you had to install the Microsoft Visual Studio pack to use the SDK on a Windows computer. It allows you to use the NMake and Visual Studio builder to compile the pioasm and elf2uf2 tools. But the problem is you always have to run NMake from a Developer Command Prompt, not an ordinary command prompt. That’s too much explanation? Just forget about it and let’s focus on using MinGW.

The next command we shall run is make in a MinGW environment. But for some reason, the build fails with the message shown below.

PS D:\Code\Pico-CPP\Test\build> make
Scanning dependencies of target bs2_default
[  1%] Building ASM object pico-sdk/src/rp2_common/boot_stage2/CMakeFiles/bs2_default.dir/compile_time_choice.S.obj
[  2%] Linking ASM executable bs2_default.elf
[  2%] Built target bs2_default
[  3%] Generating bs2_default.bin
[  4%] Generating bs2_default_padded_checksummed.S
[  4%] Built target bs2_default_padded_checksummed_asm
[  5%] Creating directories for 'ELF2UF2Build'
[  6%] No download step for 'ELF2UF2Build'
[  7%] No update step for 'ELF2UF2Build'
[  8%] No patch step for 'ELF2UF2Build'
[  9%] Performing configure step for 'ELF2UF2Build'
-- The C compiler identification is GNU 8.1.0
-- The CXX compiler identification is GNU 8.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Code/Pico-CPP/Test/build/elf2uf2
[ 10%] Performing build step for 'ELF2UF2Build'
'C:/Program' is not recognized as an internal or external command,
operable program or batch file.
make[2]: *** [elf2uf2/src/ELF2UF2Build-stamp/ELF2UF2Build-build] Error 1
make[1]: *** [CMakeFiles/ELF2UF2Build.dir/all] Error 2
make: *** [all] Error 2
PS D:\Code\Pico-CPP\Test\build>
Terminal

Something is wrong somewhere and we don’t know what. It must be something with something not being able to read path names with whitespaces on them. If you are a person who knows what’s happening, please drop us a comment.

So if that fails, we have to use an alternative way and that is using CMake’s --build command. The following command will build the project.

cmake --build d:\Code\Pico-CPP\Test\build --config Debug --target all -j 18
Terminal

It builds the entire project successfully and we are left with binary files ready to be flashed to our Pico. As you can see the second parameter should be the folder you want the output files to be written. In our case, it’s the d:\Code\Pico-CPP\Test\build folder. We are building all targets in Debug mode. The -j 18 simply means the number of parallel jobs that compile the project. The larger the number, the faster will be the compilation. We got the following output at the Terminal.

PS D:\Code\Pico-CPP\Test\build> cmake --build d:\Code\Pico-CPP\Test\build --config Debug --target all -j 18
[  2%] Built target bs2_default
[  3%] Performing build step for 'ELF2UF2Build'
[  5%] Built target bs2_default_padded_checksummed_asm
[ 50%] Building CXX object CMakeFiles/elf2uf2.dir/main.cpp.obj
[  6%] Creating directories for 'PioasmBuild'
[  7%] No download step for 'PioasmBuild'
[  8%] No update step for 'PioasmBuild'
[  9%] No patch step for 'PioasmBuild'
[ 10%] Performing configure step for 'PioasmBuild'
loading initial cache file D:/Code/Pico-CPP/Test/build/pico-sdk/src/rp2_common/cyw43_driver/pioasm/tmp/PioasmBuild-cache-Release.cmake
[100%] Linking CXX executable elf2uf2.exe
-- The CXX compiler identification is GNU 8.1.0
[100%] Built target elf2uf2
[ 12%] No install step for 'ELF2UF2Build'
-- Detecting CXX compiler ABI info
[ 13%] Completed 'ELF2UF2Build'
[ 18%] Built target ELF2UF2Build
Scanning dependencies of target main
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Code/Pico-CPP/Test/build/pioasm
[ 19%] Performing build step for 'PioasmBuild'
[ 20%] Building C object CMakeFiles/main.dir/main.c.obj
[ 21%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdlib/stdlib.c.obj
[ 23%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_gpio/gpio.c.obj
[ 24%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_claim/claim.c.obj
[ 25%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_platform/platform.c.obj
[ 26%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_sync/sync.c.obj
[ 27%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_irq/irq.c.obj
[ 28%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S.obj
[ 10%] Building CXX object CMakeFiles/pioasm.dir/main.cpp.obj
[ 20%] Building CXX object CMakeFiles/pioasm.dir/pio_assembler.cpp.obj
[ 30%] Building CXX object CMakeFiles/pioasm.dir/pio_disassembler.cpp.obj
[ 40%] Building CXX object CMakeFiles/pioasm.dir/gen/lexer.cpp.obj
[ 29%] [ 50%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_sync/lock_core.c.obj[ 30%]
Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_sync/sem.c.objBuilding CXX object CMakeFiles/pioasm.dir/gen/parser.cpp.obj

[ 31%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_time/time.c.obj
[ 32%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_time/timeout_helper.c.obj
[ 34%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_timer/timer.c.obj
[ 60%] Building CXX object CMakeFiles/pioasm.dir/c_sdk_output.cpp.obj
[ 35%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_util/pheap.c.obj
[ 70%] Building CXX object CMakeFiles/pioasm.dir/python_output.cpp.obj
[ 36%] [ 90%] [ 90%] Building CXX object CMakeFiles/pioasm.dir/ada_output.cpp.obj
Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_util/datetime.c.obj
Building CXX object CMakeFiles/pioasm.dir/hex_output.cpp.obj
[ 37%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_util/queue.c.obj
[ 38%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_sync/mutex.c.obj
[ 39%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_sync/critical_section.c.obj
[ 40%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_uart/uart.c.obj
[ 41%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_divider/divider.S.obj
[ 42%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_runtime/runtime.c.obj
[ 43%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_clocks/clocks.c.obj
[ 47%] [ 47%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_pll/pll.c.objBuilding C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c.obj[ 47%]

Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_vreg/vreg.c.obj
[ 48%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_xosc/xosc.c.obj
[ 49%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_printf/printf.c.obj
[ 50%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S.obj
[ 51%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_bootrom/bootrom.c.obj
[ 52%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_divider/divider.S.obj
[ 53%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_double/double_aeabi.S.obj
[ 54%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_double/double_init_rom.c.obj
[ 56%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_double/double_math.c.obj
[ 57%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_double/double_v1_rom_shim.S.obj
[ 58%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_float/float_aeabi.S.obj
[ 60%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_float/float_init_rom.c.obj
[ 60%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S.obj
[ 61%] [ 62%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S.obj
Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_float/float_math.c.obj
[ 63%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_malloc/pico_malloc.c.obj
[ 64%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S.obj
[ 65%] Building CXX object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj
[ 67%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_standard_link/crt0.S.obj
[ 68%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj
[ 69%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj
[ 70%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio_uart/stdio_uart.c.obj
[ 71%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio_usb/reset_interface.c.obj
[ 72%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb.c.obj
[ 73%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c.obj
[ 74%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c.obj
[ 75%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c.obj
[ 76%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/device/usbd.c.obj
[ 78%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/device/usbd_control.c.obj
[ 79%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/audio/audio_device.c.obj
[ 80%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/cdc/cdc_device.c.obj
[ 81%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/dfu/dfu_device.c.obj
[ 82%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/dfu/dfu_rt_device.c.obj
C:\Pico\pico-sdk\lib\tinyusb\src\portable\raspberrypi\rp2040\rp2040_usb.c:[ 83%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/hid/hid_device.c.obj
 In function 'rp2040_usb_init[ 84%] ':
C:\Pico\pico-sdk\lib\tinyusb\src\portable\raspberrypi\rp2040\rp2040_usb.c:61:3: warning: 'memset' writing 156 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
   61 |   memset(usb_hw, 0, sizeof(*usb_hw));
      |   Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/midi/midi_device.c.obj^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

C:\Pico\pico-sdk\lib\tinyusb\src\portable\raspberrypi\rp2040\rp2040_usb.c:62:3: warning:        'Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/msc/msc_device.c.objmemset
' writing 4096 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
   62 |   memset(usb_dpram, 0, sizeof(*usb_dpram));
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ 86%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/net/ecm_rndis_device.c.obj
[ 87%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/net/ncm_device.c.obj
[ 89%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/usbtmc/usbtmc_device.c.obj
[ 90%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/vendor/vendor_device.c.obj
[ 91%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/video/video_device.c.obj
[ 92%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/tusb.c.obj
[ 93%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/common/tusb_fifo.c.obj
[ 94%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c.obj
[ 95%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_unique_id/unique_id.c.obj
[ 96%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_flash/flash.c.obj
[100%] Linking CXX executable pioasm.exe
[ 97%] Linking CXX executable main.elf
[100%] Built target pioasm
[ 98%] No install step for 'PioasmBuild'
[100%] Completed 'PioasmBuild'
[100%] Built target PioasmBuild
[100%] Built target main
PS D:\Code\Pico-CPP\Test\build>
Terminal

You can now use any of the output files of your choice. If you have your Pico board connected to the computer as a mass storage device, you can simply drag and drop the UF2 file to program the flash. BIN and HEX files are good for flashing via SWD and ELF and MAP files are suitable for debugging.

Build with Visual Studio Build Tools

This is the recommended method demonstrated in Chapter 9.2 of the official documentation. You should have installed the Build Tools for Visual Studio 2022 in your system for this method to work. Once the tool is installed, you can find the Developer Command Prompt in the start menu. You need to run all the commands from this special CMD window. As per Microsoft, the NMake should be always run from a Developer Command Prompt.

Microsoft-Windows-Visual-Studio-Developer-Command-Prompt-Start-Menu-CIRCUITSTATE-Electronics-01
Search for Developer Command Prompt after installing the Visual Studio build tools

In our system, we can, again, right-click on the explorer and open the Developer Command Prompt on the Terminal application.

Microsoft-Windows-Visual-Studio-Developer-Command-Prompt-on-Terminal-Application-CIRCUITSTATE-Electronics-01
Developer Command Prompt on Terminal

You can first run the cmake "NMake Makefiles .. and then the nmake command to generate the binaries.

Cmake-Developer-Command-Prompt-Raspberry-Pi-Pico-C-C++-SDK-CIRCUITSTATE-Electronics-01
cmake command result
NMake-Developer-Command-Prompt-Raspberry-Pi-Pico-C-C++-SDK-CIRCUITSTATE-Electronics-01
nmake command result

We got the following output on the Terminal.

**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.1.4
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************

D:\Code\Pico-CPP\Test\build>cmake -G "NMake Makefiles" ..
Using PICO_SDK_PATH from environment ('C:\Pico\pico-sdk')
PICO_SDK_PATH is C:/Pico/pico-sdk
Defaulting PICO_PLATFORM to rp2040 since not specified.
Defaulting PICO platform compiler to pico_arm_gcc since not specified.
-- Defaulting build type to 'Release' since not specified.
PICO compiler is pico_arm_gcc
-- The C compiler identification is GNU 11.2.1
-- The CXX compiler identification is GNU 11.2.1
-- The ASM compiler identification is GNU
-- Found assembler: C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/11.2 2022.02/bin/arm-none-eabi-gcc.exe
Build type is Release
Defaulting PICO target board to pico since not specified.
Using board configuration from C:/Pico/pico-sdk/src/boards/include/boards/pico.h
-- Found Python3: C:/Users/Vishnu Mohanan/AppData/Local/Programs/Python/Python39/python.exe (found version "3.9.6") found components: Interpreter
TinyUSB available at C:/Pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; enabling build support for USB.
cyw43-driver available at C:/Pico/pico-sdk/lib/cyw43-driver
lwIP available at C:/Pico/pico-sdk/lib/lwip
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Code/Pico-CPP/Test/build

D:\Code\Pico-CPP\Test\build>nmake

Microsoft (R) Program Maintenance Utility Version 14.31.31106.2
Copyright (C) Microsoft Corporation.  All rights reserved.

Scanning dependencies of target bs2_default
[  1%] Building ASM object pico-sdk/src/rp2_common/boot_stage2/CMakeFiles/bs2_default.dir/compile_time_choice.S.obj
[  2%] Linking ASM executable bs2_default.elf
[  2%] Built target bs2_default
[  3%] Generating bs2_default.bin
[  4%] Generating bs2_default_padded_checksummed.S
[  4%] Built target bs2_default_padded_checksummed_asm
[  5%] Creating directories for 'ELF2UF2Build'
[  6%] No download step for 'ELF2UF2Build'
[  7%] No update step for 'ELF2UF2Build'
[  8%] No patch step for 'ELF2UF2Build'
[  9%] Performing configure step for 'ELF2UF2Build'
-- The C compiler identification is MSVC 19.31.31106.2
-- The CXX compiler identification is MSVC 19.31.31106.2
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.31.31103/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.31.31103/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Code/Pico-CPP/Test/build/elf2uf2
[ 10%] Performing build step for 'ELF2UF2Build'

Microsoft (R) Program Maintenance Utility Version 14.31.31106.2
Copyright (C) Microsoft Corporation.  All rights reserved.

[ 50%] Building CXX object CMakeFiles/elf2uf2.dir/main.cpp.obj
main.cpp
C:\Pico\pico-sdk\tools\elf2uf2\main.cpp(359): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Pico\pico-sdk\tools\elf2uf2\main.cpp(365): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
[100%] Linking CXX executable elf2uf2.exe
[100%] Built target elf2uf2
[ 12%] No install step for 'ELF2UF2Build'
[ 13%] Completed 'ELF2UF2Build'
[ 13%] Built target ELF2UF2Build
Scanning dependencies of target main
[ 14%] Building C object CMakeFiles/main.dir/main.c.obj
[ 15%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdlib/stdlib.c.obj
[ 16%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_gpio/gpio.c.obj
[ 17%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_claim/claim.c.obj
[ 18%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_platform/platform.c.obj
[ 19%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_sync/sync.c.obj
[ 20%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_irq/irq.c.obj
[ 21%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S.obj
[ 23%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_sync/sem.c.obj
[ 24%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_sync/lock_core.c.obj
[ 25%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_time/time.c.obj
[ 26%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_time/timeout_helper.c.obj
[ 27%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_timer/timer.c.obj
[ 28%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_util/datetime.c.obj
[ 29%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_util/pheap.c.obj
[ 30%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_util/queue.c.obj
[ 31%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_sync/mutex.c.obj
[ 32%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/common/pico_sync/critical_section.c.obj
[ 34%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_uart/uart.c.obj
[ 35%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_divider/divider.S.obj
[ 36%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_runtime/runtime.c.obj
[ 37%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_clocks/clocks.c.obj
[ 38%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_pll/pll.c.obj
[ 39%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_vreg/vreg.c.obj
[ 40%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c.obj
[ 41%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_xosc/xosc.c.obj
[ 42%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_printf/printf.c.obj
[ 43%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S.obj
[ 45%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_bootrom/bootrom.c.obj
[ 46%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_divider/divider.S.obj
[ 47%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_double/double_aeabi.S.obj
[ 48%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_double/double_init_rom.c.obj
[ 49%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_double/double_math.c.obj
[ 50%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_double/double_v1_rom_shim.S.obj
[ 51%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S.obj
[ 52%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_float/float_aeabi.S.obj
[ 53%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_float/float_init_rom.c.obj
[ 54%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_float/float_math.c.obj
[ 56%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S.obj
[ 57%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_malloc/pico_malloc.c.obj
[ 58%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S.obj
[ 59%] Building ASM object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_standard_link/crt0.S.obj
[ 60%] Building CXX object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj
[ 61%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj
[ 62%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj
[ 63%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio_uart/stdio_uart.c.obj
[ 64%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio_usb/reset_interface.c.obj
[ 65%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb.c.obj
[ 67%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c.obj
[ 68%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c.obj
[ 69%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c.obj
C:\Pico\pico-sdk\lib\tinyusb\src\portable\raspberrypi\rp2040\rp2040_usb.c: In function 'rp2040_usb_init':
C:\Pico\pico-sdk\lib\tinyusb\src\portable\raspberrypi\rp2040\rp2040_usb.c:61:3: warning: 'memset' writing 156 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
   61 |   memset(usb_hw, 0, sizeof(*usb_hw));
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Pico\pico-sdk\lib\tinyusb\src\portable\raspberrypi\rp2040\rp2040_usb.c:62:3: warning: 'memset' writing 4096 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
   62 |   memset(usb_dpram, 0, sizeof(*usb_dpram));
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ 70%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/device/usbd.c.obj
[ 71%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/device/usbd_control.c.obj
[ 72%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/audio/audio_device.c.obj
[ 73%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/cdc/cdc_device.c.obj
[ 74%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/dfu/dfu_device.c.obj
[ 75%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/dfu/dfu_rt_device.c.obj
[ 76%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/hid/hid_device.c.obj
[ 78%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/midi/midi_device.c.obj
[ 79%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/msc/msc_device.c.obj
[ 80%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/net/ecm_rndis_device.c.obj
[ 81%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/net/ncm_device.c.obj
[ 82%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/usbtmc/usbtmc_device.c.obj
[ 83%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/vendor/vendor_device.c.obj
[ 84%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/class/video/video_device.c.obj
[ 85%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/tusb.c.obj
[ 86%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/lib/tinyusb/src/common/tusb_fifo.c.obj
[ 87%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c.obj
[ 89%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/pico_unique_id/unique_id.c.obj
[ 90%] Building C object CMakeFiles/main.dir/C_/Pico/pico-sdk/src/rp2_common/hardware_flash/flash.c.obj
[ 91%] Linking CXX executable main.elf
[ 91%] Built target main
[ 92%] Creating directories for 'PioasmBuild'
[ 93%] No download step for 'PioasmBuild'
[ 94%] No update step for 'PioasmBuild'
[ 95%] No patch step for 'PioasmBuild'
[ 96%] Performing configure step for 'PioasmBuild'
loading initial cache file D:/Code/Pico-CPP/Test/build/pico-sdk/src/rp2_common/cyw43_driver/pioasm/tmp/PioasmBuild-cache-Release.cmake
-- The CXX compiler identification is MSVC 19.31.31106.2
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.31.31103/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Code/Pico-CPP/Test/build/pioasm
[ 97%] Performing build step for 'PioasmBuild'

Microsoft (R) Program Maintenance Utility Version 14.31.31106.2
Copyright (C) Microsoft Corporation.  All rights reserved.

[ 10%] Building CXX object CMakeFiles/pioasm.dir/main.cpp.obj
main.cpp
C:\Pico\pico-sdk\tools\pioasm\pio_types.h(272): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
[ 20%] Building CXX object CMakeFiles/pioasm.dir/pio_assembler.cpp.obj
pio_assembler.cpp
C:\Pico\pico-sdk\tools\pioasm\pio_types.h(272): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
C:\Pico\pico-sdk\tools\pioasm\pio_assembler.cpp(132): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
C:\Pico\pico-sdk\tools\pioasm\pio_assembler.cpp(141): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
[ 30%] Building CXX object CMakeFiles/pioasm.dir/pio_disassembler.cpp.obj
pio_disassembler.cpp
[ 40%] Building CXX object CMakeFiles/pioasm.dir/gen/lexer.cpp.obj
lexer.cpp
C:\Pico\pico-sdk\tools\pioasm\pio_types.h(272): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
[ 50%] Building CXX object CMakeFiles/pioasm.dir/gen/parser.cpp.obj
parser.cpp
C:\Pico\pico-sdk\tools\pioasm\pio_types.h(272): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
[ 60%] Building CXX object CMakeFiles/pioasm.dir/c_sdk_output.cpp.obj
c_sdk_output.cpp
[ 70%] Building CXX object CMakeFiles/pioasm.dir/python_output.cpp.obj
python_output.cpp
[ 80%] Building CXX object CMakeFiles/pioasm.dir/hex_output.cpp.obj
hex_output.cpp
[ 90%] Building CXX object CMakeFiles/pioasm.dir/ada_output.cpp.obj
ada_output.cpp
[100%] Linking CXX executable pioasm.exe
[100%] Built target pioasm
[ 98%] No install step for 'PioasmBuild'
[100%] Completed 'PioasmBuild'
[100%] Built target PioasmBuild

D:\Code\Pico-CPP\Test\build>
Terminal

You can now see the binaries in the build folder. Even though you have to use slightly different methods to compile your programs, all the configurations and customizations possible in the CMake files are common to all methods and you can refer to the official documentation for reference. Raspberry Pi Pico C/C++ SDK has everything you need to know about the C/C++ SDK.

Build with VS Code

The project you have created can also be compiled using VS Code. Simply open the project folder in VS Code. The first time you open the folder, VS Code will automatically detect the type of project and will prompt you to select a compiler. VS Code will scan your system and find all the installed compilers. From the list, we need to choose the ARM-GCC compiler. Depending on which version of the compiler you have installed, the list item may be different.

Select-ARM-GCC-Compiler-VS-Code-SDK-CIRCUITSTATE-Electronics-01
Select the compiler

In our system, we have ARM-GCC 11.2.1 (arm-none-eabi). This is the toolchain we must use to compile our Pico C/C++ projects. Once you select the compiler, VS Code will try to configure the project and will print the following output to the console.

[variant] Loaded new set of variants
[kit] Successfully loaded 18 kits from C:\Users\Vishnu Mohanan\AppData\Local\CMakeTools\cmake-tools-kits.json
[proc] Executing command: "C:\Program Files (x86)\Arm GNU Toolchain arm-none-eabi\11.2 2022.02\bin\arm-none-eabi-gcc.exe" -v
[main] Configuring folder: Test 
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug "-DCMAKE_C_COMPILER:FILEPATH=C:\Program Files (x86)\Arm GNU Toolchain arm-none-eabi\11.2 2022.02\bin\arm-none-eabi-gcc.exe" "-DCMAKE_CXX_COMPILER:FILEPATH=C:\Program Files (x86)\Arm GNU Toolchain arm-none-eabi\11.2 2022.02\bin\arm-none-eabi-g++.exe" -Sd:/Code/Pico-CPP/Test -Bd:/Code/Pico-CPP/Test/build -G "MinGW Makefiles"
[cmake] Not searching for unused variables given on the command line.
[cmake] Using PICO_SDK_PATH from environment ('C:\Pico\pico-sdk')
[cmake] PICO_SDK_PATH is C:/Pico/pico-sdk
[cmake] Defaulting PICO_PLATFORM to rp2040 since not specified.
[cmake] Defaulting PICO platform compiler to pico_arm_gcc since not specified.
[cmake] PICO compiler is pico_arm_gcc
[cmake] -- The C compiler identification is GNU 11.2.1
[cmake] -- The CXX compiler identification is GNU 11.2.1
[cmake] -- The ASM compiler identification is GNU
[cmake] -- Found assembler: C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/11.2 2022.02/bin/arm-none-eabi-gcc.exe
[cmake] Build type is Debug
[cmake] Using regular optimized debug build (set PICO_DEOPTIMIZED_DEBUG=1 to de-optimize)
[cmake] Defaulting PICO target board to pico since not specified.
[cmake] Using board configuration from C:/Pico/pico-sdk/src/boards/include/boards/pico.h
[cmake] -- Found Python3: C:/Users/Vishnu Mohanan/AppData/Local/Programs/Python/Python39/python.exe (found version "3.9.6") found components: Interpreter 
[cmake] TinyUSB available at C:/Pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; enabling build support for USB.
[cmake] Compiling TinyUSB with CFG_TUSB_DEBUG=1
[cmake] cyw43-driver available at C:/Pico/pico-sdk/lib/cyw43-driver
[cmake] lwIP available at C:/Pico/pico-sdk/lib/lwip
[cmake] -- Configuring done
[cmake] -- Generating done
[cmake] -- Build files have been written to: D:/Code/Pico-CPP/Test/build
Console

You can go ahead and build your project by clicking the Build button on the bottom bar of VS Code. If you can’t find the button for some reason, you can run it from Terminal → Run Build Task and choose CMake: build from the list.

VS-Code-Raspberry-Pi-Pico-C-C++-Project-SDK-CIRCUITSTATE-Electronics-01
Pico project loaded on VS Code
VS-Code-Raspberry-Pi-Pico-Run-Build-Task-CMake-C-C++-SDK-CIRCUITSTATE-Electronics-01
Choose the CMake: build task to build your project

It is highly recommended to disable all conflicting extensions when working a C/C++ project. Extensions like PlatformIO, Arduino, nRF Tools can interfere with automatic configuration, intellisense etc. Therefore it is a good idea to disable them on your project workspace. You can do this by clicking on the small cog icon on the extension and choose Disable (Workspace) option.

You must have noticed the red squiggly lines on the include line of the program. VS Code is able to build the project but is not able to fetch all the dependencies. This is because VS Code is not quite sure where the Pico C/C++ SDK is. We can fix this by adding the SDK path to the C/C++ configuration of VS Code. Click the Win32 button on the bottom-right and choose Edit Configuration (UI) from the list. This will open the settings window. Scroll down to Include path option and add your Pico SDK path to a new line. In our case, the SDK is at C:\Pico\pico-sdk. After adding it, reload your VS Code editor so that the intellisense can do a fresh scan and find all the dependencies. You can also change the compiler path and intellisense type.

Add-Raspbery-Pi-Pico-SDK-Path-to-VS-Code-for-Intellisense-CIRCUITSTATE-Electronics-01
Find the Include path option and add your SDK path
VS-Code-Error-Squiggles-Gone-After-Adding-Pico-SDK-Path-CIRCUITSTATE-Electronics-01
Error squiggles should now disappear

To help you get started, we have provided a download link to the project we have created. Try unzipping it, opening it with VS Code, and then compiling. Remember to disable any conflicting extensions. Also, VS Code may suggest extensions based on the files opened. Install them if you haven’t already.

Create A Project with Project Generator

Creating the project files manually can be problematic and it is a process that can be easily automated. That’s what you can do with the Pico Project Generator. It is a Python script that will generate all the required files and directories in one go. To use the tool, you can clone the repository to your system with the following command.

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

You must use the Developer Command Prompt to run this successfully. There is both a GUI and a command-line interface for the project generator. To invoke the GUI, run the following command inside the project generator directory.

pico_project.py --gui
Terminal

You will get a GUI window like below.

Raspberry-Pi-Pico-Project-Generator-Script-GUI-SDK-CIRCUITSTATE-Electronics-01
Raspberry Pi Pico C/C++ project generator
Raspberry-Pi-Pico-Project-Generator-Build-Window-CIRCUITSTATE-Electronics-01
Raspberry Pi Pico project builder build window

You can select the project name, and location, set some of the basic options like the default standard output, etc. The most interesting option is the Create VSCode project item. Checking this box will generate four JSON files inside the .vscode folder in the project root directory.

  1. c_cpp_properties.json – Has the C/C++ IntelliSense configuration. The project generator creates this file for the Linux environment and there’s no option for VS Code running on Windows.
  2. extensions.json – This has a list of recommended extensions. VS Code will prompt you to install them.
  3. launch.json – This has the configuration for launching the debugger. By default, you will be using OpenOCD and GDB.
  4. settings.json – A few settings for your current workspace.

The project can be opened in VS Code and compiled just like we have seen before. You can use the official Pico Debug Probe to debug your RP2040 Pico C/C++ SDK projects. Check out the following tutorial to learn more. You can also let us know your feedback on this tutorial.

How to Debug RP2040 C/C++ SDK Projects with Raspberry Pi Debug Probe and VS-Code by CIRCUITSTATE Electronics Featured Image

Debugging RP2040 Pico C/C++ SDK Projects using Raspberry Pi Debug Probe & VS Code

Learn how to use the official Pico Debug Probe to debug your Raspberry Pi Pico RP2040 C/C++ SDK projects using VS Code.
  1. RP2040 Datasheet [PDF]
  2. Raspberry Pi Pico Datasheet [PDF]
  3. Hardware Design with RP2040 [PDF]
  4. Getting started with Raspberry Pi Pico [PDF]
  5. Raspberry Pi Pico C/C++ SDK [PDF]
  6. Getting Started with Raspberry Pi Pico : RP2040 Microcontroller Board – Pinout, Schematic and Programming Tutorial
  7. How to Set Up Raspberry Pi Pico C/C++ Toolchain on Windows with VS Code – Shawn Hymel
  8. How to Program Raspberry Pi Pico with Arduino IDE – Steps for Installation and Uploading Example Sketches
  9. Raspberry Pi Pico High-Quality Pinout Diagram [PDF]
Share to your friends
Vishnu Mohanan

Vishnu Mohanan

Founder and CEO at CIRCUITSTATE Electronics

Articles: 84

Leave a Reply

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

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.