Git Product home page Git Product logo

picotool's Introduction

Building

You need to set PICO_SDK_PATH in the environment, or pass it to cmake with -DPICO_SDK_PATH=/path/to/pico-sdk. To use features such as signing or hashing, you will need to make sure the mbedtls submodule in the SDK is checked out - this can be done by running this from your SDK directory.

git submodule update --init lib/mbedtls

You also need to install libusb-1.0.

Linux / macOS

Use your favorite package tool to install dependencies. For example, on Ubuntu:

sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake

Then simply build like a normal CMake project:

mkdir build
cd build
cmake ..
make

On Linux you can add udev rules in order to run picotool without sudo:

sudo cp udev/99-picotool.rules /etc/udev/rules.d/

Windows

For Windows without MinGW

Download libUSB from here https://libusb.info/

set LIBUSB_ROOT environment variable to the install directory.

mkdir build
cd build
cmake -G "NMake Makefiles" ..
nmake
For Windows with MinGW in WSL

Download libUSB from here https://libusb.info/

set LIBUSB_ROOT environment variable to the install directory.

mkdir build
cd build
cmake ..
make
For Windows with MinGW in MSYS2:

No need to download libusb separately or set LIBUSB_ROOT.

pacman -S $MINGW_PACKAGE_PREFIX-{toolchain,cmake,libusb}
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
cmake --build .

Usage by the Raspberry Pi Pico SDK

The Raspberry Pi Pico SDK (pico-sdk) version 2.0.0 and above uses picotool to do the ELF-to-UF2 conversion previously handled by the elf2uf2 tool in the SDK. The SDK also uses picotool to hash and sign binaries.

Whilst the SDK can download picotool on its own per project, if you have multiple projects or build configurations, it is preferable to install a single copy of picotool locally. This can be done most simply with make install or cmake --install .; the SDK will use this installed version by default.

Alternatively, you can install to a custom path via:

cmake -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR -DPICOTOOL_FLAT_INSTALL=1 ..

In order for the SDK to find picotool in this custom path, you will need to set the picotool_DIR variable in your project, either by setting the picotool_DIR environment variable, by passing -Dpicotool_DIR=$MY_INSTALL_DIR/picotool to your cmake command, or by adding set(picotool_DIR $MY_INSTALL_DIR/picotool) to your CMakeLists.txt file.

Overview

picotool is a tool for working with RP2040/RP2350 binaries, and interacting with RP2040/RP2350 devices when they are in BOOTSEL mode. (As of version 1.1 of picotool it is also possible to interact with devices that are not in BOOTSEL mode, but are using USB stdio support from the Raspberry Pi Pico SDK by using the -f argument of picotool).

Note for additional documentation see https://rptl.io/pico-get-started

$ picotool help
PICOTOOL:
Tool for interacting with RP2040/RP2350 device(s) in BOOTSEL mode, or with an RP2040/RP2350 binary

SYNOPSIS:
    picotool info [-b] [-p] [-d] [--debug] [-l] [-a] [device-selection]
    picotool info [-b] [-p] [-d] [--debug] [-l] [-a] <filename> [-t <type>]
    picotool config [-s <key> <value>] [-g <group>] [device-selection]
    picotool config [-s <key> <value>] [-g <group>] <filename> [-t <type>]
    picotool load [-p] [-n] [-N] [-u] [-v] [-x] <filename> [-t <type>] [-o <offset>] [device-selection]
    picotool encrypt [--quiet] [--verbose] [--hash] [--sign] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> [-t <type>] [<signing_key>] [-t <type>]
    picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] [<key>] [-t <type>] [<otp>] [-t <type>] [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]]
    picotool link [--quiet] [--verbose] <outfile> [-t <type>] <infile1> [-t <type>] <infile2> [-t <type>] [<infile3>] [-t <type>] [-p] <pad>
    picotool save [-p] [device-selection]
    picotool save -a [device-selection]
    picotool save -r <from> <to> [device-selection]
    picotool verify [device-selection]
    picotool reboot [-a] [-u] [-g <partition>] [-c <cpu>] [device-selection]
    picotool otp list|get|set|load|dump|permissions|white-label
    picotool partition info|create
    picotool uf2 info|convert
    picotool version [-s] [<version>]
    picotool coprodis [--quiet] [--verbose] <infile> [-t <type>] <outfile> [-t <type>]
    picotool help [<cmd>]

COMMANDS:
    info        Display information from the target device(s) or file.
                Without any arguments, this will display basic information for all connected RP2040 devices in BOOTSEL mode
    config      Display or change program configuration settings from the target device(s) or file.
    load        Load the program / memory range stored in a file onto the device.
    encrypt     Encrypt the program.
    seal        Add final metadata to a binary, optionally including a hash and/or signature.
    link        Link multiple binaries into one block loop.
    save        Save the program / memory stored in flash on the device to a file.
    verify      Check that the device contents match those in the file.
    reboot      Reboot the device
    otp         Commands related to the RP2350 OTP (One-Time-Programmable) Memory
    partition   Commands related to RP2350 Partition Tables
    uf2         Commands related to UF2 creation and status
    version     Display picotool version
    coprodis    Post-process coprocessor instructions in dissassembly files.
    help        Show general help or help for a specific command

Use "picotool help <cmd>" for more info

Note commands that aren't acting on files require a device in BOOTSEL mode to be connected.

info

The is Binary Information support in the SDK which allows for easily storing compact information that picotool can find (See Binary Info section below). The info command is for reading this information.

The information can be either read from one or more connected devices in BOOTSEL mode, or from a file. This file can be an ELF, a UF2 or a BIN file.

$ picotool help info
INFO:
    Display information from the target device(s) or file.
    Without any arguments, this will display basic information for all connected RP2040 devices in BOOTSEL mode

SYNOPSIS:
    picotool info [-b] [-p] [-d] [--debug] [-l] [-a] [device-selection]
    picotool info [-b] [-p] [-d] [--debug] [-l] [-a] <filename> [-t <type>]

OPTIONS:
    Information to display
        -b, --basic
            Include basic information. This is the default
        -p, --pins
            Include pin information
        -d, --device
            Include device information
        --debug
            Include device debug information
        -l, --build
            Include build attributes
        -a, --all
            Include all information

TARGET SELECTION:
    To target one or more connected RP2040 device(s) in BOOTSEL mode (the default)
        --bus <bus>
            Filter devices by USB bus number
        --address <addr>
            Filter devices by USB device address
        --vid <vid>
            Filter by vendor id
        --pid <pid>
            Filter by product id
        --ser <ser>
            Filter by serial number
        -f, --force
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
        -F, --force-no-reboot
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but without the
            RPI-RP2 drive mounted
    To target a file
        <filename>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension

Note the -f arguments vary slightly for Windows vs macOS / Unix platforms.

e.g.

$ picotool info Program Information name: hello_world features: stdout to UART



$ picotool info -a
Program Information
 name:          hello_world
 features:      stdout to UART
 binary start:  0x10000000
 binary end:    0x1000606c

Fixed Pin Information
 20:  UART1 TX
 21:  UART1 RX

Build Information
 build date:        Dec 31 2020
 build attributes:  Debug build

Device Information
 flash size:   2048K
 ROM version:  2

$ picotool info -bp Program Information name: hello_world features: stdout to UART

Fixed Pin Information 20: UART1 TX 21: UART1 RX



$ picotool info -a lcd_1602_i2c.uf2
File lcd_1602_i2c.uf2:

Program Information
 name:          lcd_1602_i2c
 web site:      https://github.com/raspberrypi/pico-examples/tree/HEAD/i2c/lcd_1602_i2c
 binary start:  0x10000000
 binary end:    0x10003c1c

Fixed Pin Information
 4:  I2C0 SDA
 5:  I2C0 SCL

Build Information
 build date:  Dec 31 2020

config

Config allows you to configure the binary info on a device, if it is configurable. Specifically, you can configure bi_ptr_int32 and bi_ptr_string.

$ picotool help config
CONFIG:
    Display or change program configuration settings from the target device(s) or file.

SYNOPSIS:
    picotool config [-s <key> <value>] [-g <group>] [device-selection]
    picotool config [-s <key> <value>] [-g <group>] <filename> [-t <type>]

OPTIONS:
        <key>
            Variable name
        <value>
            New value
        -g <group>
            Filter by feature group

