Raspberry Pi Pico 2 was released last month with a Raspberry Pi RP2350 microcontroller equipped with two Arm Cortex-M33 cores and two 32-bit RISC-V “Hazard3” cores with up to two cores usable at any time. So in this guide, we’ll show how to use the RISC-V cores on the RP2350 MCU, compare their performance against the Arm Cortex-M33 cores, and even build Linux for RISC-V for RP2350 boards that have PSRAM.
Apart from the extra memory and more powerful cores, plus new features related to security and the HSTX interface, the Raspberry Pi Pico 2 and Pico will be very similar to the end user and the instructions in our article “Getting Started with Raspberry Pi Pico using MicroPython and C” remain valid. I don’t think there’s a MicroPython RISC-V image yet, so we’ll focus on running C programs on the RISC-V cores.
A quick check with the Arm cores
I received a kit with the Raspberry Pi Pico 2, a micro USB to USB cable, and the Raspberry Pi Debug Probe, and I’ll use all these in this article.
Since we’ll benchmark the Arm cores later, I’ll install the C/C++ environment for Arm first and blink the onboard LED to make sure my Raspberry Pi Pico 2 sample works fine.:Let’s install the dependencies, SDK, and code samples:
1 2 3 4 5 6 |
sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential git clone https://github.com/raspberrypi/pico-sdk cd pico-sdk git submodule update --init cd .. git clone -b master https://github.com/raspberrypi/pico-examples.git |
The steps above are exactly the same as for the Raspberry Pi Pico. Let’s now build the blink_simple demo for the RP2350 target:
1 2 3 4 5 |
cd pico-examples/blink_simple/ export PICO_SDK_PATH=../../pico-sdk cmake -DPICO_PLATFORM=rp2350 .. cd blink_simple make -j16 |
The procedure is almost the same as on the Raspberry Pi Pico, except we need to add “-DPICO_PLATFORM=rp2350” to build the RP2350, as the Pico SDK defaults to RP2040.
We have a bunch of files:
1 2 3 4 5 6 7 8 9 10 |
jaufranc@CNX-LAPTOP-5:~/edev/Raspberry-Pi-Pico-2/pico-examples/blink_simple/blink_simple$ ls -l total 924 -rwxrwxr-x 1 jaufranc jaufranc 5988 Aug 31 10:05 blink_simple.bin -rw-rw-r-- 1 jaufranc jaufranc 61996 Aug 31 10:05 blink_simple.dis -rwxrwxr-x 1 jaufranc jaufranc 391376 Aug 31 10:05 blink_simple.elf -rw-rw-r-- 1 jaufranc jaufranc 316949 Aug 31 10:05 blink_simple.elf.map -rw-rw-r-- 1 jaufranc jaufranc 12800 Aug 31 10:05 blink_simple.uf2 drwxrwxr-x 3 jaufranc jaufranc 4096 Aug 31 10:04 CMakeFiles -rw-rw-r-- 1 jaufranc jaufranc 1161 Aug 31 10:03 cmake_install.cmake -rw-rw-r-- 1 jaufranc jaufranc 132463 Aug 31 10:03 Makefile |
We can confirm the Arm architecture is used here:
1 2 |
file blink_simple.elf blink_simple.elf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped |
Let’s copy the “blink_simple.uf2” firmware to the Raspberry Pi Pico 2 that shows up as RP2350 in the file manager.
The onboard LED starts blinking. Success!
Blinky on the RISC-V cores
Let’s reproduce this on the RISC-V cores. We’ll need to check the Pico C/C++ SDK PDF documentation to get the right toolchain, where we learn (in section 2.10) that only the more recent GCC versions support the Hazard3, meaning it would have to be built from source, or we can select another toolchain such as the CORE-V toolchain available for various Linux distributions and macOS.
My laptop is still running Ubuntu 22.04, so I downloaded and installed the relevant toolchain, and set the export PICO_TOOLCHAIN_PATH and PICO_RISCV_TOOLCHAIN_PATH variables:
1 2 3 4 5 |
cd ../../.. wget https://buildbot.embecosm.com/job/corev-gcc-ubuntu2204/47/artifact/corev-openhw-gcc-ubuntu2204-20240530.tar.gz tar xvf corev-openhw-gcc-ubuntu2204-20240530.tar.gz export PICO_TOOLCHAIN_PATH=~/edev/Raspberry-Pi-Pico-2/corev-openhw-gcc-ubuntu2204-20240530 export PICO_RISCV_TOOLCHAIN_PATH=~/edev/Raspberry-Pi-Pico-2/corev-openhw-gcc-ubuntu2204-20240530 |
Now we can go back to the blink_simple directory and configure the blink_simple sample to be built with the RISC-V toolchain:
1 2 3 |
cd pico-examples/blink_simple/ rm CMakeCache.txt cmake -DPICO_PLATFORM=rp2350-riscv .. |
Let’s check the output of the latest command to make sure the RISC-V toolchain has been selected:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
Using PICO_SDK_PATH from environment ('../../pico-sdk') PICO_SDK_PATH is /home/jaufranc/edev/Raspberry-Pi-Pico-2/pico-sdk Defaulting target board (PICO_BOARD) to 'pico2' since not specified. Using board configuration from /home/jaufranc/edev/Raspberry-Pi-Pico-2/pico-sdk/src/boards/include/boards/pico2.h Pico Platform (PICO_PLATFORM) is 'rp2350-riscv'. -- Defaulting build type to 'Release' since not specified. Defaulting compiler (PICO_COMPILER) to 'pico_riscv_gcc' since not specified. Configuring toolchain based on PICO_COMPILER 'pico_riscv_gcc' Defaulting PICO_GCC_TRIPLE to 'riscv32-unknown-elf;riscv32-corev-elf' -- The C compiler identification is GNU 14.1.0 -- The CXX compiler identification is GNU 14.1.0 -- The ASM compiler identification is GNU -- Found assembler: /home/jaufranc/edev/Raspberry-Pi-Pico-2/corev-openhw-gcc-ubuntu2204-20240530/bin/riscv32-corev-elf-gcc -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /home/jaufranc/edev/Raspberry-Pi-Pico-2/corev-openhw-gcc-ubuntu2204-20240530/bin/riscv32-corev-elf-gcc - 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: /home/jaufranc/edev/Raspberry-Pi-Pico-2/corev-openhw-gcc-ubuntu2204-20240530/bin/riscv32-corev-elf-g++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done Build type is Release -- Found Python3: /usr/bin/python3.10 (found version "3.10.12") found components: Interpreter TinyUSB available at /home/jaufranc/edev/Raspberry-Pi-Pico-2/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; enabling build support for USB. BTstack available at /home/jaufranc/edev/Raspberry-Pi-Pico-2/pico-sdk/lib/btstack cyw43-driver available at /home/jaufranc/edev/Raspberry-Pi-Pico-2/pico-sdk/lib/cyw43-driver lwIP available at /home/jaufranc/edev/Raspberry-Pi-Pico-2/pico-sdk/lib/lwip mbedtls available at /home/jaufranc/edev/Raspberry-Pi-Pico-2/pico-sdk/lib/mbedtls Skipping encrypted example which is unsupported on this platform Skipping hello_dcp example which is unsupported on this platform Skipping cache_perfctr example which is unsupported on this platform Skipping ssi_dma example which is unsupported on this platform Skipping multicore_fifo_irqs example which is unsupported on this platform Skipping RTC examples as hardware_rtc is unavailable on this platform Skipping universal examples as PICO_RISCV_TOOLCHAIN_PATH and PICO_ARM_TOOLCHAIN_PATH are not defined Skipping TinyUSB dual examples, as TinyUSB hw/mcu/raspberry_pi/Pico-PIO-USB submodule unavailable Skipping FreeRTOS examples as FREERTOS_KERNEL_PATH not defined -- Configuring done -- Generating done -- Build files have been written to: /home/jaufranc/edev/Raspberry-Pi-Pico-2/pico-examples/blink_simple |
It looks good. We can also see some of the samples won’t work on RISC-V as they rely on features only available to the Arm cores.
Let’s try to build the sample:
1 2 |
cd blink_simple make |
We have the same bunch of files but with different sizes:
1 2 3 4 5 6 7 8 9 10 |
jaufranc@CNX-LAPTOP-5:~/edev/Raspberry-Pi-Pico-2/pico-examples/blink_simple/blink_simple$ ls -l total 916 -rwxrwxr-x 1 jaufranc jaufranc 6596 Aug 31 10:37 blink_simple.bin -rw-rw-r-- 1 jaufranc jaufranc 109916 Aug 31 10:37 blink_simple.dis -rwxrwxr-x 1 jaufranc jaufranc 344512 Aug 31 10:37 blink_simple.elf -rw-rw-r-- 1 jaufranc jaufranc 322778 Aug 31 10:37 blink_simple.elf.map -rw-rw-r-- 1 jaufranc jaufranc 13824 Aug 31 10:37 blink_simple.uf2 drwxrwxr-x 3 jaufranc jaufranc 4096 Aug 31 10:32 CMakeFiles -rw-rw-r-- 1 jaufranc jaufranc 1237 Aug 31 10:32 cmake_install.cmake -rw-rw-r-- 1 jaufranc jaufranc 121565 Aug 31 10:32 Makefile |
For instance, the blink_simple.uf2 is 13824 bytes when compiled for RISC-V, but was 12800 bytes for Arm.
Let’s double-check our new blink_simple.elf file:
1 2 |
file blink_simple.elf blink_simple.elf: ELF 32-bit LSB executable, UCB RISC-V, RVC, soft-float ABI, version 1 (SYSV), statically linked, with debug_info, not stripped |
RISC-V it is! Another utility to check the architecture is the uf2conv.py script from Microsoft:
1 2 3 4 5 6 7 8 |
jaufranc@CNX-LAPTOP-5:~/edev/Raspberry-Pi-Pico-2/uf2/utils$ ./uf2conv.py -i ~/edev/Raspberry-Pi-Pico-2/pico-examples/blink_simple/blink_simple/blink_simple.uf2 --- UF2 File Header Info --- Family ID is RP2XXX_ABSOLUTE, hex value is 0xe48bff57 Target Address is 0x10ffff00 Family ID is RP2350_RISCV, hex value is 0xe48bff5a Target Address is 0x10000000 All block flag values consistent, 0x2000 ---------------------------- |
Time to enter bootloader mode by pressing the BOOTSEL button and power cycling the Pico 2 board, before copying the blink_simple.uf2 file to the RP2350 drive…
Success! The LED is blinking with the Raspberry Pi Pico 2 running our RISC-V binary.
Serial output on the Raspberry Pi Pico 2 / Cytron MOTION 2350 Pro
Since I’m going to run a benchmark, I’ll need some serial console to visualize the output. I don’t have headers where I am right now, but I do have some jumper cables, so I solder three wires to pin 1 to 3 of the Raspberry Pi Pico 2 and connected it to the Raspberry Pi Debug Probe.
Then I build the hello_world using RISC-V to give it a try:
1 2 3 4 |
cd pico-examples/hello_world/ cmake -DPICO_PLATFORM=rp2350-riscv .. cd hello_world/ make |
But I didn’t find any UF2 file there:
1 2 3 4 5 6 7 |
jaufranc@CNX-LAPTOP-5:~/edev/Raspberry-Pi-Pico-2/pico-examples/hello_world/hello_world$ ls -l total 24 drwxrwxr-x 2 jaufranc jaufranc 4096 Aug 31 12:52 CMakeFiles -rw-rw-r-- 1 jaufranc jaufranc 1566 Aug 31 12:51 cmake_install.cmake -rw-rw-r-- 1 jaufranc jaufranc 4761 Aug 31 12:51 Makefile drwxrwxr-x 3 jaufranc jaufranc 4096 Aug 31 12:53 serial drwxrwxr-x 3 jaufranc jaufranc 4096 Aug 31 12:53 usb |
But after the initial confusion, I realized there are two hello_world samples. The “serial” sample outputs data through serial and requires a USB to TTL board, while the “usb” sample outputs data through USB to serial, so we don’t need the debug probe, and the micro USB to USB cable is enough…
However, it looks like I may have managed to temporarily “brick” my Raspberry Pi Pico 2 (See RISC-V Linux section), and after several failed attempts at recovery, I decided to switch to Cytron MOTION 2350 Pro board for testing that part… I started with the hello_serial.uf2.
This uses the Bootterm program and /dev/ttyACM0 device exposed by the Raspberry Pi Debug Probe.
I then copied the hello_usb.uf2 to the board and only used a USB-C cable and Bootterm connected to /dev/ttyACM1 device exposed by the USB interface of the Raspberry Pi RP2350 microcontroller.
All good. Let’s have a quick look at the hello_serial.c code
1 2 3 4 5 6 7 8 9 10 11 |
#include <stdio.h> #include "pico/stdlib.h" int main() { stdio_init_all(); while (true) { printf("Hello, world!\n"); sleep_ms(1000); } } ~ |
and the hello_usb.c code:
1 2 3 4 5 6 7 8 9 10 |
#include <stdio.h> #include "pico/stdlib.h" int main() { stdio_init_all(); while (true) { printf("Hello, world!\n"); sleep_ms(1000); } } |
Wait… What? Those are the exact same files. The difference is only in the CMakeLists.txt.
Serial:
1 2 3 4 5 6 7 8 9 10 11 12 |
add_executable(hello_serial hello_serial.c ) # pull in common dependencies target_link_libraries(hello_serial pico_stdlib) # create map/bin/hex/uf2 file etc. pico_add_extra_outputs(hello_serial) # add url via pico_set_program_url example_auto_set_url(hello_serial) |
USB:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
cat CMakeLists.txt if (TARGET tinyusb_device) add_executable(hello_usb hello_usb.c ) # pull in common dependencies target_link_libraries(hello_usb pico_stdlib) # enable usb output, disable uart output pico_enable_stdio_usb(hello_usb 1) pico_enable_stdio_uart(hello_usb 0) # create map/bin/hex/uf2 file etc. pico_add_extra_outputs(hello_usb) # add url via pico_set_program_url example_auto_set_url(hello_usb) elseif(PICO_ON_DEVICE) message("Skipping hello_usb because TinyUSB submodule is not initialized in the SDK") endif() |
Simply setting the following two lines switch from serial to USB serial output:
1 2 3 |
# enable usb output, disable uart output pico_enable_stdio_usb(hello_usb 1) pico_enable_stdio_uart(hello_usb 0) |
Good to know.
Coremark on the Arm and RISC-V cores of the Raspberry Pi RP2350 MCU
I wanted to run a benchmark to evaluate the performance of the Hazard3 RISC-V core(s) against the Arm Cortex-M33 core(s). I found the CoreMark-RP2040 project on GitHub, which I managed to build for RISC-V after changing the Makefile to add “-DPICO_PLATFORM=rp2350-riscv” to the cmake command:
1 |
mkdir build && mkdir artifacts_to_upload && cd build && cmake -DPICO_PLATFORM=rp2350-riscv .. -DCMAKE_BUILD_TYPE=Debug && $(BUILD_SYS) |
I also had to export the full path for the Pico SDK even though I have checked out the project in the pico-examples directory. Running make all could complete the build:
1 2 |
export PICO_SDK_PATH=~/edev/Raspberry-Pi-Pico-2/pico-sdk/ make all |
The UF2 file can be found in the artifacts_to_upload directory:
1 2 3 4 |
ls -l artifacts_to_upload/ total 764 -rwxrwxr-x 1 jaufranc jaufranc 667040 Aug 31 15:23 Coremark-RP2040.elf -rw-rw-r-- 1 jaufranc jaufranc 111616 Aug 31 15:23 Coremark-RP2040.uf2 |
I copied it to the RP2350 drive (MOTION 2350 Pro board) and could start the CoreMark benchmark in the serial console, but it did not work:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
jaufranc@CNX-LAPTOP-5:~/edev/Raspberry-Pi-Pico-2$ bt No port specified, using ttyACM1 (last registered). Use -l to list ports. Trying port ttyACM1... Connected to ttyACM1 at 115200 bps. Escape character is 'Ctrl-]'. Use escape followed by '?' for help. CoreMark Performance Benchmark CoreMark measures how quickly your processor can manage linked lists, compute matrix multiply, and execute state machine code. Iterations/Sec is the main benchmark result, higher numbers are better. Press any key to continue.... Running.... (usually requires 12 to 20 seconds) Starting core 0 iterations Starting core 1 iterations |
There must be some modification needed. TaterLi (see comments) told me to set MULTITHREAD to 1 in src/core_portme.h. And indeed it works:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
2K performance run parameters for coremark. CoreMark Size : 666 Total ticks : 13973896 Total time (secs): 13.973896 Iterations/Sec : 286.248016 Iterations : 4000 Compiler version : GCC14.1.0 Compiler flags : og Memory location : STACK seedcrc : 0xe9f5 [0]crclist : 0xe714 [0]crcmatrix : 0x1fd7 [0]crcstate : 0x8e3a [0]crcfinal : 0x65c5 Correct operation validated. See README.md for run and reporting rules. CoreMark 1.0 : 286.248016 / GCC14.1.0 og / STACK |
But something is wrong as the score (286.2 CoreMark/MHz) is completely different from the one in the Hazard3 repository for the RISC-V core found in the RP2350 MCU:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
2K performance run parameters for coremark. CoreMark Size : 666 Total ticks : 15758494 Total time (secs): 15.758494 Iterations/Sec : 3.807470 Iterations : 60 Compiler version : GCC14.2.1 20240807 Compiler flags : -O3 -g -march=rv32ima_zicsr_zifencei_zba_zbb_zbkb_zbs -mbranch-cost=1 -funroll-all-loops --param max-inline-insns-auto=200 -finline-limit=10000 -fno-code-hoisting -fno-if-conversion2 -DPERFORMANCE_RUN=1 Memory location : STACK seedcrc : 0xe9f5 [0]crclist : 0xe714 [0]crcmatrix : 0x1fd7 [0]crcstate : 0x8e3a [0]crcfinal : 0xa14c Correct operation validated. See README.md for run and reporting rules. CoreMark 1.0 : 3.807470 / GCC14.2.1 20240807 -O3 -g -march=rv32ima_zicsr_zifencei_zba_zbb_zbkb_zbs -mbranch-cost=1 -funroll-all-loops --param max-inline-insns-auto=200 -finline-limit=10000 -fno-code-hoisting -fno-if-conversion2 -DPERFORMANCE_RUN=1 / STACK |
That’s 3.81 CoreMark/MHz.
I tried again to run the performance on one of the Arm Cortex-M33 cores:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
2K performance run parameters for coremark. CoreMark Size : 666 Total ticks : 14243088 Total time (secs): 14.243088 Iterations/Sec : 280.837976 Iterations : 4000 Compiler version : GCC10.3.1 20210621 (release) Compiler flags : og Memory location : STACK seedcrc : 0xe9f5 [0]crclist : 0xe714 [0]crcmatrix : 0x1fd7 [0]crcstate : 0x8e3a [0]crcfinal : 0x65c5 Correct operation validated. See README.md for run and reporting rules. CoreMark 1.0 : 280.837976 / GCC10.3.1 20210621 (release) og / STACK |
Here the score is 280.83 CoreMark/MHz or similar to the 286 CoreMark/Mhz for the RISC-V core. Note that it’s not a standardized test…
The 3.81 CoreMark/Mhz reported for the Hazard3 RISC-V is likely better compared to the Cortex-M33 in the LPC55xx microcontroller as the document entitled “LPC55xx CoreMark on Cortex-M33 Porting Guide” mentions 4.08 CoreMark/MHz. In any case, both the Cortex-M33 and Hazard3 cores have very similar integer performance. One person ran a sample with floating-point and the Hazard3 core is currently much slower than the Cortex-M33 cores because it’s using a software implement, while the Cortex-M33 relies on “highly optimized FP routines”.
RISC-V Linux for RP2350 boards with PSRAM
Mr-Bossman has recently released a RISC-V Linux port using the buildroot build system which you can find on GitHub. The Raspberry Pi Pico 2 won’t be able to run RISC-V Linux simply because it does not have enough RAM with only 520KB from the RP2350 MCU and just 4MB flash on the board for storage. That’s why the RISC-V Linux port was tested on the Sparkfun Pro Micro – RP2350 board with 16MB flash and 8MB PSRAM.
Nevertheless, I’ll try to build the Linux image on my laptop, and I’ll also get a working RISC-V gcc toolchain in the process:
1 2 3 4 5 6 |
git clone https://github.com/Mr-Bossman/pi-pico2-linux cd pi-pico2-linux git submodule update --init cd buildroot make BR2_EXTERNAL=$PWD/../ raspberrypi-pico2_defconfig make -j 16 |
This will take a while and ends with:
1 2 3 4 5 6 7 8 |
>>> Executing post-image script support/scripts/genimage.sh INFO: cmd: "mkdir -p "/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/buildroot/output/build/genimage.tmp"" (stderr): INFO: cmd: "rm -rf "/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/buildroot/output/build/genimage.tmp"/*" (stderr): INFO: cmd: "mkdir -p "/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/buildroot/output/images"" (stderr): INFO: hdimage(flash-image.bin): adding primary partition 'raspberrypi-pico2.dtb' from 'raspberrypi-pico2.dtb' ... INFO: hdimage(flash-image.bin): adding primary partition 'Image' from 'Image' ... INFO: hdimage(flash-image.bin): adding primary partition 'rootfs.ext4' from 'rootfs.ext4' ... INFO: cmd: "rm -rf "/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/buildroot/output/build/genimage.tmp/"" (stderr): |
We can check the resulting images in the relevant directory:
1 2 3 4 5 6 7 8 9 10 |
jaufranc@CNX-LAPTOP-5:~/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/buildroot$ ls -lh output/images/ total 13M -rw-r--r-- 1 jaufranc jaufranc 6.0M Aug 31 11:51 flash-image.bin -rw-r--r-- 1 jaufranc jaufranc 3.1M Aug 31 11:28 Image -rwxr-xr-x 1 jaufranc jaufranc 1.2K Aug 31 11:28 raspberrypi-pico2.dtb -rw-r--r-- 1 jaufranc jaufranc 833K Aug 31 11:51 rootfs.cpio -rw-r--r-- 1 jaufranc jaufranc 454K Aug 31 11:51 rootfs.cpio.gz -rw-r--r-- 1 jaufranc jaufranc 2.0M Aug 31 11:51 rootfs.ext2 lrwxrwxrwx 1 jaufranc jaufranc 11 Aug 31 11:51 rootfs.ext4 -> rootfs.ext2 -rw-r--r-- 1 jaufranc jaufranc 1.2M Aug 31 11:51 rootfs.tar |
“Image” is the Linux kernel, “rootfs.ext2” the root file systems, “raspberrypi-pico2.dtb” the device tree file, and “flash-image.bin” the complete image. It is 6MB in size, so you’d need a Raspberry Pi RP2350 board with at least 8MB flash plus some PSRAM.
We are not quite finished and we have one more command to complete the build:
1 2 |
cd ../psram-bootloader make flash-kernel |
The last command fails with:
1 2 3 4 5 6 7 8 9 |
cd build && cmake .. CMake Error at pico_sdk_import.cmake:74 (message): Directory '/home/jaufranc/.pico-sdk/sdk/2.0.0' not found Call Stack (most recent call first): CMakeLists.txt:40 (include) -- Configuring incomplete, errors occurred! make: *** [Makefile:10: build/Makefile] Error 1 |
That’s because CMakeList.txt needs to be updated to match the config of your system, notably the three lines below:
1 2 3 |
set(PICO_SDK_PATH ${USERHOME}/edev/Raspberry-Pi-Pico-2/pico-sdk/) set(PICO_TOOLCHAIN_PATH ${USERHOME}/edev/Raspberry-Pi-Pico-2/corev-openhw-gcc-ubuntu2204-20240530) set(pioasm_HINT ${USERHOME}/edev/Raspberry-Pi-Pico-2/pico-sdk/tools/pioasm) |
After changing those lines the build could complete and only failed when trying to flash the image since I didn’t connect any:
1 2 3 4 5 6 7 8 9 10 |
[ 98%] Building C object CMakeFiles/psram-bootloader.dir/home/jaufranc/edev/Raspberry-Pi-Pico-2/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c.obj [100%] Linking CXX executable psram-bootloader.elf make[3]: Leaving directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader/build' [100%] Built target psram-bootloader make[2]: Leaving directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader/build' make[1]: Leaving directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader/build' make[1]: Entering directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader' Makefile:26: *** No RP2350 device found. Stop. make[1]: Leaving directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader' make: *** [Makefile:31: flash] Error 2 |
If I connect my Raspberry Pi Pico 2 it goes further asking me for the sudo password when running picotool to flash the image for the board:
1 2 3 4 5 6 7 8 9 10 11 |
[100%] Built target psram-bootloader make[2]: Leaving directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader/build' make[1]: Leaving directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader/build' make[1]: Entering directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader' cp build/psram-bootloader.uf2 "/media/jaufranc/RP2350"/ make[1]: Leaving directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader' sleep 3 make[1]: Entering directory '/home/jaufranc/edev/Raspberry-Pi-Pico-2/pi-pico2-linux/psram-bootloader' You must be root! sudo make picotool PICOTOOL_ARGS='load -fxp 0 ../buildroot/output/images/flash-image.bin' [sudo] password for jaufranc: |
Since it’s designed for the Sparkfun Pro Micro – RP2350 only, I stopped there. It still managed to change something as my Pi Pico 2 won’t run the blinky sample and outputs the following in the serial console:
1 2 3 |
Invalid PSRAM ID: 0 PSRAM setup failed Press any key to reset. |
That’s because a new bootloader was copied to the board:
1 |
cp build/psram-bootloader.uf2 "/media/jaufranc/RP2350"/ |
I’m stuck. While I can copy a different UF2 firmware, the board won’t reboot, and the update apparently fails since it’s still running the psram-bootloader after a power cycle. I’ve asked on Raspberry Pi forums and we’ll see if there’s a solution. [Update: The solution – in the comments section below and the forum thread – was to simply copy flash_nuke.uf2 to the board to clear the flash].
That will be all. I hope this article can help some people more easily get started with the RISC-V cores on the Raspberry Pi Pico 2 board and RP2350 MCU.
Jean-Luc started CNX Software in 2010 as a part-time endeavor, before quitting his job as a software engineering manager, and starting to write daily news, and reviews full time later in 2011.
Support CNX Software! Donate via cryptocurrencies, become a Patron on Patreon, or purchase goods on Amazon or Aliexpress
clean
make -j4 ( four )
how long does it take: make a blink
I managed to mess up my board by using GDB to load an ESP32-H2 elf file, which writes to ~0x4000_0000. Revived it by finding, downloading and loading flash_nuke.uf2 to clear all flash
I had seen that one, but my problem is that copying UF2 files to the board does nothing. Maybe I’ll try later.
Using flash_nuke.uf2 @ https://datasheets.raspberrypi.com/soft/flash_nuke.uf2 did help me recover access to my board. The blink_simple code is working again.
Modify MULTITHREAD to 1, located in core_portme.h, because at present RP2350 no matter RISC-V or ARM platform, his multi-core support is not very perfect.
BUILD_TYPE=Debug RISC-V Result:
Thanks. It works now, but the score does not look right…
It could be compiler or no optimization (debug mode) related.
The compiler is based on a recent build of riscv/riscv-gnu-toolchain.
Use better compilation args (rv)
Can anyone enlighten me what is the rationel behind adding two kinds of cores? Feels like silicon waste (ie price hike) without any benefit, except it’s kinda cool?
I view that as a long-term plan to experiment with RISC-V cores while keeping a proven solution with the Arm Cortex-M33 cores.
Most people will still use the Arm cores, but this will allow developers to grow the ecosystem around RISC-V cores, and if this works well, some future (and cheaper) Raspberry Pi microcontrollers may be RISC-V only.
The extra cost must have been low enough to justify adding the RISC-V cores.
Thanks!
This is an interesting article. It’s a good way to get some risv-v experience.