This is an old revision of the document!
Table of Contents
Raspberry Pi PICO
Dual core Arm Cortex-M0 microcontroller designed to run MicroPython.
There are four varieties of PICO version 1 board produced by RPi. The differences are whether they come pre-installed with header pins and a debug socket and if they have a WiFi adapter on board.
Power
VBUS USB 5V VSYS 1.8 to 5.5V Ground 3V3_EN 3V3 300mA MAX
Bootloader
Entry to the bootloader occurs when either the flash is empty or the BOOTSEL button is depressed when plugging in the device.
Mounting the drive will gain access to firmware upload.
mount /dev/sda1 /mnt cat /mnt/INFO_UF2.TXT
RP2040-B1
UF2 Bootloader v2.0 Model: Raspberry Pi RP2 Board-ID: RPI-RP2
RP2040-B2
UF2 Bootloader v3.0 Model: Raspberry Pi RP2 Board-ID: RPI-RP2
UF2 Bootloader v3.0 Model: Raspberry Pi RP2 Board-ID: RPI-RP2
RP2350-A2
UF2 Bootloader v1.0 Model: Raspberry Pi RP2350 Board-ID: RP2350
SDK
apt install build-essential git pkg-config libusb-1.0-0-dev cmake
mkdir -p /opt cd /opt git clone https://github.com/raspberrypi/pico-sdk cd pico-sdk git submodule update --init
setenv PICO_SDK_PATH /opt/pico-sdk
FreeRTOS
cd /opt git clone https://github.com/FreeRTOS/FreeRTOS-Kernel
setenv FREERTOS_KERNEL_PATH /opt/FreeRTOS-Kernel
Picotool
This tool is used to convert ELF binaries into UF2 objects to upload to the PICO. and to inspect running firmware via the bootloader.
mkdir -p /opt/src cd /opt/src git clone https://github.com/raspberrypi/picotool cd picotool git submodule update --init mkdir build cd build cmake .. make make install
cp /opt/src/picotool/udev/99-picotool.rules /etc/udev/rules.d udevadm control --reload-rules udevadm trigger
Picotool can show flash info when in bootloader mode.
Below are two PICOs which contain no firmware and one other running debugprobe.
RP2040
picotool info -a Multiple RP2040 devices in BOOTSEL mode found: Device at bus 1, address 37: ---------------------------- Program Information none Fixed Pin Information none Build Information none Device Information type: RP2040 revision: B2 Device at bus 1, address 40: ---------------------------- Program Information none Fixed Pin Information none Build Information none Device Information type: RP2040 revision: B2 Device at bus 1, address 41: ---------------------------- Program Information name: debugprobe features: PROBE UART BAUDRATE 115200 PROBE UART INTERFACE uart1 UART stdin / stdout binary start: 0x10000000 binary end: 0x10009f70 Fixed Pin Information 0: UART0 TX, UART0 TX 1: UART0 RX, UART0 RX 2: PROBE SWCLK 3: PROBE SWDIO 4: PROBE UART TX 5: PROBE UART RX 25: LED Build Information sdk version: 2.0.0 pico_board: pico build date: Aug 23 2024 build attributes: Release Device Information type: RP2040 revision: B1 flash size: 2048K flash id: 0xE66038B7135F7437
RP2350
Program Information none Fixed Pin Information none Build Information none Device Information type: RP2350 revision: A2 package: QFN60 chipid: 0x1c789de3e289c250 flash devinfo: 0x0c00 current cpu: ARM available cpus: ARM, RISC-V default cpu: ARM secure boot: 0 debug enable: 1 secure debug enable: 1 boot_random: 509d1a5d:1a015864:615e1d4b:c7483967 boot type: normal last booted partition: none diagnostic source: slot 0 last boot diagnostics: 0x00010041 rom gitrev: 0x312e22fa
Reboot firmware on specific device
picotool reboot --bus 1 --address 41
Debugprobe
Debugprobe turns a Pi PICO into a debugger which can then be used to debug another Pi PICO.
This project was previously known as picoprobe and the difference would appear to be change in protocol from picoprobe to cmsis-dap as the interface when using OpenOCD.
This is cheap alternative to buying a dedicated debugger.
NB on the Pi Pico revision B1 Debugprobe will disconnect from the USB bus and lock up when using its UART feature. This was seen on a Pi 4B host. This fault has not been seen when using a Pi Pico revision B2 on the same host.
Debug probe depends on GCC-ARM and Picotool to build from source.
cd /opt/src/ git clone https://github.com/raspberrypi/debugprobe cd debugprobe git submodule update --init
debugprobe
The debugprobe is also a dedicated hardware device which uses a PI PICO.
Build and copy debugprobe.uf2 to the debugprobe device.
cd /opt/src/debugprobe mkdir debugprobe cd debugprobe cmake .. make
Pi PICO
A regular PI PICO as a debugger has its own firmware.
Build and copy debugprobe_on_pico.uf2 to a Pi PICO device.
cd /opt/src/debugprobe mkdir debugprobe_on_pico cd debugprobe_on_pico cmake -DDEBUG_ON_PICO=1 .. make
Pi PICO 2
cd /opt/src/debugprobe mkdir debugprobe_on_pico2 cd debugprobe_on_pico2 cmake -DDEBUG_ON_PICO=1 -DPICO_BOARD=pico2 -DPICO_PLATFORM=rp2350 .. make
USB
usb 1-1.1: new full-speed USB device number 5 using dwc_otg usb 1-1.1: New USB device found, idVendor=2e8a, idProduct=000c, bcdDevice= 2.01 usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-1.1: Product: Debugprobe on Pico (CMSIS-DAP) usb 1-1.1: Manufacturer: Raspberry Pi usb 1-1.1: SerialNumber: E66038B7135F7437 cdc_acm 1-1.1:1.1: ttyACM0: USB ACM device usbcore: registered new interface driver cdc_acm cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
OpenOCD
Wiring
debubprobe_on_Pico GND Target Pico GND debugprobe_on_Pico GP2 Target Pico SWCLK debugprobe_on_Pico GP3 Target Pico SWDIO debugprobe_on_Pico GP4/UART1 TX Target Pico GP1/UART0 RX debugprobe_on_pico GP5/UART1 RX Target Pico GP0/UART0 TX
Debug
openocd -f "interface/cmsis-dap.cfg" -f "target/rp2040.cfg" -c "adapter speed 5000" Open On-Chip Debugger 0.12.0+dev-00683-gac63cd00d (2024-08-24-12:37) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : Hardware thread awareness created Info : Hardware thread awareness created adapter speed: 5000 kHz Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E66038B7135F7437 Info : CMSIS-DAP: SWD supported Info : CMSIS-DAP: Atomic commands supported Info : CMSIS-DAP: Test domain timer supported Info : CMSIS-DAP: FW Version = 2.0.0 Info : CMSIS-DAP: Interface Initialised (SWD) Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0 Info : CMSIS-DAP: Interface ready Info : clock speed 5000 kHz Info : SWD DPIDR 0x0bc12477, DLPIDR 0x00000001 Info : SWD DPIDR 0x0bc12477, DLPIDR 0x10000001 Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected Info : [rp2040.core0] target has 4 breakpoints, 2 watchpoints Info : [rp2040.core0] Examination succeed Info : [rp2040.core1] Cortex-M0+ r0p1 processor detected Info : [rp2040.core1] target has 4 breakpoints, 2 watchpoints Info : [rp2040.core1] Examination succeed Info : [rp2040.core0] starting gdb server on 3333 Info : Listening on port 3333 for gdb connections
Program
#! /bin/bash if test $# -ne 1; then echo "missing arg" exit 1 fi ELF=$1 openocd -f "interface/cmsis-dap.cfg" -f "target/rp2040.cfg" -c "adapter speed 5000" \ -c "program $ELF preverify verify reset exit"
Examples
cd /opt/src git clone https://github.com/raspberrypi/pico-examples cd pico-examples mkdir build cd build cmake .. make
cd /opt/src/pico-examples/build/blink openocd -f "interface/cmsis-dap.cfg" -f "target/rp2040.cfg" -c "adapter speed 5000" -c "program blink.elf preverify verify reset exit" Open On-Chip Debugger 0.12.0-00024-g34afaa939 (2024-08-26-02:18) [https://github.com/STMicroelectronics/OpenOCD] Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html adapter speed: 5000 kHz Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E66038B7135F7437 Info : CMSIS-DAP: SWD supported Info : CMSIS-DAP: Atomic commands supported Info : CMSIS-DAP: Test domain timer supported Info : CMSIS-DAP: FW Version = 2.0.0 Info : CMSIS-DAP: Interface Initialised (SWD) Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0 Info : CMSIS-DAP: Interface ready Info : clock speed 5000 kHz Info : SWD DPIDR 0x0bc12477, DLPIDR 0x00000001 Info : SWD DPIDR 0x0bc12477, DLPIDR 0x10000001 Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected Info : [rp2040.core0] target has 4 breakpoints, 2 watchpoints Info : [rp2040.core1] Cortex-M0+ r0p1 processor detected Info : [rp2040.core1] target has 4 breakpoints, 2 watchpoints Info : starting gdb server for rp2040.core0 on 3333 Info : Listening on port 3333 for gdb connections Info : starting gdb server for rp2040.core1 on 3334 Info : Listening on port 3334 for gdb connections [rp2040.core0] halted due to debug-request, current mode: Thread xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00 [rp2040.core1] halted due to debug-request, current mode: Thread xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00 **pre-verifying** Error: checksum mismatch - attempting binary compare ** Programming Started ** Info : Found flash device 'win w25q16jv' (ID 0x001540ef) Info : RP2040 B0 Flash Probe: 2097152 bytes @0x10000000, in 32 sectors Info : Padding image section 1 at 0x100019ec with 20 bytes (bank write end alignment) Warn : Adding extra erase range, 0x10001a00 .. 0x1000ffff ** Programming Finished ** ** Verify Started ** ** Verified OK ** ** Resetting Target ** shutdown command invoked
J-Link
Segger J-Link can be use to interact with the PICO via the debug port.
Connect SWCLK, SWDIO and VREF on the target PICO.
CORE 0
echo "exit" | /opt/JLink/JLinkExe -device RP2040_M0_0 -if swd -speed 4000 -autoconnect 1 -nogui 1 SEGGER J-Link Commander V7.82a (Compiled Oct 31 2022 11:25:49) DLL version V7.82a, compiled Oct 31 2022 11:25:22 Connecting to J-Link via USB...O.K. Firmware: J-Link EDU Mini V1 compiled Oct 21 2022 11:17:52 Hardware version: V1.00 J-Link uptime (since boot): 0d 00h 09m 41s S/N: 801011752 License(s): FlashBP, GDB USB speed mode: Full speed (12 MBit/s) VTref=3.259V Device "RP2040_M0_0" selected. Connecting to target via SWD ConfigTargetSettings() start J-Link script: ConfigTargetSettings() ConfigTargetSettings() end Found SW-DP with ID 0x0BC12477 DPIDR: 0x0BC12477 CoreSight SoC-400 or earlier Scanning AP map to find all available APs AP[1]: Stopped AP scan as end of AP map has been reached AP[0]: AHB-AP (IDR: 0x04770031) Iterating through AP map to find AHB-AP to use AP[0]: Core found AP[0]: AHB-AP ROM base: 0xE00FF000 CPUID register: 0x410CC601. Implementer code: 0x41 (ARM) Found Cortex-M0 r0p1, Little endian. FPUnit: 4 code (BP) slots and 0 literal slots CoreSight components: ROMTbl[0] @ E00FF000 [0][0]: E000E000 CID B105E00D PID 000BB008 SCS [0][1]: E0001000 CID B105E00D PID 000BB00A DWT [0][2]: E0002000 CID B105E00D PID 000BB00B FPB Cortex-M0 identified.
CORE 1
echo "exit" | /opt/JLink/JLinkExe -device RP2040_M0_1 -if swd -speed 4000 -autoconnect 1 -nogui 1 SEGGER J-Link Commander V7.82a (Compiled Oct 31 2022 11:25:49) DLL version V7.82a, compiled Oct 31 2022 11:25:22 Connecting to J-Link via USB...O.K. Firmware: J-Link EDU Mini V1 compiled Oct 21 2022 11:17:52 Hardware version: V1.00 J-Link uptime (since boot): 0d 00h 09m 48s S/N: 801011752 License(s): FlashBP, GDB USB speed mode: Full speed (12 MBit/s) VTref=3.260V Device "RP2040_M0_1" selected. Connecting to target via SWD ConfigTargetSettings() start J-Link script: ConfigTargetSettings() ConfigTargetSettings() end Found SW-DP with ID 0x0BC12477 DPIDR: 0x0BC12477 CoreSight SoC-400 or earlier Scanning AP map to find all available APs AP[1]: Stopped AP scan as end of AP map has been reached AP[0]: AHB-AP (IDR: 0x04770031) Iterating through AP map to find AHB-AP to use AP[0]: Core found AP[0]: AHB-AP ROM base: 0xE00FF000 CPUID register: 0x410CC601. Implementer code: 0x41 (ARM) Found Cortex-M0 r0p1, Little endian. FPUnit: 4 code (BP) slots and 0 literal slots CoreSight components: ROMTbl[0] @ E00FF000 [0][0]: E000E000 CID B105E00D PID 000BB008 SCS [0][1]: E0001000 CID B105E00D PID 000BB00A DWT [0][2]: E0002000 CID B105E00D PID 000BB00B FPB Cortex-M0 identified.