TARGET SELECTION:
    To target one or more connected RP2040 device(s) in BOOTSEL mode (the default)
        --bus <bus>
            Filter devices by USB bus number
        --address <addr>
            Filter devices by USB device address
        --vid <vid>
            Filter by vendor id
        --pid <pid>
            Filter by product id
        --ser <ser>
            Filter by serial number
        -f, --force
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
        -F, --force-no-reboot
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but without the
            RPI-RP2 drive mounted
    To target a file
        <filename>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
$ picotool config
n = 5
name = "Billy"
nonconst_pins:
 default_pin = 3
 default_name = "My First Pin"
$ picotool config -g nonconst_pins
nonconst_pins:
 default_pin = 3
 default_name = "My First Pin"
$ picotool config -s name Jane
name = "Billy"
setting name -> "Jane"

$ picotool config
n = 5
name = "Jane"
nonconst_pins:
 default_pin = 3
 default_name = "My First Pin"

load

load allows you to write data from a file onto the device (either writing to flash, or to RAM)

$ picotool help load
LOAD:
    Load the program / memory range stored in a file onto the device.

SYNOPSIS:
    picotool load [--ignore-partitions] [--family <family_id>] [-p <partition>] [-n] [-N] [-u] [-v] [-x] <filename> [-t <type>] [-o
                <offset>] [device-selection]

OPTIONS:
    Post load actions
        --ignore-partitions
            When writing flash data, ignore the partition table and write to absolute space
        --family
            Specify the family ID of the file to load
        <family_id>
            family id to use for load
        -p, --partition
            Specify the partition to load into
        <partition>
            partition to load into
        -n, --no-overwrite
            When writing flash data, do not overwrite an existing program in flash. If picotool cannot determine the size/presence of the
            program in flash, the command fails
        -N, --no-overwrite-unsafe
            When writing flash data, do not overwrite an existing program in flash. If picotool cannot determine the size/presence of the
            program in flash, the load continues anyway
        -u, --update
            Skip writing flash sectors that already contain identical data
        -v, --verify
            Verify the data was written correctly
        -x, --execute
            Attempt to execute the downloaded file as a program after the load
    File to load from
        <filename>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
    BIN file options
        -o, --offset
            Specify the load address for a BIN file
        <offset>
            Load offset (memory address; default 0x10000000)
    Target device selection
        --bus <bus>
            Filter devices by USB bus number
        --address <addr>
            Filter devices by USB device address
        --vid <vid>
            Filter by vendor id
        --pid <pid>
            Filter by product id
        --ser <ser>
            Filter by serial number
        -f, --force
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
        -F, --force-no-reboot
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but without the
            RPI-RP2 drive mounted

e.g.

$ picotool load blink.uf2
Loading into Flash: [==============================]  100%

save

save allows you to save a range of RAM, the program in flash, or an explicit range of flash from the device to a BIN file or a UF2 file.

$ picotool help save
SAVE:
    Save the program / memory stored in flash on the device to a file.

SYNOPSIS:
    picotool save [-p] [device-selection]
    picotool save -a [device-selection]
    picotool save -r <from> <to> [device-selection]

OPTIONS:
    Selection of data to save
        -p, --program
            Save the installed program only. This is the default
        -a, --all
            Save all of flash memory
        -r, --range
            Save a range of memory. Note that UF2s always store complete 256 byte-aligned blocks of 256 bytes, and the range is expanded
            accordingly
        <from>
            The lower address bound in hex
        <to>
            The upper address bound in hex
    Source device selection
        --bus <bus>
            Filter devices by USB bus number
        --address <addr>
            Filter devices by USB device address
        --vid <vid>
            Filter by vendor id
        --pid <pid>
            Filter by product id
        --ser <ser>
            Filter by serial number
        -f, --force
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
        -F, --force-no-reboot
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but without the
            RPI-RP2 drive mounted
    File to save to
        <filename>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension

e.g. first looking at what is on the device...

$ picotool info
Program Information
name:      lcd_1602_i2c
web site:  https://github.com/raspberrypi/pico-examples/tree/HEAD/i2c/lcd_1602_i2c

... saving it to a file ...

$ picotool save spoon.uf2
Saving file: [==============================]  100%
Wrote 51200 bytes to spoon.uf2

... and looking at the file:

$ picotool info spoon.uf2
File spoon.uf2:
Program Information
name:      lcd_1602_i2c
web site:  https://github.com/raspberrypi/pico-examples/tree/HEAD/i2c/lcd_1602_i2c

seal

seal allows you to sign and/or hash a binary to run on RP2350.

By default, it will just sign the binary, but this can be configured with the --hash and --no-sign arguments.

Your signing key must be for the secp256k1 curve, in PEM format. You can create a .PEM file with:

openssl ecparam -name secp256k1 -genkey -out private.pem
$ picotool help seal
SEAL:
    Add final metadata to a binary, optionally including a hash and/or signature.

SYNOPSIS:
    picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] [<key>] [-t
                <type>] [<otp>] [-t <type>] [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]]

OPTIONS:
        --quiet
            Don't print any output
        --verbose
            Print verbose output
        --major <major>
            Add Major Version
        --minor <minor>
            Add Minor Version
        --rollback <rollback> [<rows>..]
            Add Rollback Version
    Configuration
        --hash
            Hash the file
        --sign
            Sign the file
        --clear
            Clear all of SRAM on load
    File to load from
        <infile>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
    BIN file options
        -o, --offset
            Specify the load address for a BIN file
        <offset>
            Load offset (memory address; default 0x10000000)
    File to save to
        <outfile>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
    Key file
        <key>
            The file name
        -t <type>
            Specify file type (pem) explicitly, ignoring file extension
    File to save OTP to (will edit existing file if it exists)
        <otp>
            The file name
        -t <type>
            Specify file type (json) explicitly, ignoring file extension

encrypt

encrypt allows you to encrypt and sign a binary for use on the RP2350. By default, it will sign the encrypted binary, but that can be configured similarly to picotool sign.

The encrypted binary will have the following structure:

  • First metadata block (5 words)
  • IV (4 words)
  • Encrypted Binary
  • Padding to ensure the encrypted length is a multiple of 4 words
  • Signature metadata block

The AES key must be provided as a .bin file of the 256 bit AES key to be used for encryption.

$ picotool help encrypt
ENCRYPT:
    Encrypt the program.

SYNOPSIS:
    picotool encrypt [--quiet] [--verbose] [--hash] [--sign] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> [-t <type>]
                [<signing_key>] [-t <type>]

OPTIONS:
        --quiet
            Don't print any output
        --verbose
            Print verbose output
    Signing Configuration
        --hash
            Hash the encrypted file
        --sign
            Sign the encrypted file
    File to load from
        <infile>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
    BIN file options
        -o, --offset
            Specify the load address for a BIN file
        <offset>
            Load offset (memory address; default 0x10000000)
    File to save to
        <outfile>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
    AES Key
        <aes_key>
            The file name
        -t <type>
            Specify file type (bin) explicitly, ignoring file extension
    Signing Key file
        <signing_key>
            The file name
        -t <type>
            Specify file type (pem) explicitly, ignoring file extension

partition

The partition commands allow you to interact with the partition tables on RP2350 devices, and also create them.

info

$ picotool help partition info
PARTITION INFO:
    Print the device's partition table.

SYNOPSIS:
    picotool partition info -m <family_id> [device-selection]

OPTIONS:
        -m <family_id> [device-selection]
$ picotool partition info
un-partitioned_space :  S(rw) NSBOOT(rw) NS(rw), uf2 { absolute }
partitions:
  0(A)       00002000->00201000 S(rw) NSBOOT(rw) NS(rw), id=0000000000000000, "A", uf2 { rp2350-arm-s, rp2350-riscv }, arm_boot 1, riscv_boot 1
  1(B w/ 0)  00201000->00400000 S(rw) NSBOOT(rw) NS(rw), id=0000000000000001, "B", uf2 { rp2350-arm-s, rp2350-riscv }, arm_boot 1, riscv_boot 1
$ picotool partition info -m rp2350-arm-s
un-partitioned_space :  S(rw) NSBOOT(rw) NS(rw), uf2 { absolute }
partitions:
  0(A)       00002000->00201000 S(rw) NSBOOT(rw) NS(rw), id=0000000000000000, "A", uf2 { rp2350-arm-s, rp2350-riscv }, arm_boot 1, riscv_boot 1
  1(B w/ 0)  00201000->00400000 S(rw) NSBOOT(rw) NS(rw), id=0000000000000001, "B", uf2 { rp2350-arm-s, rp2350-riscv }, arm_boot 1, riscv_boot 1
Family id 'rp2350-arm-s' can be downloaded in partition 0:
  00002000->00201000

create

