Introduction
Raspberry Pi Pico is a tiny, fast, and versatile board built using RP2040, a brand new microcontroller chip designed by Raspberry Pi. RP2040 features a dual-core Arm Cortex-M0+ processor with 264KB internal RAM and support for up to 16MB of off-chip Flash. A wide range of flexible I/O options includes I2C, SPI, and uniquely Programmable I/O (PIO).
In this article, we will learn how to create a new C/C++ project for Raspberry Pi Pico and build it using C/C++ SDK.
What You Will Learn
- How to create a C/C++ project for Raspberry Pi Pico?
- How to build a new C/C++ program for Raspberry Pi Pico?
- How to compile and build C/C++ programs for Raspberry Pi Pico using the SDK?
- How to compile and build C/C++ programs for Raspberry Pi Pico in Windows PC?
Prerequisite Hardware
- Raspberry Pi Pico
- Micro USB Cable
- Windows 10 Computer
Prerequisite Software
- Raspberry Pi Pico C/C++ SDK
- Visual Studio Code / Notepad++
Create Folder Structure for New C/C++ Project
- Use Windows File Explorer to navigate to the folder containing
pico-sdk
andpico-examples
- Create an empty folder
pico-empty-project
- Navigate inside the folder
pico-empty-project
- Create an empty folder
build
- Create an empty folder
main
- Create a file
CMakeLists.txt
- Add the below code to
CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
# Import Pico SDK
include(pico_sdk_import.cmake)
project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR})
# Initialize the SDK
pico_sdk_init()
include(example_auto_set_url.cmake)
# Add main Folder
add_subdirectory(main)
- Navigate to folder
pico-examples
- Copy the file
example_auto_set_url.cmake
andpico_sdk_import.cmake
- Navigate to folder
pico-empty-project
- Paste the file
example_auto_set_url.cmake
andpico_sdk_import.cmake
- Navigate to folder
main
- Create a file
CMakeLists.txt
- Add the below code to
CMakeLists.txt
add_executable(main
main.c
)
# Import pico_stdlib which imports commonly used features
target_link_libraries(main pico_stdlib)
# Create map/bin/hex file etc.
pico_add_extra_outputs(main)
# Add path via pico_set_program_url CMAKE
example_auto_set_url(main)
- Create a file
main.c
- Add your own code or the provided blink code
/**
* www.ArnabKumarDas.com
*
* On-Board LED Blinky
*/
#include "pico/stdlib.h"
int main()
{
const uint LED_PIN = PICO_DEFAULT_LED_PIN;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (1)
{
gpio_put(LED_PIN, 1);
sleep_ms(250);
gpio_put(LED_PIN, 0);
sleep_ms(250);
gpio_put(LED_PIN, 1);
sleep_ms(250);
gpio_put(LED_PIN, 0);
sleep_ms(750);
}
}
Building the New C/C++ Project
- Open the Visual Studio 2019 Developer Command Prompt
- Navigate to the new project build folder
pico-empty-project\build
** Visual Studio 2019 Developer Command Prompt v16.9.4
** Copyright (c) 2021 Microsoft Corporation
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools>cd /D D:\Electronics\RP2040\pico-empty-project
D:\Electronics\RP2040\pico-empty-project>cd build
D:\Electronics\RP2040\pico-empty-project\build>
- Execute the command
cmake -G "NMake Makefiles" ..
D:\Electronics\RP2040\pico-empty-project\build>cmake -G "NMake Makefiles" ..
D:\Electronics\RP2040\pico-empty-project\build>
- Execute the command
nmake
to build the project
D:\Electronics\RP2040\pico-empty-project\build>nmake
D:\Electronics\RP2040\pico-empty-project\build>
- Navigate to the folder
\pico-empty-project\build\main
to view the build artifacts
Flashing the Raspberry Pi Pico
- Push and hold the BOOTSEL button (white colour near USB port)
- Plug the Pico into the USB port of the Windows 10 Computer
- Raspberry Pi Pico will mount as a Mass Storage Device called RPI-RP2
- Drag and Drop or Copy and Paste the
main.uf2
UF2 Binary into the RPI-RP2 Drive - Pico will Reboot automatically, and the on-board Green LED should start Blinking
Download
- Download and Extract the file to the folder containing
pico-sdk
andpico-examples
- Follow the build instructions
- Edit the cmake files to add new source and header files
- Edit the folder name to project name
4 Comments
Nigel The Engineer · July 22, 2022 at 7:44 pm
Hi,
It works. Thank you so much for the “Raspberry Pi Pico : Create and Build New C/C++ Project in Windows”. It is the first example I have found that seems to work reliably on my system.
Ideally, I would like to repeat this exercise with the “Empty project” on an external drive on our server but this doesn’t work for some reason. Any ideas?
Thanks, Nigel
Crazy Engineer · July 24, 2022 at 12:39 am
Please share the Errors.
Dave · September 23, 2022 at 5:46 am
Have followed the instructions above to the letter, and copied main.uf2 to the board, but the LED does not blink. Have been working on the pico since Sunday, and getting nowhere !
Have copied the screen output for the cmake and nmake below, was wondering if you could possibly take a quick look to see if you can spot anything incorrect ?
Many thanks in advance !
Dave
Output for cmake is :-
C:\Users\DAVE TRADER\pico-empty-project\build>cmake -G “NMake Makefiles” ..
Using PICO_SDK_PATH from environment (‘C:\Users\DAVE TRADER\pico-sdk’)
PICO_SDK_PATH is C:/Users/DAVE TRADER/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.3.1
— The CXX compiler identification is GNU 11.3.1
— The ASM compiler identification is GNU
— Found assembler: A:/Arm GNU Toolchain arm-none-eabi/11.3 rel1/bin/arm-none-eabi-gcc.exe
Build type is Release
Defaulting PICO target board to pico since not specified.
Using board configuration from C:/Users/DAVE TRADER/pico-sdk/src/boards/include/boards/pico.h
— Found Python3: A:/Python/Python310/python.exe (found version “3.10.7”) found components: Interpreter
TinyUSB available at C:/Users/DAVE TRADER/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; enabling build support for USB.
cyw43-driver available at C:/Users/DAVE TRADER/pico-sdk/lib/cyw43-driver
lwIP available at C:/Users/DAVE TRADER/pico-sdk/lib/lwip
— Configuring done
— Generating done
— Build files have been written to: C:/Users/DAVE TRADER/pico-empty-project/build
NMAKE OUTPUT
Microsoft (R) Program Maintenance Utility Version 14.33.31630.0
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
[ 4%] Creating directories for ‘PioasmBuild’
[ 5%] No download step for ‘PioasmBuild’
[ 7%] No update step for ‘PioasmBuild’
[ 8%] No patch step for ‘PioasmBuild’
[ 10%] Performing configure step for ‘PioasmBuild’
loading initial cache file C:/Users/DAVE TRADER/pico-empty-project/build/pico-sdk/src/rp2_common/cyw43_driver/pioasm/tmp/PioasmBuild-cache-Release.cmake
— The CXX compiler identification is MSVC 19.33.31630.0
— Detecting CXX compiler ABI info
— Detecting CXX compiler ABI info – done
— Check for working CXX compiler: A:/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.33.31629/bin/Hostx86/x86/cl.exe – skipped
— Detecting CXX compile features
— Detecting CXX compile features – done
— Configuring done
— Generating done
— Build files have been written to: C:/Users/DAVE TRADER/pico-empty-project/build/pioasm
[ 11%] Performing build step for ‘PioasmBuild’
Microsoft (R) Program Maintenance Utility Version 14.33.31630.0
Copyright (C) Microsoft Corporation. All rights reserved.
[ 10%] Building CXX object CMakeFiles/pioasm.dir/main.cpp.obj
main.cpp
[ 20%] Building CXX object CMakeFiles/pioasm.dir/pio_assembler.cpp.obj
pio_assembler.cpp
[ 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
[ 50%] Building CXX object CMakeFiles/pioasm.dir/gen/parser.cpp.obj
parser.cpp
[ 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
[ 13%] No install step for ‘PioasmBuild’
[ 14%] Completed ‘PioasmBuild’
[ 14%] Built target PioasmBuild
[ 16%] Generating bs2_default.bin
[ 17%] Generating bs2_default_padded_checksummed.S
[ 17%] Built target bs2_default_padded_checksummed_asm
[ 19%] Creating directories for ‘ELF2UF2Build’
[ 20%] No download step for ‘ELF2UF2Build’
[ 22%] No update step for ‘ELF2UF2Build’
[ 23%] No patch step for ‘ELF2UF2Build’
[ 25%] Performing configure step for ‘ELF2UF2Build’
— The C compiler identification is MSVC 19.33.31630.0
— The CXX compiler identification is MSVC 19.33.31630.0
— Detecting C compiler ABI info
— Detecting C compiler ABI info – done
— Check for working C compiler: A:/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.33.31629/bin/Hostx86/x86/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: A:/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.33.31629/bin/Hostx86/x86/cl.exe – skipped
— Detecting CXX compile features
— Detecting CXX compile features – done
— Configuring done
— Generating done
— Build files have been written to: C:/Users/DAVE TRADER/pico-empty-project/build/elf2uf2
[ 26%] Performing build step for ‘ELF2UF2Build’
Microsoft (R) Program Maintenance Utility Version 14.33.31630.0
Copyright (C) Microsoft Corporation. All rights reserved.
[ 50%] Building CXX object CMakeFiles/elf2uf2.dir/main.cpp.obj
main.cpp
C:\Users\DAVE TRADER\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:\Users\DAVE TRADER\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
[ 28%] No install step for ‘ELF2UF2Build’
[ 29%] Completed ‘ELF2UF2Build’
[ 29%] Built target ELF2UF2Build
Scanning dependencies of target main
[ 31%] Building C object main/CMakeFiles/main.dir/main.c.obj
[ 32%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_stdlib/stdlib.c.obj
[ 34%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_gpio/gpio.c.obj
[ 35%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_claim/claim.c.obj
[ 37%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_platform/platform.c.obj
[ 38%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_sync/sync.c.obj
[ 40%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_irq/irq.c.obj
[ 41%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S.obj
[ 43%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/common/pico_sync/sem.c.obj
[ 44%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/common/pico_sync/lock_core.c.obj
[ 46%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/common/pico_time/time.c.obj
[ 47%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/common/pico_time/timeout_helper.c.obj
[ 49%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_timer/timer.c.obj
[ 50%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/common/pico_util/datetime.c.obj
[ 52%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/common/pico_util/pheap.c.obj
[ 53%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/common/pico_util/queue.c.obj
[ 55%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/common/pico_sync/mutex.c.obj
[ 56%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/common/pico_sync/critical_section.c.obj
[ 58%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_uart/uart.c.obj
[ 59%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_divider/divider.S.obj
[ 61%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_runtime/runtime.c.obj
[ 62%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_clocks/clocks.c.obj
[ 64%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_pll/pll.c.obj
[ 65%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_vreg/vreg.c.obj
[ 67%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c.obj
[ 68%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/hardware_xosc/xosc.c.obj
[ 70%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_printf/printf.c.obj
[ 71%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S.obj
[ 73%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_bootrom/bootrom.c.obj
[ 74%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_divider/divider.S.obj
[ 76%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_double/double_aeabi.S.obj
[ 77%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_double/double_init_rom.c.obj
[ 79%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_double/double_math.c.obj
[ 80%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_double/double_v1_rom_shim.S.obj
[ 82%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S.obj
[ 83%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_float/float_aeabi.S.obj
[ 85%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_float/float_init_rom.c.obj
[ 86%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_float/float_math.c.obj
[ 88%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S.obj
[ 89%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_malloc/pico_malloc.c.obj
[ 91%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S.obj
[ 92%] Building ASM object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_standard_link/crt0.S.obj
[ 94%] Building CXX object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj
[ 95%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj
[ 97%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj
[ 98%] Building C object main/CMakeFiles/main.dir/C_/Users/DAVE_TRADER/pico-sdk/src/rp2_common/pico_stdio_uart/stdio_uart.c.obj
[100%] Linking CXX executable main.elf
a:/armgnu~1/1142da~1.3re/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: a:/armgnu~1/1142da~1.3re/bin/../lib/gcc/arm-none-eabi/11.3.1/thumb/v6-m/nofp\libc.a(libc_a-closer.o): in function `_close_r’:
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/closer.c:47: warning: _close is not implemented and will always fail
a:/armgnu~1/1142da~1.3re/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: a:/armgnu~1/1142da~1.3re/bin/../lib/gcc/arm-none-eabi/11.3.1/thumb/v6-m/nofp\libc.a(libc_a-lseekr.o): in function `_lseek_r’:
/data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/lseekr.c:49: warning: _lseek is not implemented and will always fail
[100%] Built target main
C:\Users\DAVE TRADER\pico-empty-project\build>
Brandon C Rich · June 2, 2023 at 6:47 pm
So I would be willing to bet that your problem has to do with the difference between file systems from Linux to Windows Windows runs in NTFS file system whereas Linux runs a whole bunch of other ones and the problem is is because Windows is copyrighted it does not have any information in it that tells it how to read the other file systems now there may be things that you can update or install and windows nowadays that will allow it I know in Linux you have a thing called the like M tools or are the 3G and NTFS or whatever but basically I always include in my Linux stuff a partition for NTFS just to interact with Windows I know that windows and Linux both can read the fat FAT32 I’m just a different file formats so that’s something that they can share but any of the file systems and Linux so but yeah windows cannot read almost any of the file systems that Linux uses and so that I believe that’s the problem you’re running into