This command allows you to create partition tables, and additionally embed them into the block loop if ELF files (for example, for bootloaders). By default, all partition tables are hashed, and you can also sign them.

$ picotool help partition create
PARTITION CREATE:
    Create a partition table from json

SYNOPSIS:
    picotool partition create [--quiet] [--verbose] <infile> [-t <type>] <outfile> [-t <type>] [[-o <offset>] [--family <family_id>]]
                [<bootloader>] [-t <type>] [[--sign <keyfile>] [-t <type>] [--no-hash] [--singleton]] [[--abs-block] [<abs_block_loc>]]

OPTIONS:
        --quiet
            Don't print any output
        --verbose
            Print verbose output
    partition table JSON
        <infile>
            The file name
        -t <type>
            Specify file type (json) explicitly, ignoring file extension
    output file
        <outfile>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
    UF2 output options
        -o, --offset
            Specify the load address for UF2 file output
        <offset>
            Load offset (memory address; default 0x10000000)
        --family
            Specify the family if for UF2 file output
        <family_id>
            family id for UF2 (default absolute)
    embed partition table into bootloader ELF
        <bootloader>
            The file name
        -t <type>
            Specify file type (elf) explicitly, ignoring file extension
    Partition Table Options
        --sign <keyfile>
            The file name
        -t <type>
            Specify file type (pem) explicitly, ignoring file extension
        --no-hash
            Don't hash the partition table
        --singleton
            Singleton partition table
    Errata RP2350-E9 Fix
        --abs-block
            Enforce support for an absolute block
        <abs_block_loc>
            absolute block location (default to 0x10ffff00)

uf2

The uf2 commands allow for creation of UF2s, and cam provide information when if a UF2 download has failed.

convert

This command replaces the elf2uf2 functionality that was previously in the Raspberry Pi Pico SDK. It will attempt to auto-detect the family ID, but if this fails you can specify one manually with the --family argument.

picotool help uf2 convert
UF2 CONVERT:
    Convert ELF/BIN to UF2.

SYNOPSIS:
    picotool uf2 convert [--quiet] [--verbose] <infile> [-t <type>] <outfile> [-t <type>] [-o <offset>] [--family <family_id>]
                [[--abs-block] [<abs_block_loc>]]

OPTIONS:
        --quiet
            Don't print any output
        --verbose
            Print verbose output
    File to load from
        <infile>
            The file name
        -t <type>
            Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
    File to save UF2 to
        <outfile>
            The file name
        -t <type>
            Specify file type (uf2) explicitly, ignoring file extension
    Packaging Options
        -o, --offset
            Specify the load address
        <offset>
            Load offset (memory address; default 0x10000000 for BIN file)
    UF2 Family options
        <family_id>
            family id for UF2
    Errata RP2350-E9 Fix
        --abs-block
            Add an absolute block
        <abs_block_loc>
            absolute block location (default to 0x10ffff00)

info

This command reads the information on a device about why a UF2 download has failed. It will only give information if the most recent download has failed.

$ picotool help uf2 info
UF2 INFO:
    Print info about UF2 download.

SYNOPSIS:
    picotool uf2 info [device-selection]

OPTIONS:
    Target device selection
        --bus <bus>
            Filter devices by USB bus number
        --address <addr>
            Filter devices by USB device address
        --vid <vid>
            Filter by vendor id
        --pid <pid>
            Filter by product id
        --ser <ser>
            Filter by serial number
        -f, --force
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
        -F, --force-no-reboot
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but without the
            RPI-RP2 drive mounted

otp

The otp commands are for interacting with the RP2350 OTP Memory. They are not available on RP2040 devices, as RP2040 has no OTP.

Note that the OTP Memory is One-Time-Programmable, which means that once a bit has been changed from 0 to 1, it cannot be changed back. Therefore, caution should be used when using these commands, as they risk bricking your RP2350 device. For example, if you set SECURE_BOOT_ENABLE but don't set a boot key, and disable the PICOBOOT interface, then your device will be unusable.

For the list, set, get and load commands, you can define your own OTP layout in a JSON file and pass that in with the -i argument. These rows will be added to the default rows when parsing.

$ picotool help otp
OTP:
    Commands related to the RP2350 OTP (One-Time-Programmable) Memory

SYNOPSIS:
    picotool otp list [-p] [-n] [-i <filename>] [<selector>..]
    picotool otp get [-c <copies>] [-r] [-e] [-n] [-i <filename>] [device-selection] [-z] [<selector>..]
    picotool otp set [-c <copies>] [-r] [-e] [-i <filename>] [-z] <selector> <value> [device-selection]
    picotool otp load [-r] [-e] [-s <row>] [-i <filename>] <filename> [-t <type>] [device-selection]
    picotool otp dump [-r] [-e] [device-selection]
    picotool otp permissions <filename> [-t <type>] [--led <pin>] [--hash] [--sign] [<key>] [-t <type>] [device-selection]
    picotool otp white-label -s <row> <filename> [-t <type>] [device-selection]

SUB COMMANDS:
    list          List matching known registers/fields
    get           Get the value of one or more OTP registers/fields (RP2350 only)
    set           Set the value of an OTP row/field (RP2350 only)
    load          Load the row range stored in a file into OTP and verify. Data is 2 bytes/row for ECC, 4 bytes/row for raw. (RP2350 only)
    dump          Dump entire OTP (RP2350 only)
    permissions   Set the OTP access permissions (RP2350 only)
    white-label   Set the white labelling values in OTP (RP2350 only)

set/get

These commands will set/get specific rows of OTP. By default, they will write/read all redundant rows, but this can be overridden with the -c argument

load

This command allows loading of a range of OTP rows onto the device. The source can be a binary file, or a JSON file such as the one output by picotool sign. For example, if you wish to sign a binary and then test secure boot with it, you can run the following set of commands:

$ picotool sign hello_world.elf hello_world.signed.elf private.pem otp.json
$ picotool load hello_world.signed.elf
$ picotool otp load otp.json
$ picotool reboot

white-label

This command allows for OTP white-labelling, which sets the USB configuration used by the device in BOOTSEL mode. This can be configured from a JSON file, an example of which is in sample-wl.json.

$ picotool help otp white-label
OTP WHITE-LABEL:
    Set the white labelling values in OTP

SYNOPSIS:
    picotool otp white-label -s <row> <filename> [-t <type>] [device-selection]

OPTIONS:
    File with white labelling values
        <filename>
            The file name
        -t <type>
            Specify file type (json) explicitly, ignoring file extension
    Target device selection
        --bus <bus>
            Filter devices by USB bus number
        --address <addr>
            Filter devices by USB device address
        --vid <vid>
            Filter by vendor id
        --pid <pid>
            Filter by product id
        --ser <ser>
            Filter by serial number
        -f, --force
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
        -F, --force-no-reboot
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but without the
            RPI-RP2 drive mounted

$ picotool otp white-label -s 0x100 ../sample-wl.json 
Setting attributes 20e0
0x2e8b, 0x000e, 0x0215, 0x0c09, 0x1090, 0x200c, 0x2615, 0x20e0, 0x310b, 0x3706, 0x3a04, 0x3c04, 0x3e21, 0x4f15, 0x5a0a, 0x5f0a, 0x007a, 0x00df, 0x6c34, 0xd83c, 0xdf4c, 0x0020, 0x0054, 0x0065, 0x0073, 0x0074, 0x0027, 0x0073,
0x0020, 0x0050, 0x0069, 0x0073, 0x6554, 0x7473, 0x5220, 0x3250, 0x3533, 0x3f30, 0x6f6e, 0x6e74, 0x6365, 0x7365, 0x6173, 0x6972, 0x796c, 0x6e61, 0x6d75, 0x6562, 0x0072, 0x6554, 0x7473, 0x6950, 0x4220, 0x6f6f, 0x0074, 0x6554,
0x7473, 0x6950, 0x794d, 0x6950, 0x3876, 0x3739, 0x7468, 0x7074, 0x3a73, 0x2f2f, 0x7777, 0x2e77, 0x6172, 0x7073, 0x6562, 0x7272, 0x7079, 0x2e69, 0x6f63, 0x2f6d, 0x656e, 0x7377, 0x002f, 0x6f53, 0x656d, 0x4e20, 0x7765, 0x2073,
0x6241, 0x756f, 0x2074, 0x7453, 0x6675, 0x0066, 0x794d, 0x5420, 0x7365, 0x2074, 0x6950, 0x5054, 0x2d49, 0x5052, 0x3332, 0x3035,
$ picotool reboot -u
$ lsusb -v -s 1:102
Bus 001 Device 102: ID 2e8b:000e zß水🍌 Test's Pis Test RP2350?
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x2e8b 
  idProduct          0x000e 
  bcdDevice            2.15
  iManufacturer           1 zß水🍌 Test's Pis
  iProduct                2 Test RP2350?
  iSerial                 3 notnecessarilyanumber
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0037
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower               64mA
...

permissions

This command will run a binary on your device in order to set the OTP permissions, as these are not directly accessible from picotool on due to the default permissions settings required to fix errata XXX on RP2350. Because it runs a binary, the binary needs to be sign it if secure boot is enabled. The binary will print what it is doing over uart, which can be configured using the UART Configuration arguments. You can define your OTP permissions in a json file, an example of which is in sample-permissions.json.

$ picotool help otp permissions
OTP PERMISSIONS:
    Set the OTP access permissions

SYNOPSIS:
    picotool otp permissions <filename> [-t <type>] [--led <pin>] [--hash] [--sign] [<key>] [-t <type>] [device-selection]

OPTIONS:
    File to load permissions from
        <filename>
            The file name
        -t <type>
            Specify file type (json) explicitly, ignoring file extension
        --led <pin>
            LED Pin to flash; default 25
    Signing Configuration
        --hash
            Hash the executable
        --sign
            Sign the executable
    Key file
        <key>
            The file name
        -t <type>
            Specify file type (pem) explicitly, ignoring file extension
    Target device selection
        --bus <bus>
            Filter devices by USB bus number
        --address <addr>
            Filter devices by USB device address
        --vid <vid>
            Filter by vendor id
        --pid <pid>
            Filter by product id
        --ser <ser>
            Filter by serial number
        -f, --force
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
        -F, --force-no-reboot
            Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing the
            command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but without the
            RPI-RP2 drive mounted
$ picotool otp permissions --sign private.pem --tx 46 ../sample-permissions.json 
Picking file ./xip_ram_perms.elf
page10
page10 = 0
setting page10 -> 4063233
page11
page11 = 0
setting page11 -> 4128781
page12
page12 = 0
setting page12 -> 4128781
tx_pin = 0
setting tx_pin -> 46
Loading into XIP RAM: [==============================]  100%
>>> using flash update boot of 13ffc000

The device was rebooted to start the application.

Binary Information

Binary information is machine locatable and generally machine consumable. I say generally because anyone can include any information, and we can tell it from ours, but it is up to them whether they make their data self describing.

Note that we will certainly add more binary info over time, but I'd like to get a minimum core set included in most binaries from launch!!

Basic Information

This information is really handy when you pick up a Pico and don't know what is on it!

Basic information includes

  • program name
  • program description
  • program version string
  • program build date
  • program url
  • program end address
  • program features - this is a list built from individual strings in the binary, that can be displayed (e.g. we will have one for UART stdio and one for USB stdio) in the SDK
  • build attributes - this is a similar list of strings, for things pertaining to the binary itself (e.g. Debug Build)

The binary information is self-describing/extensible, so programs can include information picotool is not aware of (e.g. MicroPython includes a list of in-built libraries)

Pins

This is certainly handy when you have an executable called 'hello_world.elf' but you forgot what board it is built for...

Static (fixed) pin assignments can be recorded in the binary in very compact form:

$ picotool info --pins sprite_demo.elf
File sprite_demo.elf:

Fixed Pin Information
0-4:    Red 0-4
6-10:   Green 0-4
11-15:  Blue 0-4
16:     HSync
17:     VSync
18:     Display Enable
19:     Pixel Clock
20:     UART1 TX
21:     UART1 RX

Configuration

This is very handy if you want to be able to modify parameters in a binary, without having to recompile it.

$ picotool config -s name Jane
name = "Billy"
setting name -> "Jane"

Including Binary information

Binary information is declared in the program by macros (vile warped macros); for the pins example:

$ picotool info --pins sprite_demo.elf
File sprite_demo.elf:

Fixed Pin Information
0-4:    Red 0-4
6-10:   Green 0-4
11-15:  Blue 0-4
16:     HSync
17:     VSync
18:     Display Enable
19:     Pixel Clock
20:     UART1 TX
21:     UART1 RX

... there is one line in the setup_default_uart function:

bi_decl_if_func_used(bi_2pins_with_func(PICO_DEFAULT_UART_RX_PIN, PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART));

The two pin numbers, and the function UART are stored, then decoded to their actual function names (UART1 TX etc) by picotool. The bi_decl_if_func_used makes sure the binary information is only included if the containing function is called.

Equally, the video code contains a few lines like this:

bi_decl_if_func_used(bi_pin_mask_with_name(0x1f << (PICO_SCANVIDEO_COLOR_PIN_BASE + PICO_SCANVIDEO_DPI_PIXEL_RSHIFT), "Red 0-4"));

For the configuration example, you put the line

bi_decl(bi_ptr_string(0x1111, 0x3333, name, "Billy", 128));

into your code, which will then create the name variable for you to subsequently print. The parameters are the tag, the ID, variable name, default value, and maximum string length.

printf("Name is %s\n", name);

Details

Things are designed to waste as little space as possible, but you can turn everything off with preprocessor variable PICO_NO_BINARY_INFO=1. Additionally, any SDK code that inserts binary info can be separately excluded by its own preprocessor variable.

You need

#include "pico/binary_info.h"

Basically you either use bi_decl(bi_blah(...)) for unconditional inclusion of the binary info blah, or bi_decl_if_func_used(bi_blah(...)) for binary information that may be stripped if the enclosing function is not included in the binary by the linker (think --gc-sections)

There are a bunch of bi_ macros in the headers

#define bi_binary_end(end) ...
#define bi_program_name(name) ...
#define bi_program_description(description) ...
#define bi_program_version_string(version_string) ...
#define bi_program_build_date_string(date_string) ...
#define bi_program_url(url) ...
#define bi_program_feature(feature) ...
#define bi_program_build_attribute(attr) ...
#define bi_1pin_with_func(p0, func) ...
#define bi_2pins_with_func(p0, p1, func) ...
#define bi_3pins_with_func(p0, p1, p2, func) ...
#define bi_4pins_with_func(p0, p1, p2, p3, func) ...
#define bi_5pins_with_func(p0, p1, p2, p3, p4, func) ...
#define bi_pin_range_with_func(plo, phi, func) ...
#define bi_pin_mask_with_name(pmask, label) ...
#define bi_pin_mask_with_names(pmask, label) ...
#define bi_1pin_with_name(p0, name) ...
#define bi_2pins_with_names(p0, name0, p1, name1) ...
#define bi_3pins_with_names(p0, name0, p1, name1, p2, name2) ...
#define bi_4pins_with_names(p0, name0, p1, name1, p2, name2, p3, name3) ... 

which make use of underlying macros, e.g.

#define bi_program_url(url) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_URL, url)

NOTE: It is easy to forget to enclose these in bi_decl etc., so an effort has been made (at the expense of a lot of kittens) to make the build fail with a somewhat helpful error message if you do so.

For example, trying to compile

bi_1pin_with_name(0, "Toaster activator");

gives

/home/graham/dev/mu/pico_sdk/src/common/pico_binary_info/include/pico/binary_info/code.h:17:55: error: '_error_bi_is_missing_enclosing_decl_261' undeclared here (not in a function)
17 | #define __bi_enclosure_check_lineno_var_name __CONCAT(_error_bi_is_missing_enclosing_decl_,__LINE__)
|                                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... more macro call stack of doom

Setting common fields from CMake

You can use

pico_set_program_name(foo "not foo") # as "foo" would be the default
pico_set_program_description(foo "this is a foo")
pico_set_program_version(foo "0.00001a")
pico_set_program_url(foo "www.plinth.com/foo")

Note all of these are passed as command line arguments to the compilation, so if you plan to use quotes, newlines etc you may have better luck defining via bi_decl in the code.

Additional binary information/picotool features

Block devices

MicroPython and CircuitPython, eventually the SDK and others may support one or more storage devices in flash. We already have macros to define these although picotool doesn't do anything with them yet... but backup/restore/file copy and even fuse mount in the future might be interesting.

I suggest we tag these now...

This is what I have right now off the top of my head (at the time)

#define bi_block_device(_tag, _name, _offset, _size, _extra, _flags)

with the data going into

typedef struct __packed _binary_info_block_device {
        struct _binary_info_core core;
        bi_ptr_of(const char) name; // optional static name (independent of what is formatted)
        uint32_t offset;
        uint32_t size;
        bi_ptr_of(binary_info_t) extra; // additional info
        uint16_t flags;
} binary_info_block_device_t;

and

enum {
    BINARY_INFO_BLOCK_DEV_FLAG_READ = 1 << 0, // if not readable, then it is basically hidden, but tools may choose to avoid overwriting it
    BINARY_INFO_BLOCK_DEV_FLAG_WRITE = 1 << 1,
    BINARY_INFO_BLOCK_DEV_FLAG_REFORMAT = 1 << 2, // may be reformatted..

    BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN = 0 << 4, // unknown free to look
    BINARY_INFO_BLOCK_DEV_FLAG_PT_MBR = 1 << 4, // expect MBR
    BINARY_INFO_BLOCK_DEV_FLAG_PT_GPT = 2 << 4, // expect GPT
    BINARY_INFO_BLOCK_DEV_FLAG_PT_NONE = 3 << 4, // no partition table
};

Forced Reboots

Running commands with -f/F requires compatible code to be running on the device. The definition of compatible code for the purposes of binaries compiled using the pico-sdk is code that

  • Is still running - If your code has returned then rebooting with -f/F will not work - instead you can set the compile definition PICO_ENTER_USB_BOOT_ON_EXIT to reboot and be accessible to picotool once your code has finished execution, for example with target_compile_definitions(<yourTargetName> PRIVATE PICO_ENTER_USB_BOOT_ON_EXIT=1)
  • Uses stdio_usb - If your binary calls stdio_init_all() and you have pico_enable_stdio_usb(<yourTargetName> 1) in your CMakeLists.txt file then you meet this requirement (see the hello_usb example)

Issues

If you ctrl+c out of the middle of a long operation, then libusb seems to get a bit confused, which means we aren't able to unlock our lockout of USB MSD writes (we have turned them off so the user doesn't step on their own toes). Simply running picotool info again will unlock it properly the next time (or you can reboot the device).

picotool's People

Contributors

akhilharihar avatar armandomontanez avatar birdybro avatar davidegrayson avatar dp111 avatar earlephilhower avatar georgerennie avatar jeffmhastings avatar kilograham avatar kripton avatar lurch avatar mbrunnen avatar rlane avatar thatoddmailbox avatar tjvr avatar xdeschuyteneer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

picotool's Issues

Please tag a release

Most Linux distributions won't package software that exists only as a git repository since no "version number" is known. It would help if you could tag an official release so there is a common, official version number. Thanks :)

elf2uf2 on s390x: ERROR: Not an ELF file

Hi,

I have this CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
project(hello_world)
pico_sdk_init()

add_executable(hello_world hello.c)
target_link_libraries(hello_world pico_stdlib)
pico_add_extra_outputs(hello_world)

and this hello-world program (yes this program is not even making use of the pico sdk but the problem is also there if we add that):

#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}

On s390x the build will fail like this:

$ make VERBOSE=1
[...]
/usr/bin/arm-none-eabi-objcopy -Oihex /home/josch/hello_world.elf hello_world.hex
/usr/bin/arm-none-eabi-objcopy -Obinary /home/josch/hello_world.elf hello_world.bin
/usr/bin/arm-none-eabi-objdump -h /home/josch/hello_world.elf > hello_world.dis
/usr/bin/arm-none-eabi-objdump -d /home/josch/hello_world.elf >> hello_world.dis
elf2uf2/elf2uf2 /home/josch/hello_world.elf hello_world.uf2
ERROR: Not an ELF file
make[2]: *** [CMakeFiles/hello_world.dir/build.make:812: hello_world.elf] Error 254
make[2]: *** Deleting file 'hello_world.elf'
make[2]: Leaving directory '/home/josch'
make[1]: *** [CMakeFiles/Makefile2:1491: CMakeFiles/hello_world.dir/all] Error 2
make[1]: Leaving directory '/home/josch'
make: *** [Makefile:91: all] Error 2

I added some printfs into tools/elf2uf2/main.cpp to investigate the values of ELF_MAGIC and eh_out.common.magic in read_and_check_elf32_header and got this:

ELF_MAGIC = 464c457f
eh_out.common.magic = 7f454c46

There seems to be an endian problem somewhere? The file utility seems to think that my hello_world.elf has the correct magic:

$ file hello_world.elf
hello_world.elf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped

Any ideas?

Picotool coprodis unusably slow with large program (W11)

MMBasic creates an image which is just under a Megabyte (rp2040). elf2uf2 used to create the uf2 in a couple of seconds. picotool takes several minutes and a processor is running a maximum during this period (W11 PC with I7-12700). It does eventually complete and appears to create a valid uf2.
I believe the problem is in the creation of the dis file which is 11.4Mbytes. If I kill picotool using the task manager the UF2 is created but the dis creation fails

picotool save: 2M range produces a 4M .uf2

I'm using the following command to dump the contents of an RP2 based board to a .uf2:

picotool save --range 0x10000000 0x10200000 filename.uf2

I expect this to produce a 2M binary, but the result is 4M in size:

4.0M Apr 23 14:23 filename.uf2

Attempting to load this file results in an error at various degrees of progress:

picotool load filename.uf2
Loading into Flash: [==========                    ]  35%
ERROR: Communication with RP2040 device failed
picotool load filename.uf2
Loading into Flash: [============================= ]  97%
ERROR: Communication with RP2040 device failed

For context we're trying to snapshot a configured CircuitPython installation so that a board can be shipped with a ready-to-go example. Here's the board info:

Program Information
 name:            CircuitPython
 version:         6.2.0
 web site:        https://circuitpython.org
 features:        double reset -> BOOTSEL
 binary start:    0x10000000
 embedded drive:  0x00100000-0x00200000 (1024K): CircuitPython

Fixed Pin Information
 none

Build Information
 build date:        2021-04-05
 build attributes:  BOARD=pimoroni_keybow2040

Device Information
 flash size:   2048K
 ROM version:  2

I'm working upon the assumption that the "embedded drive" is an offset to the binary start, but this board only has a 2M flash part anyway so a full flash dump is feasible. My "failed" flashes seem to verify okay with picotool verify.

Flashing the 4M binary using the drag-and-drop seems to give mixed results. Some boards work, some don't. Perhaps writing a larger-than-the-flash-size file over USB causes it to loop from the start of the flash and corrupt the binary if the board doesn't catch it and reset quickly enough?

No license defined

There is no license defined for the project.
Could you add one, please?

It looks like it should be BSD-3-Clause

picotool load works, then does not

My development system Linux Mint 21.1, running on a fast PC (12th Gen Intel Core i9-12900K).
The target board is a Pico W

The following command with the -f flag successfully uploads on the first try.
$ picotool load -f filename
However, subsequent upload attempts fail with this error message.
No accessible RP2040 devices in BOOTSEL mode were found.
Unplugging the pico, pressing BOOTSEL button and replugging the board allows picotool to upload again ... but only once.

The following workaround using the -F flag seems to be robust
$ picotool load -F filename
$ picotool reboot

Seems like there may be a timing issue when using the -f flag

load command fails when specifying bus and address

I'm unable to flash a device using picotool with a specified bus and address even though the same device can be seen using the info command. This is on Windows 11 with the libusb driver installed via zadig. The device is in BOOTSEL mode.

When I run .\picotool.exe info -a --bus 2 --address 12 I get back a response showing the flash size and rom version.

When I run .\picotool.exe load firmware.uf2 the firmware loads successfully.

When I run .\picotool.exe load firmware.uf2 --bus 2 --address 12 I get back "No accessible RP2040 device in BOOTSEL mode was found at bus 2, address 12."

Why doesn't the load command work with the bus and address specified?

add a udev rule for linux systems to access the pico without sudo

I created a udev rules file so I can use picotool without sudo

# make raspberry pi pico accessible without sudo.

SUBSYSTEM!="usb_device", ACTION!="add", GOTO="rpi2_end"
# Raspberry Pi Pico
ATTR{idVendor}=="2e8a", ATTRS{idProduct}=="0003", MODE="660", GROUP="plugdev"

LABEL="rpi2_end"

"LibUSB is not found" error when PkgConfig is missing

I just installed LibUSB, then ran PICO_SDK_PATH=[path_to_sdk] cmake .. just like the README says. I then received the following error:

Using PICO_SDK_PATH from environment ('/home/reinier/code/badgeteam/rpi-pico-sdk')
-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
-- Could NOT find LIBUSB (missing: LIBUSB_INCLUDE_DIR)
CMake Error at CMakeLists.txt:34 (message):
  picotool cannot be built because libUSB is not found

I then ran sudo apt install pkg-config after which the build succeeded. This makes me think the error I originally received is erroneous. :)

pico-examples inline download and build of picotool does not accurately detect libusb

When I update a project in pico-examples with usb support the build process is smart enough to download and build picotool as a part of the overall build.

However, the build reports: "libUSB is not found - no USB support will be built"

On the exact same dev machine, if I download this repository directly and build it - it builds fine with usb support (all dependencies are present).

It would be extremely handy if that integrated build accurately built with USB support because it would eliminate many tutorial steps to build picotool again separately.

I did try logging out and in again in case there was some type of path update issue after installing the OS dependencies (even though the full build directly from this project did not require that to work).

Is there a configuration change I would need to make when building pico-examples to get this working?

[BUG] FindLIBUSB.cmake points to an old include and library paths

The findLIBUSB.cmake file points to folders that existed in "libusb-1.0.24"

FIND_PATH(LIBUSB_INCLUDE_DIR libusb.h
       ***HINTS $ENV{LIBUSB_ROOT}/include/libusb-1.0***
       PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS})
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb-1.0 usb-1.0 usb
       ***HINTS $ENV{LIBUSB_ROOT}/VS2019/MS32/static***

libusb1.0.24 path to "libusb-1.0.lib" ( $ENV{LIBUSB_ROOT}/VS2019/MS32/static)
image

libusb1.0.24 path to "libusb.h" ($ENV{LIBUSB_ROOT}/include/libusb-1.0)
image

In the version 1.0.26 (as of June 6, 2022)

  • folder structure has changed
    version libusb1.0.24
    image
    current version (libusb1.0.26)
    image

  • libusb.h file is now in each sub directory
    image

  • VS2019 removed and libusb-1.0.lib under VS2015-win32
    image

Make picotool build on FreeBSD

Picotool currently doesn't quite build on FreeBSD because libusb (which is part of the base system rather than an add-on package) is just 'libusb' rather than 'libusb-1.0' even though it's compatible with the Linux -1.0 version.

So very simple patch makes it all work:

diff --git a/cmake/FindLIBUSB.cmake b/cmake/FindLIBUSB.cmake
index c8cc62c..560e023 100644
--- a/cmake/FindLIBUSB.cmake
+++ b/cmake/FindLIBUSB.cmake
@@ -20,7 +20,7 @@ else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
ENDIF(NOT WIN32)
FIND_PATH(LIBUSB_INCLUDE_DIR libusb.h
PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS})

  • FIND_LIBRARY(LIBUSB_LIBRARIES NAMES usb-1.0
  • FIND_LIBRARY(LIBUSB_LIBRARIES NAMES usb-1.0 usb
    PATHS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS})
    include(FindPackageHandleStandardArgs)
    FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR)

ie. just add "usb" after "usb-1.0" on the FIND_LIBRARY line.

Support "list" command

I wonder if a picotool list command might be useful? Consider the following scenario:

% lsusb | grep 2e8a                                       
Bus 020 Device 012: ID 2e8a:000a 2e8a Pico  Serial: 000000000000
Bus 020 Device 009: ID 2e8a:0005 2e8a Board in FS mode  Serial: 000000000000
% ./picotool info
No accessible RP2040 devices in BOOTSEL mode were found.

but:

Device at bus 20, address 9 appears to be a RP2040 MicroPython device not in BOOTSEL mode.
Device at bus 20, address 12 appears to be a RP2040 device with a USB serial connection, so consider -f or -F.

if I then plug in a Pico with a blank Flash chip (wiped using flash_nuke.uf2) I get:

% lsusb | grep 2e8a
Bus 020 Device 012: ID 2e8a:000a 2e8a Pico  Serial: 000000000000
Bus 020 Device 009: ID 2e8a:0005 2e8a Board in FS mode  Serial: 000000000000
Bus 020 Device 013: ID 2e8a:0003 2e8a RP2 Boot  Serial: E0C912D24340
% ./picotool info
Program Information
 none

In this latter case it would be nice if e.g. a ./picotool list could tell me:

Device at bus 20, address 9 appears to be a RP2040 MicroPython device not in BOOTSEL mode.
Device at bus 20, address 12 appears to be a RP2040 device with a USB serial connection, so consider -f or -F.
Device at bus 20, address 13 appears to be a RP2040 device in BOOTSEL mode.

For bonus points, it could even include the other VID/PID combos from https://github.com/raspberrypi/usb-pid ? πŸ˜‰

Release pre-build binaries

Would be great if picotool releases pre-build binaries. That would make the tool a lot more accessible.

Build errors with GCC11

I have the following build errors with GCC11:

[   19s] [ 50%] Building CXX object CMakeFiles/picotool.dir/main.cpp.o
[   19s] /usr/bin/c++ -DPICO_BUILD=1 -DPICO_NO_HARDWARE=1 -DPICO_ON_DEVICE=0 -I/usr/include/libusb-1.0 -I/home/abuild/rpmbuild/BUILD/picotool-1.0.1/pico-sdk-1.1.2/src/common/pico_binary_info/include -I/home/abuild/rpmbuild/BUILD/picotool-1.0.1/pico-sdk-1.1.2/src/common/boot_uf2/include -I/home/abuild/rpmbuild/BUILD/picotool-1.0.1/pico-sdk-1.1.2/src/common/boot_picoboot/include -I/home/abuild/rpmbuild/BUILD/picotool-1.0.1/pico-sdk-1.1.2/src/host/pico_platform/include -I/home/abuild/rpmbuild/BUILD/picotool-1.0.1/picoboot_connection -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type -flto=auto -g -DNDEBUG -O2 -g -DNDEBUG -std=gnu++14 -MD -MT CMakeFiles/picotool.dir/main.cpp.o -MF CMakeFiles/picotool.dir/main.cpp.o.d -o CMakeFiles/picotool.dir/main.cpp.o -c /home/abuild/rpmbuild/BUILD/picotool-1.0.1/main.cpp
[   19s] In file included from /home/abuild/rpmbuild/BUILD/picotool-1.0.1/main.cpp:11:
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h: In member function 'D& cli::matchable_derived<T>::repeatable()':
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:257:25: error: 'numeric_limits' is not a member of 'std'
[   19s]   257 |             _max = std::numeric_limits<int>::max();
[   19s]       |                         ^~~~~~~~~~~~~~
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:257:40: error: expected primary-expression before 'int'
[   19s]   257 |             _max = std::numeric_limits<int>::max();
[   19s]       |                                        ^~~
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h: At global scope:
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:444:31: error: 'numeric_limits' is not a member of 'std'
[   19s]   444 |         int _max_value = std::numeric_limits<int>::max();
[   19s]       |                               ^~~~~~~~~~~~~~
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:444:46: error: expected primary-expression before 'int'
[   19s]   444 |         int _max_value = std::numeric_limits<int>::max();
[   19s]       |                                              ^~~
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h: In lambda function:
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:408:36: error: 'numeric_limits' is not a member of 'std'
[   19s]   408 |                 long lvalue = std::numeric_limits<long>::max();
[   19s]       |                                    ^~~~~~~~~~~~~~
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:408:51: error: expected primary-expression before 'long'
[   19s]   408 |                 long lvalue = std::numeric_limits<long>::max();
[   19s]       |                                                   ^~~~
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h: At global scope:
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:500:40: error: 'numeric_limits' is not a member of 'std'
[   19s]   500 |         unsigned int _max_value = std::numeric_limits<unsigned int>::max();
[   19s]       |                                        ^~~~~~~~~~~~~~
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:500:55: error: expected primary-expression before 'unsigned'
[   19s]   500 |         unsigned int _max_value = std::numeric_limits<unsigned int>::max();
[   19s]       |                                                       ^~~~~~~~
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h: In lambda function:
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:460:36: error: 'numeric_limits' is not a member of 'std'
[   19s]   460 |                 long lvalue = std::numeric_limits<long>::max();
[   19s]       |                                    ^~~~~~~~~~~~~~
[   19s] /home/abuild/rpmbuild/BUILD/picotool-1.0.1/cli.h:460:51: error: expected primary-expression before 'long'
[   19s]   460 |                 long lvalue = std::numeric_limits<long>::max();
[   19s]       |                                                   ^~~~

Picotool unusably slow with large program (W11)

MMBasic creates an image which is just under a Megabyte (rp2040). elf2uf2 used to create the uf2 in a couple of seconds. picotool takes several minutes and a processor is running a maximum during this period (W11 PC with I7-12700). It does eventually complete and appears to create a valid uf2.
I believe the problem is in the creation of the dis file which is 11.4Mbytes. If I kill picotools using the task manager the UF2 is created but the dis creation fails

Getting picotool on Linux?

I've located my Pico C SDK development platform on my Ubuntu 22.04. I'm worried that I'll wear out my USB port with all of the plugging and unplugging. I understand that picotool offers a solution for this - allowing one to build & upload without the plugging, un-plugging & button-pushing (a la arduino-pico & Arduino's IDE). I've looked in at the README here & Appendix B in the Getting Started Guide, but I am still unclear on how to get picotool installed. Have I missed that??

Here's my directory setup... if someone could tell me where I need to insert the required directory, I think I can go from there.

~/pico$ tree -L 1
.
β”œβ”€β”€ ina260_i2c
β”œβ”€β”€ MyProjects
β”œβ”€β”€ pico-examples
β”œβ”€β”€ pico-extras
β”œβ”€β”€ pico-playground
β”œβ”€β”€ pico-sdk

--force doesn't work on MacOS

Executing any command with -f or -F has no effect.

picotool either responds with "No accessible RP2040 devices in BOOTSEL mode were found." or, if the device is manually put into BOOTSEL mode, it flashes the device.
Using -f, I'd expect the device to be rebooted. This is not the case.
Everything else regarding picotool seems to work as expected.

I'm using running on an M1 using:

  • cmake version 3.24.1
  • Apple clang version 13.1.6 (clang-1316.0.21.2.5) Target: arm64-apple-darwin21.6.0
  • libusb-1.0, version 1.0.26
  • picotool v1.1.0 (Darwin 21.6.0, AppleClang-13.1.6.13160021, Release)
  • picotool pulled at 03f28122cc170535f35e5bf8fa37be024489f5eb
  • pico-sdk pulled at 2e6142b15b8a75c1227dd3edbe839193b2bf9041

The pico is connected via a USB A to C adapter (also tested with a USB hub yielding no difference).

The cmake and make output is listed here:

➜  build git:(master) cmake ..
-- The C compiler identification is AppleClang 13.1.6.13160021
-- The CXX compiler identification is AppleClang 13.1.6.13160021
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - 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: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
Using PICO_SDK_PATH from environment ('/Users/robin/Documents/code/pico/pico-sdk')
-- Found PkgConfig: /opt/homebrew/bin/pkg-config (found version "0.29.2")
-- Checking for module 'libusb-1.0'
--   Found libusb-1.0, version 1.0.26
-- Found LIBUSB: /opt/homebrew/lib/libusb-1.0.dylib
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/robin/Documents/code/pico/picotool/build
➜  build git:(master) βœ— make
[ 25%] Building CXX object CMakeFiles/picotool.dir/main.cpp.o
[ 50%] Building CXX object CMakeFiles/picotool.dir/picoboot_connection/picoboot_connection_cxx.cpp.o
[ 75%] Building C object CMakeFiles/picotool.dir/picoboot_connection/picoboot_connection.c.o
[100%] Linking CXX executable picotool
[100%] Built target picotool

I'm not sure wether this is a bug in picotool or a problem on my setup.

The compiler or linker does not enter the information in the binary file.

I use the core: "https://github.com/earlephilhower/arduino-pico"
I followed the guide contained in the file: "getting-started-with-pico.pdf"
And the compilation takes place without errors.
Using picotool the information I entered is not visible, however.
I believe the compiler eliminates the two functions.
I looked at the file: "ctags_target_for_gcc_minus_e.cpp" which is generated at the end of the compilation and the two functions are not there.

This is the file :

/*
  Fade

  This example shows how to fade an LED on pin 9 using the analogWrite()
  function.

  The analogWrite() function uses PWM, so if you want to change the pin you're
  using, be sure to use another PWM capable pin. On most Arduino, the PWM pins
  are identified with a "~" sign, like ~3, ~5, ~6, ~9, ~10 and ~11.

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Fade
*/
#include "pico/binary_info.h"



int led = 25;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
  
}

// the loop routine runs over and over again forever:
void loop() {
  bi_decl(bi_program_description("This is a test binary."));
  bi_decl(bi_1pin_with_name(LED_PIN, "On-board LED"));
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);

I also put the functions in setup () but the functions are eliminated.

I have not understood what needs to be done to set up the compiler or linker to prevent functions from being eliminated.

I tried to remove from "platform.txt" --gc-sections from the parameters passed to the linker

compiler.ldflags={compiler.wrap} -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common

but in this way the compilation ends with errors.

tistructor@Lenovo-Y520:~/.arduino15/packages/rp2040/tools/pqt-picotool/1.5.0-b-03f2812$ ./picotool info -a /tmp/arduino_build_852227/Fade.ino.uf2
File /tmp/arduino_build_852227/Fade.ino.uf2:

Program Information
 none

Fixed Pin Information
 none

Build Information
 none
./picotool info -a 
Program Information
 none

Fixed Pin Information
 none

Build Information
 none

Device Information
 flash size:   4096K
 ROM version:  3

Unable to see device via --address flag on Windows

Steps to reproduce:

  1. Plug in a RP2040 Pico to Windows 11 while holding down the BOOTSEL button
  2. Run picotool info

Result: device is found, reports no program information (correct)

  1. Run picotool info --address 5

Result: "No accessible RP2040 devices in BOOTSEL mode were found with address 5."
Expected result: device is found and reports no program information

I'm using WinUSB v6.1.760.16385 for the driver, installed via zadig. The device address comes from the device properties in Device Manager.

Error building in Windows

After trying to build using ninja, I get the following error.

[4/4] Linking CXX executable picotool.exe
FAILED: picotool.exe
cmd.exe /C "cd . && C:\MinGW\bin\c++.exe -O3 -DNDEBUG CMakeFiles/picotool.dir/main.cpp.obj CMakeFiles/picotool.dir/picoboot_connection/picoboot_connection_cxx.cpp.obj CMakeFiles/picotool.dir/picoboot_connection/picoboot_connection.c.obj -o picotool.exe -Wl,--out-implib,libpicotool.dll.a -Wl,--major-image-version,0,--minor-image-version,0 C:/Users/blam/Desktop/LIBUSB/VS2019/MS32/static/libusb-1.0.lib -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."

C:/Users/blam/Desktop/LIBUSB/VS2019/MS32/static/libusb-1.0.lib: error adding symbols: File format not recognized
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Thanks

Error saving all flash rom

Hello, When I try to save all flash from the pico, it disconnects from BOOTSEL mode and I get an error.

image

I have to disconnect the pico and set it back to BOOTSEL mode, while I can save a program (-p) without any problem.
i'm working in Windows WSL2 ubuntu, using usbipd to connect USB device to ubuntu

Device in BOOTSEL cant be seen

My device mounts in BOOTSEL and shows the file system but pico tool reports
`pi@raspberrypi:~/pico/picotool $ picotool info --bus 1 --address 21
No accessible RP2040 device in BOOTSEL mode was found at bus 1, address 21.

but:

Device at bus 1, address 21 appears to be a RP2040 device in BOOTSEL mode, but picotool was unable to connect`

environment:
Built following getting started guide
Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux
pico connected via USB

Typo in pin list.

Pin 15 when configured as SPI comes out as "PI1 TX" instead of "SPI1 TX".

The fault is in main.cpp, line 83. column 180.

Build on Windows with MinGW without WSL

I tired to build the tool on Windows but the options documented in README.md did not work for me.

I do not have a Visual Studio installation, so I wanted to use MinGW. After some time tinkering around I found that modifying the FindLIBUSB.cmake file and replacing the HINTS $ENV{LIBUSB_ROOT}/VS2019/MS32/static line with HINTS $ENV{LIBUSB_ROOT}/MinGW64/static and running cmake -G "MinGW Makefiles" .. followed by mingw-make forked like a charm, I got my exe.

Now to the question or idea - could we update the FindLIBUSB.cmake to consider 32bit and 64bit machines, Windows MSVC and MinGW lib inclusion based on generator input?

For example something like this ?

if(CMAKE_GENERATOR MATCHES "MinGW")
    HINTS $ENV{LIBUSB_ROOT}/MinGW64/static
else
    HINTS $ENV{LIBUSB_ROOT}/VS2019/MS64/static
endif()

"Unable to connect" in Windows (building with Git for Windows SDK)

I'm running into the following error after building picotool on Windows 10:

No accessible RP2040 devices in BOOTSEL mode were found.

but:

Device at bus 1, address 20 appears to be a RP2040 device in BOOTSEL mode, but picotool was unable to connect

The Getting Started guide says to use sudo to fix this, but that's for Linux. How do you fix this issue on Windows? I have the Raspberry Pi Pico in BOOTSEL mode as required.


Please note that I did not build picotool with Build Tools for Visual Studio. Instead, I did the following:

Set up Pico C/C++ toolchain using Git Bash and MinGW instead of Build Tools for Visual Studio following the instructions here: https://shawnhymel.com/2096/how-to-set-up-raspberry-pi-pico-c-c-toolchain-on-windows-with-vs-code/

In order to get the pacman package manager, I installed Git for Windows SDK from this site: https://gitforwindows.org/.

From there, I opened the git-bash.exe from C:\git-sdk-64 (Git for Windows SDK installation directory) to build OpenOCD:

pacman -Syu 
pacman -Su
pacman -S mingw-w64-x86_64-toolchain git make libtool pkg-config autoconf automake texinfo mingw-w64-x86_64-libusb 
cd /c/VSARM/sdk/pico
git clone https://github.com/raspberrypi/openocd.git --branch picoprobe --depth=1 
cd openocd
./bootstrap
./configure --enable-picoprobe --disable-werror
make -j4

I was also able to use those packages to build picotool:

cd /c/VSARM/sdk/pico
git clone -b master https://github.com/raspberrypi/picotool.git 
cd picotool
mkdir build
cd build
cmake -G "MinGW Makefiles" -DPC_LIBUSB_INCLUDEDIR="/c/git-sdk-64/mingw64/include/libusb-1.0" ..
make
cp /c/git-sdk-64/mingw64/bin/libusb-1.0.dll .

I can run picotool successfully (Pico is connected and in BOOTSEL mode):

./picotool.exe info

However, that results in the error above, and I'm afraid I'm stuck.

I realize that this is not the method outlined in the Getting Started guide, but I would appreciate any help trying to figure out why picotool cannot connect.

No rule to install `picotool` binary

All the cmake system is in place except for the installation of picotool to /usr/bin target.
When make install is run, we get:

make: *** No rule to make target 'install'.  Stop.

Is picotool on brew?

Hey everyone πŸ‘‹

I'm wondering if / where I can find and install picotool using homebrew?

I tried just brew install picotool but it could not find any casks or formulae.

Cheers!

How to convert a modified elf to uf2.

I wanted to understand how to use the picotool to take a modified elf file and convert it to a uf2 that can be dropped into the flash like a normal uf2?

Warning on 'sprintf' while compiling.

While compiling picotool with macOS I get the following warning:
warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]

Is this kept for compatibility reasons or would it be ok to submit a pullrequest with the snprintf variant?

Unable to reset pico

When I run picotool.exe reboot -f -u, I get the following error: ERROR: Unable to locate reset interface on the device, despite the fact that running the info command indicates Device at bus 1, address 30 appears to be a RP2040 device with a USB serial connection, not in BOOTSEL mode. You can force reboot into BOOTSEL mode via 'picotool reboot -f -u' first.. Running a load command does work, however, if I manually enter BOOTSEL via the button.

I am using picotool 1.1.2 and libusb 1.0.26 on Windows 11.

I have tried using both the Win32 driver and the libusb-win32 driver from Zadig.

Support commands other than "reset" for non BOOTSEL device with STDIO USB reset interface

If a device is not in BOOTSEL mode but is exposing a reset interface along with STDIO USB, then we can potentially run any command by first resetting the device to BOOTSEL mode, and then performing the original intended command.

  • We should use the same -f, --force or whatever from #13
  • We can reset the device into PICOBOOT only mode when doing this to avoid the device ever showing up as a drive

Open question; if we are performing an operation other than "load -x", what should we do after - the device will be left not running. We can either reset it or expose the USB interface at that point (in which case we may as well expose it as soon as reset if we won't be resetting again after the command)

picotool crashes when given an ELF built with embedded rust

$ cargo build --example pico_blinky
   Compiling pico v0.1.0 (/home/jonathan/rp-hal/boards/pico)
    Finished dev [unoptimized + debuginfo] target(s) in 0.91s
$ ../picotool/build/picotool info ./target/thumbv6m-none-eabi/debug/examples/pico_blinky
ERROR: filename './target/thumbv6m-none-eabi/debug/examples/pico_blinky' does not have a recognized file type (extension)
$ cp ./target/thumbv6m-none-eabi/debug/examples/pico_blinky ./pico_blinky.elf
$ ../picotool/build/picotool info ./pico_blinky.elf
picotool: /home/jonathan/picotool/main.cpp:156: void range_map<T>::check_overlap(uint32_t) [with T = long unsigned int; uint32_t = unsigned int]: Assertion `p >= f->first' failed.
[1]    3871 abort      ../picotool/build/picotool info ./pico_blinky.elf

Minor compiler warning on build, fread return value unused

Compiling picotool under Ubuntu 20.04 and GCC 9.4 results in the following warning about not checking the the source file read completed properly:

Scanning dependencies of target picotool
[ 25%] Building CXX object CMakeFiles/picotool.dir/main.cpp.o
/home/earle/src/picotool/main.cpp: In member function β€˜virtual void file_memory_access::read(uint32_t, uint8_t*, uint32_t, bool)’:
/home/earle/src/picotool/main.cpp:869:22: warning: ignoring return value of β€˜size_t fread(void*, size_t, size_t, FILE*)’, declared with attribute warn_unused_result [-Wunused-result]
  869 |                 fread(buffer, this_size, 1, file);
      |                 ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ 50%] Building CXX object CMakeFiles/picotool.dir/picoboot_connection/picoboot_connection_cxx.cpp.o
[ 75%] Building C object CMakeFiles/picotool.dir/picoboot_connection/picoboot_connection.c.o
[100%] Linking CXX executable picotool
[100%] Built target picotool

Build error "β€˜numeric_limits’ is not a member of β€˜std’"

I ran into the following error when trying to build picotool on Linux:

.../picotool/cli.h: In member function β€˜D& cli::matchable_derived<T>::repeatable()’:
.../picotool/cli.h:257:25: error: β€˜numeric_limits’ is not a member of β€˜std’
  257 |             _max = std::numeric_limits<int>::max();

(And a few follow-up errors).

Google lead me to the solution of adding #include <limits>to cli.h.

This is on Arch Linux using gcc 11.1.0, libstdc++ 3.3.6 and cmake 3.20.2 (I don't know enough about C++ to make a qualified guess what the root issue is, but I'm surprised nobody seems to have reported this yet, so it might well depend on the build environment).

-f option missing for load command on Windows

As per README it is stated that the load command supports the "-f" option as of version 1.1.

When using the picotool version 1.1.1 on Windows this option still is absent. Also help does not show it and trying to use it results in error.
This is the help excerpt I get:
picotool load [-n] [-N] [-u] [-v] [-x] [-t ] [-o ] [--bus ] [--address ]

embedding ${CMAKE_SYSTEM_VERSION} makes picotool unreproducible

Hi,

maybe you have heard about the reproducible builds effort which a number of big organizations like Debian, Fedora, NixOS, Guix or Arch Linux are implementing. You can find more information here: https://reproducible-builds.org/#why-does-it-matter

In Debian, i'm using this patch to make picotool reproducible and allow independent verification that the provided source code results in the same application binary irrespective of who compiles it:

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,7 +41,7 @@ else()
 
     add_executable(picotool main.cpp)
     set(PICOTOOL_VERSION 1.1.2)
-    set(SYSTEM_VERSION "${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}")
+    set(SYSTEM_VERSION "${CMAKE_SYSTEM_NAME}")
     set(COMPILER_INFO "${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}, ${CMAKE_BUILD_TYPE}")
     target_compile_definitions(picotool PRIVATE
             PICOTOOL_VERSION="${PICOTOOL_VERSION}"

I'm wondering if you would consider adding this kind of change to picotool or whether I will continue applying this patch in Debian.

Thanks!

Feature: Target devices by it's unique ID

Feature request: Target devices by their unique ID, so that I can work with multiple devices connected at the same time, while allowing the USB port connections to change.

The unique id is available on the SDK (pico_get_unique_board_id), the same string is exposed on the device descriptor.

"Unable to Connect" Windows built with mingw

Hi,
I am having this same issue even after installing the libusb-win32 driver to RP2 Boot (Interface 1) using Zadig. Any ideas on whats the issue here?
I used mingw32-make to build the executable and it seems to work just fine, but just cannot connect to the pico board.

Originally posted by @JeffersonDing in #20 (comment)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.