| ## 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 | |
| ```text | |
| $ picotool help | |
| PICOTOOL: | |
| Tool for interacting with RP-series device(s) in BOOTSEL mode, or with an RP-series binary | |
| SYNOPSIS: | |
| picotool help [<cmd>] | |
| picotool version [-s] [<version>] | |
| picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [device-selection] | |
| picotool info [-b] [-m] [-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 [--ignore-partitions] [--family <family_id>] [-p <partition>] [-n] [-N] [-u] | |
| [-v] [-x] <filename> [-t <type>] [-o <offset>] [device-selection] | |
| picotool save [-p] [-v] [--family <family_id>] <filename> [-t <type>] [device-selection] | |
| picotool save -a [-v] [--family <family_id>] <filename> [-t <type>] [device-selection] | |
| picotool save -r <from> <to> [-v] [--family <family_id>] <filename> [-t <type>] | |
| [device-selection] | |
| picotool verify <filename> [-t <type>] [device-selection] [-r <from> <to>] [-o <offset>] | |
| [device-selection] | |
| picotool erase [-a] [device-selection] | |
| picotool erase -p <partition> [device-selection] | |
| picotool erase -r <from> <to> [device-selection] | |
| picotool reboot [-a] [-u] [-g <partition>] [-c <cpu>] [device-selection] | |
| picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] [--pin-xip-sram] | |
| [--no-squash] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] [<key>] | |
| [<otp>] [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]] | |
| picotool encrypt [--quiet] [--verbose] [--embed] [--fast-rosc] [--use-mbedtls] | |
| [--otp-key-page <page>] [--hash] [--sign] [--no-clear] [--pin-xip-sram] | |
| <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> <iv_salt> | |
| [<signing_key>] [<otp>] | |
| picotool partition info|create | |
| picotool uf2 convert|combine|info | |
| picotool otp get|set|load|white-label|permissions|dump|list | |
| picotool coprodis [--quiet] [--verbose] <infile> <outfile> | |
| picotool link [--quiet] [--verbose] <outfile> [-t <type>] <infile1> [-t <type>] <infile2> | |
| [-t <type>] [<infile3>] [-t <type>] [-p <pad>] | |
| picotool bdev ls|mkdir|cp|rm|cat|format | |
| COMMANDS: | |
| help Show general help, or help for a specific command or topic. | |
| version Display picotool version. | |
| info Display information from the target device(s) or file. | |
| Without any arguments, this will display basic information for all connected | |
| RP-series 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. | |
| 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. | |
| erase Erase the program / memory stored in flash on the device. | |
| reboot Reboot the device. | |
| seal Add final metadata to a binary, optionally including a hash and/or signature. | |
| encrypt Encrypt the program. | |
| partition Commands related to RP2350 Partition Tables. | |
| uf2 Commands related to UF2 creation and status. | |
| otp Commands related to the RP2350 OTP (One-Time-Programmable) memory. | |
| coprodis Post-process coprocessor instructions in disassembly files. | |
| link Link multiple binaries into one block loop. | |
| bdev Commands related to embedded block devices. | |
| TOPICS: | |
| device-selection Options for Target Device Selection and Rebooting | |
| family-ids Valid Family IDs | |
| Use "picotool help <cmd>" or "picotool help <topic>" for more info | |
| ``` | |
| Note commands that aren't acting on files require a device in BOOTSEL mode to be connected. | |
| ## Links to documentation for `picotool` commands and help topics | |
| [`version`](#version) [`info`](#info) [`config`](#config) [`load`](#load) [`save`](#save) [`verify`](#verify) [`erase`](#erase) [`reboot`](#reboot) [`seal`](#seal) [`encrypt`](#encrypt) [`partition`](#partition) [`uf2`](#uf2) [`otp`](#otp) [`coprodis`](#coprodis) [`link`](#link) [`bdev`](#bdev) [`device-selection`](#device-selection) [`family-ids`](#family-ids) | |
| ## Building & Installing | |
| If you don't want to build picotool yourself, you can find pre-built executables for Windows, macOS, and Linux in the [pico-sdk-tools](https://github.com/raspberrypi/pico-sdk-tools/releases) repository. Assuming you've extracted that archive to `<extract_location>` (with the actual picotool executable at `<extract_location>/picotool/picotool`), you can point the Pico SDK at this binary by setting the `picotool_DIR` environment variable to `<extract_location>/picotool`, or by passing `-Dpicotool_DIR=<extract_location>/picotool` to your `cmake` command or setting it in your `CMakeLists.txt` file. | |
| If you do wish to build picotool yourself, then see [Building](BUILDING.md#building) for build instructions. For the Pico SDK to find your picotool you will need to install it, the simplest way being to run `cmake --install .` - see [Installing](BUILDING.md#installing-so-the-pico-sdk-can-find-it) for more details and alternatives. **You cannot just copy the binary into your `PATH`, else the Pico SDK will not be able to locate it.** | |
| ## version | |
| Displays the picotool version, and also allows checking compatibility with an expected `picotool` version, for example to check a newer `picotool` is backwards compatible with an older version. | |
| ```text | |
| $ picotool help version | |
| VERSION: | |
| Display picotool version. | |
| SYNOPSIS: | |
| picotool version [-s] [<version>] | |
| OPTIONS: | |
| -s, --semantic | |
| Output semantic version number only | |
| <version> | |
| Check compatibility with version | |
| ``` | |
| The normal output is this format: | |
| ```text | |
| $ picotool version | |
| picotool v2.3.1 (Linux, GNU-12.2.0, Release) | |
| ``` | |
| When built without libusb you get an additional message: | |
| ```text | |
| $ picotool version | |
| picotool v2.3.1 (Linux, GNU-12.2.0, Release) | |
| This version of picotool was compiled without USB support. Some commands are not available. | |
| ``` | |
| The semantic output is: | |
| ```text | |
| $ picotool version -s | |
| 2.3.1 | |
| ``` | |
| When checking compatibility with a compatible version (e.g. 2.2.0 with picotool version 2.3.1): | |
| ```text | |
| $ picotool version 2.2.0 | |
| picotool v2.3.1 (Linux, GNU-12.2.0, Release) | |
| ``` | |
| Or with an incompatible version (e.g. 2.3.1 with picotool version 2.2.0), it will exit with error code `ERROR_INCOMPATIBLE` (-3): | |
| ```text | |
| $ picotool version 2.3.1 | |
| picotool v2.2.0 (Linux, GNU-12.2.0, Release) | |
| ERROR: Version 2.3.1 not compatible with this software | |
| ``` | |
| ## info | |
| There 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. | |
| ```text | |
| $ picotool help info | |
| INFO: | |
| Display information from the target device(s) or file. | |
| Without any arguments, this will display basic information for all connected RP-series | |
| devices in BOOTSEL mode. | |
| SYNOPSIS: | |
| picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] [device-selection] | |
| picotool info [-b] [-m] [-p] [-d] [--debug] [-l] [-a] <filename> [-t <type>] | |
| OPTIONS: | |
| Information to display | |
| -b, --basic | |
| Include basic information. This is the default | |
| -m, --metadata | |
| Include all metadata blocks | |
| -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 RP-series device(s) (the default) | |
| See "picotool help device-selection" for available options | |
| To target a file | |
| <filename> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| ``` | |
| e.g. | |
| ```text | |
| $ picotool info | |
| Program Information | |
| name: hello_world | |
| features: stdout to UART | |
| ``` | |
| ```text | |
| $ 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 | |
| ``` | |
| ```text | |
| $ picotool info -bp | |
| Program Information | |
| name: hello_world | |
| features: stdout to UART | |
| Fixed Pin Information | |
| 20: UART1 TX | |
| 21: UART1 RX | |
| ``` | |
| ```text | |
| $ 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`. | |
| ```text | |
| $ 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: | |
| -s, --set <key> <value> | |
| Set config variable name to new value | |
| -g, --group <group> | |
| Filter by feature group | |
| TARGET SELECTION: | |
| To target one or more connected RP-series device(s) (the default) | |
| See "picotool help device-selection" for available options | |
| To target a file | |
| <filename> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| ``` | |
| ```text | |
| $ picotool config | |
| n = 5 | |
| name = "Billy" | |
| nonconst_pins: | |
| default_pin = 3 | |
| default_name = "My First Pin" | |
| ``` | |
| ```text | |
| $ picotool config -g nonconst_pins | |
| nonconst_pins: | |
| default_pin = 3 | |
| default_name = "My First Pin" | |
| ``` | |
| ```text | |
| $ 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) | |
| ```text | |
| $ 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: | |
| Load options | |
| --ignore-partitions | |
| Ignore the partition table, and ignore family ID compatibility | |
| --family <family_id> | |
| Specify the family ID of the file to load | |
| -p, --partition <partition> | |
| Specify the 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 | |
| Perform a bootrom reboot to execute the downloaded file as a program after the load | |
| - either a flash update boot for binaries in flash, or a RAM image boot for other | |
| binaries | |
| File to load from | |
| <filename> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| BIN file options | |
| -o, --offset <offset> | |
| Specify the load address for a BIN file (memory address; default 0x10000000) | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| e.g. | |
| ```text | |
| $ 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. | |
| ```text | |
| $ picotool help save | |
| SAVE: | |
| Save the program / memory stored in flash on the device to a file. | |
| SYNOPSIS: | |
| picotool save [-p] [-v] [--family <family_id>] <filename> [-t <type>] [device-selection] | |
| picotool save -a [-v] [--family <family_id>] <filename> [-t <type>] [device-selection] | |
| picotool save -r <from> <to> [-v] [--family <family_id>] <filename> [-t <type>] | |
| [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 <from> <to> | |
| Save a range of memory (address bounds in hex). Note that UF2s always store | |
| complete 256 byte-aligned blocks of 256 bytes, and the range is expanded | |
| accordingly. | |
| Other | |
| -v, --verify | |
| Verify the data was saved correctly | |
| --family <family_id> | |
| Specify the family ID to save the file as | |
| File to save to | |
| <filename> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| Source device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| e.g. first looking at what is on the device... | |
| ```text | |
| $ 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 ... | |
| ```text | |
| $ picotool save spoon.uf2 | |
| Saving file: [==============================] 100% | |
| Wrote 51200 bytes to spoon.uf2 | |
| ``` | |
| ... and looking at the file: | |
| ```text | |
| $ 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 | |
| ``` | |
| ## verify | |
| This command allows you to verify that the contents of Flash/SRAM on the device matches a file, similar to the `--verify` option for `save` and `load`. | |
| ```text | |
| $ picotool help verify | |
| VERIFY: | |
| Check that the device contents match those in the file. | |
| SYNOPSIS: | |
| picotool verify <filename> [-t <type>] [-r <from> <to>] [-o <offset>] [device-selection] | |
| OPTIONS: | |
| The file to compare against | |
| <filename> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| Address options | |
| -r, --range <from> <to> | |
| Compare a sub range of memory only (address bounds in hex) | |
| -o, --offset <offset> | |
| Specify the load address (memory address; default 0x10000000) when comparing with a | |
| BIN file | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ## erase | |
| `erase` allows you to erase all of flash, a partition of flash, or an explicit range of flash on the device. | |
| It defaults to erasing all of flash. | |
| ```text | |
| $ picotool help erase | |
| ERASE: | |
| Erase the program / memory stored in flash on the device. | |
| SYNOPSIS: | |
| picotool erase [-a] [device-selection] | |
| picotool erase -p <partition> [device-selection] | |
| picotool erase -r <from> <to> [device-selection] | |
| OPTIONS: | |
| Selection of data to erase | |
| -a, --all | |
| Erase all of flash memory. This is the default | |
| -p, --partition <partition> | |
| Erase a partition | |
| -r, --range <from> <to> | |
| Erase a range of memory (address bounds in hex). Note that erases must be 4096 | |
| byte-aligned, so the range is expanded accordingly. | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| e.g. first looking at what is on the device... | |
| ```text | |
| $ picotool info | |
| Partition 0 | |
| Program Information | |
| none | |
| Partition 1 | |
| Program Information | |
| name: blink | |
| web site: https://github.com/raspberrypi/pico-examples/tree/HEAD/blink | |
| features: UART stdin / stdout | |
| binary start: 0x10000000 | |
| binary end: 0x1000a934 | |
| target chip: RP2350 | |
| image type: ARM Secure | |
| ``` | |
| ... then erase partition 1 ... | |
| ```text | |
| $ picotool erase -p 1 | |
| Erasing partition 1: | |
| 0007f000->000fc000 | |
| Erasing: [==============================] 100% | |
| Erased 512000 bytes | |
| ``` | |
| ... and looking at the device again: | |
| ```text | |
| $ picotool info | |
| Partition 0 | |
| Program Information | |
| none | |
| Partition 1 | |
| Program Information | |
| none | |
| ``` | |
| ## reboot | |
| `reboot` allows you to reboot a device that is in BOOTSEL mode, or in application mode running compatible code (see [Forced Reboots](#forced-reboots)). You can reboot it into application or BOOTSEL mode, and select the Arm or Risc-V CPU on RP2350 | |
| ```text | |
| $ picotool help reboot | |
| REBOOT: | |
| Reboot the device. | |
| SYNOPSIS: | |
| picotool reboot [-a] [-u] [-g <partition>] [-c <cpu>] [device-selection] | |
| OPTIONS: | |
| Reboot type | |
| -a, --application | |
| Reboot back into the application (this is the default) | |
| -u, --usb | |
| Reboot back into BOOTSEL mode | |
| -g, --diagnostic <partition> | |
| Select diagnostic partition | |
| -c, --cpu <cpu> | |
| Select arm | riscv CPU (if possible) | |
| Selecting the device to reboot | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ## seal | |
| `seal` allows you to sign and/or hash a binary to run on RP2350. | |
| By default, it will just add an embedded block to the end containing a relative load map, thus sealing the binary. The `--hash` and `--sign` arguments can be passed to include an hash and a signature; `--major`, `--minor` and `--rollback` can be passed to include a version; and `--clear` or `--pin-xip-sram` can be passed to add load map items indicating whether SRAM should be cleared and whether XIP SRAM should be pinned. | |
| Your signing key must be for the _secp256k1_ curve, in PEM format. You can create a .PEM file with: | |
| ```bash | |
| openssl ecparam -name secp256k1 -genkey -out private.pem | |
| ``` | |
| ```text | |
| $ 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] [--pin-xip-sram] | |
| [--no-squash] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] [<key>] | |
| [<otp>] [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]] | |
| OPTIONS: | |
| --quiet | |
| Don't print any output | |
| --verbose | |
| Print verbose output | |
| <key> | |
| Key file (.pem) | |
| <otp> | |
| JSON file to save OTP to (will edit existing file if it exists) | |
| --major <major> | |
| Add Major Version | |
| --minor <minor> | |
| Add Minor Version | |
| --rollback <rollback> [<rows>..] | |
| Add Rollback Version, optionally specifying rollback rows in hex | |
| Configuration | |
| --hash | |
| Hash the file | |
| --sign | |
| Sign the file | |
| --clear | |
| Clear all of main SRAM on load | |
| --pin-xip-sram | |
| Pin XIP SRAM on load | |
| --no-squash | |
| Don't squash segments in the ELF file | |
| File to load from | |
| <infile> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| BIN file options | |
| -o, --offset <offset> | |
| Specify the load address for a BIN file (memory address; default 0x10000000) | |
| File to save to | |
| <outfile> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) 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 seal`. You can either provide your own bootloader to decrypt the binary (see pico-examples/bootloaders/encrypted), or embed a decrypting bootloader into the binary with the `--embed` argument, to create a self-decrypting binary. When embedding a bootloader, by default it will add a load map item to clear SRAM on load like the `picotool seal --clear` option - this can be disabled by passing `--no-clear`. | |
| 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 can either be provided as a 1024-bit (128 byte) 4-way key share or as a 256-bit (32 byte) AES key. In the latter case, a key share will be generated for you, as the decryption code needs a 4-way key share in OTP rather than a plain key. | |
| The 4-way key share should be generated by creating a random .bin file of length 128 bytes and the AES key will be derived from that. With the words stored in the file as A[0], B[0], C[0], D[0], A[1], B[1], etc., C[7], D[7], word i of the key X is X[i] = A[i] ^ B[i] ^ C[i] ^ D[i]. | |
| Alternatively an AES key can be provided directly, as either a 32 byte .bin file or as a string of 64 hexadecimal characters (eg 0x0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210). Picotool will generate a random key share for that key, by generating 3 random shares (A, B & C) and calculating a 4th share (D) to match the provided key (X), with each word i of the 4th share calculated as D[i] = X[i] ^ A[i] ^ B[i] ^ C[i]. | |
| When using a .bin file, picotool will use the file size to determine if a 128 byte key share or a 32 byte key has been provided - any other file size will throw an error. | |
| The encryption/decryption code also salts the IV (initialisation vector) so it's not stored in plaintext in the binary. This requires a per-device IV salt in OTP, which should be a 128-bit (16 byte) random value - this can be provided as either a 16 byte .bin file, or a string of 32 hexadecimal characters, similar to the AES key. This per-device salt will be XORed with the IV stored in the binary, to give the IV used by the decryption code. | |
| ```text | |
| $ picotool help encrypt | |
| ENCRYPT: | |
| Encrypt the program. | |
| SYNOPSIS: | |
| picotool encrypt [--quiet] [--verbose] [--embed] [--fast-rosc] [--use-mbedtls] | |
| [--otp-key-page <page>] [--hash] [--sign] [--no-clear] [--pin-xip-sram] | |
| <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> <iv_salt> | |
| [<signing_key>] [<otp>] | |
| OPTIONS: | |
| --quiet | |
| Don't print any output | |
| --verbose | |
| Print verbose output | |
| --embed | |
| Embed bootloader in output file | |
| --fast-rosc | |
| Use ~180MHz ROSC configuration for embedded bootloader | |
| --use-mbedtls | |
| Use MbedTLS implementation of embedded bootloader (faster but less secure) | |
| --otp-key-page <page> | |
| Specify the OTP page storing the AES key (default 29; IV salt is stored on the next | |
| page) | |
| <aes_key> | |
| AES Key Share or AES Key | |
| <iv_salt> | |
| IV Salt | |
| <signing_key> | |
| Signing Key file (.pem) | |
| <otp> | |
| JSON file to save OTP to (will edit existing file if it exists) | |
| Signing Configuration | |
| --hash | |
| Hash the encrypted file | |
| --sign | |
| Sign the encrypted file | |
| --no-clear | |
| Don't clear all of main SRAM on load | |
| --pin-xip-sram | |
| Pin XIP SRAM on load | |
| File to load from | |
| <infile> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| BIN file options | |
| -o, --offset <offset> | |
| Specify the load address for a BIN file (memory address; default 0x10000000) | |
| File to save to | |
| <outfile> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| ``` | |
| ## partition | |
| The `partition` commands allow you to interact with the partition tables on RP2350 devices, and also create them. | |
| ```text | |
| $ picotool help partition | |
| PARTITION: | |
| Commands related to RP2350 Partition Tables. | |
| SYNOPSIS: | |
| picotool partition info [-m <family_id>] [device-selection] | |
| picotool partition create [--quiet] [--verbose] <infile> <outfile> [-t <type>] [[-o | |
| <offset>] [--family <family_id>]] [<bootloader>] [-t <type>] [[--sign <keyfile> | |
| [-t <type>]] [--no-hash] [--singleton] [--no-btstack-flash-bank]] | |
| [[--abs-block] [<abs_block_loc>]] | |
| SUB COMMANDS: | |
| info Print the device's partition table. | |
| create Create a partition table from json. | |
| Use "picotool help partition <subcmd>" for more info | |
| ``` | |
| ### info | |
| ```text | |
| $ picotool help partition info | |
| PARTITION INFO: | |
| Print the device's partition table. | |
| SYNOPSIS: | |
| picotool partition info [-m <family_id>] [device-selection] | |
| OPTIONS: | |
| -m, --family <family_id> | |
| family ID (will show target partition for said family) | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ```text | |
| $ 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 | |
| ``` | |
| ```text | |
| $ 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 of ELF files (for example, for bootloaders). | |
| By default, all partition tables are hashed, and you can also sign them. The schema for this JSON file is [here](json/schemas/partition-table-schema.json). | |
| ```text | |
| $ picotool help partition create | |
| PARTITION CREATE: | |
| Create a partition table from json. | |
| SYNOPSIS: | |
| picotool partition create [--quiet] [--verbose] <infile> <outfile> [-t <type>] [[-o | |
| <offset>] [--family <family_id>]] [<bootloader>] [-t <type>] [[--sign <keyfile> | |
| [-t <type>]] [--no-hash] [--singleton] [--no-btstack-flash-bank]] | |
| [[--abs-block] [<abs_block_loc>]] | |
| OPTIONS: | |
| --quiet | |
| Don't print any output | |
| --verbose | |
| Print verbose output | |
| <infile> | |
| partition table JSON | |
| output file | |
| <outfile> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| UF2 output options | |
| -o, --offset <offset> | |
| Specify the load address for UF2 file output (memory address; default 0x10000000) | |
| --family <family_id> | |
| Specify the family id for UF2 file output (default absolute) | |
| Embed partition table into bootloader ELF | |
| <bootloader> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (elf) explicitly, ignoring file extension | |
| Partition Table Options | |
| --sign <keyfile> [-t, --type <type>] | |
| Sign the partition table with a PEM key | |
| --no-hash | |
| Don't hash the partition table | |
| --singleton | |
| Singleton partition table | |
| --no-btstack-flash-bank | |
| Don't check for compatibility with BTStack flash bank | |
| Errata RP2350-E10 Fix | |
| --abs-block | |
| Enforce support for an absolute block | |
| <abs_block_loc> | |
| absolute block location (memory address; default 0x10ffff00) | |
| ``` | |
| ## uf2 | |
| The `uf2` commands allow for creation of UF2s, and can provide information if a UF2 download has failed. | |
| ```text | |
| $ picotool help uf2 | |
| UF2: | |
| Commands related to UF2 creation and status. | |
| SYNOPSIS: | |
| picotool uf2 convert [--quiet] [--verbose] <infile> [-t <type>] <outfile> [-t <type>] [-o | |
| <offset>] [--family <family_id>] [--platform <platform>] [[--abs-block] | |
| [<abs_block_loc>]] | |
| picotool uf2 combine [--quiet] [--verbose] <infile1> [-t <type>] <infile2> [-t <type>] | |
| <outfile> [-t <type>] [--family <family_id>] [--offset <offset>] [--partition | |
| <partition>] [[--abs-block] [<abs_block_loc>]] | |
| picotool uf2 info [device-selection] | |
| SUB COMMANDS: | |
| convert Convert ELF/BIN to UF2. | |
| combine Combine multiple UF2 files. | |
| info Print info about UF2 download. (RP2350 only) | |
| Use "picotool help uf2 <subcmd>" for more info | |
| ``` | |
| ### 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. | |
| ```text | |
| $ 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>] [--platform <platform>] [[--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 <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| File to save UF2 to | |
| <outfile> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2) explicitly, ignoring file extension | |
| Packaging Options | |
| -o, --offset <offset> | |
| Specify the load address (memory address; default 0x10000000 for BIN file) | |
| UF2 Family options | |
| --family <family_id> | |
| Specify the family ID for UF2 | |
| Platform options | |
| --platform <platform> | |
| Optional platform for memory-address validation (eg rp2040, rp2350) | |
| Errata RP2350-E10 Fix | |
| --abs-block | |
| Add an absolute block | |
| <abs_block_loc> | |
| absolute block location (memory address; default 0x10ffff00) | |
| ``` | |
| ### combine | |
| This command is used to combine multiple UF2 files (possibly with different family IDs) into a single file with the same family ID. This can be useful for loading a partition table and multiple partitions onto a device using a single file. | |
| ```text | |
| $ picotool help uf2 combine | |
| UF2 COMBINE: | |
| Combine multiple UF2 files. | |
| SYNOPSIS: | |
| picotool uf2 combine [--quiet] [--verbose] <infile1> [-t <type>] <infile2> [-t <type>] | |
| <outfile> [-t <type>] [--family <family_id>] [--offset <offset>] [--partition | |
| <partition>] [[--abs-block] [<abs_block_loc>]] | |
| OPTIONS: | |
| --quiet | |
| Don't print any output | |
| --verbose | |
| Print verbose output | |
| First file to combine | |
| <infile1> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2) explicitly, ignoring file extension | |
| Second file to combine | |
| <infile2> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2) explicitly, ignoring file extension | |
| File to save output to | |
| <outfile> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2) explicitly, ignoring file extension | |
| UF2 Family options | |
| --family <family_id> | |
| Specify the family ID for combined UF2 (defaults to first one) | |
| Offset options | |
| --offset <offset> | |
| Offset second UF2 by amount (hexadecimal; default 0x0) | |
| Partition options | |
| --partition <partition> | |
| Place second UF2 in partition (first UF2 must contain a partition table) | |
| Errata RP2350-E10 Fix | |
| --abs-block | |
| Add an absolute block | |
| <abs_block_loc> | |
| absolute block location (memory address; default 0x10ffff00) | |
| ``` | |
| The `--partition` argument can be used to place the second file in a partition number, provided that there is a partition table in the first file. For example, take this `pt.json` | |
| ```json | |
| { | |
| "unpartitioned": { | |
| "families": ["absolute"], | |
| "permissions": { | |
| "secure": "rw", | |
| "nonsecure": "rw", | |
| "bootloader": "rw" | |
| } | |
| }, | |
| "partitions": [ | |
| { | |
| "size": "1024K", | |
| "families": ["rp2350-arm-s", "rp2350-riscv"], | |
| "permissions": { | |
| "secure": "rw", | |
| "nonsecure": "rw", | |
| "bootloader": "rw" | |
| } | |
| }, | |
| { | |
| "size": "1024K", | |
| "families": ["data"], | |
| "permissions": { | |
| "secure": "rw", | |
| "nonsecure": "rw", | |
| "bootloader": "rw" | |
| } | |
| } | |
| ] | |
| } | |
| ``` | |
| If you want to load this partition table, and put `code.uf2` and `data.uf2` into the partitions, all using a single UF2, you would run: | |
| ```text | |
| $ picotool partition create pt.json pt.uf2 | |
| $ picotool uf2 combine pt.uf2 code.uf2 tmp.uf2 --partition 0 | |
| $ picotool uf2 combine tmp.uf2 data.uf2 combined.uf2 --partition 1 | |
| $ picotool load -x combined.uf2 | |
| ``` | |
| ### info | |
| This command reads the information on an RP2350 device about why a UF2 download has failed. It will only give information if the most recent download has failed. | |
| ```text | |
| $ picotool help uf2 info | |
| UF2 INFO: | |
| Print info about UF2 download. (RP2350 only) | |
| SYNOPSIS: | |
| picotool uf2 info [device-selection] | |
| OPTIONS: | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ## 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. The schema for this JSON file is [here](json/schemas/otp-contents-schema.json) | |
| ```text | |
| $ picotool help otp | |
| OTP: | |
| Commands related to the RP2350 OTP (One-Time-Programmable) memory. | |
| SYNOPSIS: | |
| picotool otp get [-c <copies>] [-r] [-e] [-n] [-i <filename>] [device-selection] [-z] | |
| [<selector>..] | |
| picotool otp set [-c <copies>] [-r] [-e] [-s] [-i <filename>] [-z] <selector> <value> | |
| [device-selection] | |
| picotool otp load [-r] [-e] [-s <row>] [-i <filename>] <filename> [-t <type>] | |
| [device-selection] | |
| picotool otp white-label [-s <row>] <filename> [device-selection] | |
| picotool otp permissions <filename> [--led <pin>] [--hash] [--sign] [<key>] | |
| [device-selection] | |
| picotool otp dump [-r] [-e] [-p] [--output <filename>] [device-selection] | |
| picotool otp dump [-r] [-e] [-p] [--output <filename>] <input> [-t <type>] | |
| picotool otp list [-p] [-n] [-f] [-i <filename>] [<selector>..] | |
| SUB COMMANDS: | |
| 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 (MSB is ignored). (RP2350 only) | |
| white-label Set the white labelling values in OTP. (RP2350 only) | |
| permissions Set the OTP access permissions. (RP2350 only) | |
| dump Dump entire OTP. (RP2350 only) | |
| list List matching known registers/fields. | |
| Use "picotool help otp <subcmd>" for more info | |
| ``` | |
| ### get/set | |
| These commands will get/set specific rows of OTP. By default, they will read/write all redundant rows, but this can be overridden with the `-c` argument | |
| ```text | |
| $ picotool help otp get | |
| OTP GET: | |
| Get the value of one or more OTP registers/fields. (RP2350 only) | |
| SYNOPSIS: | |
| picotool otp get [-c <copies>] [-r] [-e] [-n] [-i <filename>] [device-selection] [-z] | |
| [<selector>..] | |
| OPTIONS: | |
| Row/field options | |
| -c, --copies <copies> | |
| Read multiple redundant values | |
| -r, --raw | |
| Get raw 24-bit values | |
| -e, --ecc | |
| Use error correction | |
| -n, --no-descriptions | |
| Don't show descriptions | |
| -i, --include <filename> | |
| Include extra otp definition | |
| Row/Field Selection | |
| -z, --fuzzy | |
| Allow fuzzy name searches in selector vs exact match | |
| <selector> | |
| The row/field selector, each of which can select a whole row: | |
| ROW_NAME to select a whole row by name. | |
| ROW_NUMBER to select a whole row by number. | |
| PAGE:PAGE_ROW_NUMBER to select a whole row by page and number within page. | |
| ... or can select a single field/subset of a row (where ROW_SEL is one of the above | |
| row selectors): | |
| ROW_SEL.FIELD_NAME to select a field within a row by name. | |
| ROW_SEL.n-m to select a range of bits within a row. | |
| ROW_SEL.n to select a single bit within a row. | |
| .FIELD_NAME to select any row's field by name. | |
| .. or can select multiple rows by using blank or '*' for PAGE or PAGE_ROW_NUMBER | |
| TARGET SELECTION: | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ```text | |
| $ picotool help otp set | |
| OTP SET: | |
| Set the value of an OTP row/field. (RP2350 only) | |
| SYNOPSIS: | |
| picotool otp set [-c <copies>] [-r] [-e] [-s] [-i <filename>] [-z] <selector> <value> | |
| [device-selection] | |
| OPTIONS: | |
| Redundancy/Error Correction Overrides | |
| -c, --copies <copies> | |
| Write multiple redundant values | |
| -r, --raw | |
| Set raw 24-bit values | |
| -e, --ecc | |
| Use error correction | |
| -s, --set-bits | |
| Set bits only | |
| -i, --include <filename> | |
| Include extra otp definition | |
| <value> | |
| The value to set | |
| Row/Field Selection | |
| -z, --fuzzy | |
| Allow fuzzy name searches in selector vs exact match | |
| <selector> | |
| The row/field selector, which can select a whole row: | |
| ROW_NAME to select a whole row by name. | |
| ROW_NUMBER to select a whole row by number. | |
| PAGE:PAGE_ROW_NUMBER to select a whole row by page and number within page. | |
| ... or can select a single field/subset of a row (where ROW_SEL is one of the above | |
| row selectors): | |
| ROW_SEL.FIELD_NAME to select a field within a row by name. | |
| ROW_SEL.n-m to select a range of bits within a row. | |
| ROW_SEL.n to select a single bit within a row. | |
| .FIELD_NAME to select any row's field by name. | |
| TARGET SELECTION: | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ### 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 seal`. The schema for this JSON file is [here](json/schemas/otp-schema.json) | |
| ```text | |
| $ picotool help otp load | |
| OTP 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 (MSB is ignored). (RP2350 only) | |
| SYNOPSIS: | |
| picotool otp load [-r] [-e] [-s <row>] [-i <filename>] <filename> [-t <type>] | |
| [device-selection] | |
| OPTIONS: | |
| Row options | |
| -r, --raw | |
| Set raw 24-bit values. This is the default for BIN files | |
| -e, --ecc | |
| Use error correction | |
| -s, --start_row <row> | |
| Start row to load at (note use 0x for hex) | |
| -i, --include <filename> | |
| Include extra otp definition | |
| File to load row(s) from | |
| <filename> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (json | bin) explicitly, ignoring file extension | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| For example, if you wish to sign a binary and then test secure boot with it, you can run the following set of commands: | |
| ```text | |
| $ picotool seal --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](json/sample-wl.json). The schema for this JSON file is [here](json/schemas/whitelabel-schema.json) | |
| ```text | |
| $ picotool help otp white-label | |
| OTP WHITE-LABEL: | |
| Set the white labelling values in OTP. (RP2350 only) | |
| SYNOPSIS: | |
| picotool otp white-label [-s <row>] <filename> [device-selection] | |
| OPTIONS: | |
| Row options | |
| -s, --start_row <row> | |
| Start row for white label struct (default 0x100) (note use 0x for hex) | |
| <filename> | |
| JSON file with white labelling values | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ```text | |
| $ 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, which may not be accessible in BOOTSEL mode. For example on RP2350 A2, the permissions for pages 32-63 are not writeable from BOOTSEL mode due to errata RP2350-E15. You may also have previously configured the permissions to block writes in BOOTSEL mode using `LOCK_BL`, but now wish to lock them down further. | |
| Because it runs a binary, the binary needs to be signed if secure boot is enabled. The binary will light an LED when running, which | |
| can be configured using the `--led` argument. You can define your OTP permissions in a json file, an example of which | |
| is in [sample-permissions.json](json/sample-permissions.json). The schema for this JSON file is [here](json/schemas/permissions-schema.json) | |
| ```text | |
| $ picotool help otp permissions | |
| OTP PERMISSIONS: | |
| Set the OTP access permissions. (RP2350 only) | |
| SYNOPSIS: | |
| picotool otp permissions <filename> [--led <pin>] [--hash] [--sign] [<key>] | |
| [device-selection] | |
| OPTIONS: | |
| <filename> | |
| JSON file to load permissions from | |
| --led <pin> | |
| LED Pin to flash; default 25 | |
| Signing Configuration | |
| --hash | |
| Hash the executable | |
| --sign | |
| Sign the executable | |
| <key> | |
| Key file (.pem) | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ```text | |
| $ picotool otp permissions --sign private.pem sample-permissions.json | |
| Picking file /usr/local/share/picotool/xip_ram_perms.elf | |
| page10 | |
| page10 = 0 | |
| setting page10 -> 4063233 | |
| page11 | |
| page11 = 0 | |
| setting page11 -> 4128781 | |
| page12 | |
| page12 = 0 | |
| setting page12 -> 4128768 | |
| Loading into XIP RAM: [==============================] 100% | |
| The device was rebooted to start the application. | |
| ``` | |
| ### dump | |
| This command will read the entire OTP contents and print it out as hex. | |
| ```text | |
| $ picotool help otp dump | |
| OTP DUMP: | |
| Dump entire OTP. (RP2350 only) | |
| SYNOPSIS: | |
| picotool otp dump [-r] [-e] [-p] [--output <filename>] [device-selection] | |
| picotool otp dump [-r] [-e] [-p] [--output <filename>] <input> [-t <type>] | |
| OPTIONS: | |
| Row/field options | |
| -r, --raw | |
| Get raw 24-bit values. This is the default | |
| -e, --ecc | |
| Use error correction | |
| -p, --pages | |
| Index by page number & row number | |
| --output <filename> | |
| Output BIN file to dump to (optional) | |
| TARGET SELECTION: | |
| To dump the contents of a target device | |
| See "picotool help device-selection" for available options | |
| To dump the contents of an OTP JSON file | |
| <input> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (json) explicitly, ignoring file extension | |
| ``` | |
| ### list | |
| This command will list all the defined OTP rows & fields. You can list specific rows/fields using the selector | |
| ```text | |
| $ picotool help otp list | |
| OTP LIST: | |
| List matching known registers/fields. | |
| SYNOPSIS: | |
| picotool otp list [-p] [-n] [-f] [-i <filename>] [<selector>..] | |
| OPTIONS: | |
| Row/Field Selection | |
| -p, --pages | |
| Show page number/page row number | |
| -n, --no-descriptions | |
| Don't show descriptions | |
| -f, --field-descriptions | |
| Show all field descriptions | |
| -i, --include <filename> | |
| Include extra otp definition | |
| <selector> | |
| The row/field selector, each of which can select a whole row: | |
| ROW_NAME to select a whole row by name. | |
| ROW_NUMBER to select a whole row by number. | |
| PAGE:PAGE_ROW_NUMBER to select a whole row by page and number within page. | |
| ... or can select a single field/subset of a row (where ROW_SEL is one of the above | |
| row selectors): | |
| ROW_SEL.FIELD_NAME to select a field within a row by name. | |
| ROW_SEL.n-m to select a range of bits within a row. | |
| ROW_SEL.n to select a single bit within a row. | |
| .FIELD_NAME to select any row's field by name. | |
| .. or can select multiple rows by using blank or '*' for PAGE or PAGE_ROW_NUMBER | |
| ``` | |
| ## coprodis | |
| This command is used by the SDK to post-process dissassembly files, to replace the coprocessor instructions (mcr, mrc, etc.) with more human readable ones (eg rcp_bvalid, gpioc_hi_put, etc.). | |
| ```text | |
| $ picotool help coprodis | |
| COPRODIS: | |
| Post-process coprocessor instructions in disassembly files. | |
| SYNOPSIS: | |
| picotool coprodis [--quiet] [--verbose] <infile> <outfile> | |
| OPTIONS: | |
| --quiet | |
| Don't print any output | |
| --verbose | |
| Print verbose output | |
| <infile> | |
| Input DIS | |
| <outfile> | |
| Output DIS | |
| ``` | |
| ## link | |
| This command is used to link multiple binaries with block loops into a single larger block loop. It can currently link up to 3 files into a block loop. It will add the required Rolling Window Delta items to the new block loop, to ensure that everyting is rolled correctly when being executed. For examples of its usage, see the universal examples in [pico-examples](https://github.com/raspberrypi/pico-examples?tab=readme-ov-file#universal). | |
| ```text | |
| $ picotool help link | |
| LINK: | |
| Link multiple binaries into one block loop. | |
| SYNOPSIS: | |
| picotool link [--quiet] [--verbose] <outfile> [-t <type>] <infile1> [-t <type>] <infile2> | |
| [-t <type>] [<infile3>] [-t <type>] [-p <pad>] | |
| OPTIONS: | |
| --quiet | |
| Don't print any output | |
| --verbose | |
| Print verbose output | |
| -p, --pad <pad> | |
| Specify alignment to pad to (hexadecimal; default 0x1000) | |
| File to write to | |
| <outfile> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | bin) explicitly, ignoring file extension | |
| Files to link | |
| <infile1> | |
| The file name | |
| -t, --type <type> | |
| Specify file type (uf2 | elf | bin) explicitly, ignoring file extension | |
| <infile2> | |
| The file name | |
| <infile3> | |
| The file name | |
| ``` | |
| ## bdev | |
| The `bdev` commands are for interacting with block devices in Flash. The block device location can either be determined using binary info, or you can specify a partition to use as a block device. The commands work with a LittleFS filesystem, or a FatFS filesystem. | |
| ```text | |
| $ picotool help bdev | |
| BDEV: | |
| Commands related to embedded block devices. | |
| SYNOPSIS: | |
| picotool bdev ls [<dirname>] [-r] [-p <partition number>] [--partition-name <partition | |
| name>] [--partition-id <partition id>] [--filesystem <fs>] | |
| [--force-formattable] [--force-writeable] [--format] [device-selection] | |
| picotool bdev mkdir <dirname> [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [--format] [device-selection] | |
| picotool bdev cp <src> <dest> [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [--format] [device-selection] | |
| picotool bdev rm <filename> [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [--format] [device-selection] | |
| picotool bdev cat <filename> [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [--format] [device-selection] | |
| picotool bdev format [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [device-selection] | |
| SUB COMMANDS: | |
| ls List contents of the block device. | |
| mkdir Create directory on the block device. | |
| cp Copy file to/from the block device - use :filename to indicate files on the device | |
| (eg `cp main.py :main.py` to upload to the device). | |
| rm Delete a file or an empty directory on the block device. | |
| cat Print contents of file on the block device. | |
| format Format the block device. | |
| Use "picotool help bdev <subcmd>" for more info | |
| ``` | |
| ### ls | |
| List contents of the block device | |
| ```text | |
| $ picotool help bdev ls | |
| BDEV LS: | |
| List contents of the block device. | |
| SYNOPSIS: | |
| picotool bdev ls [<dirname>] [-r] [-p <partition number>] [--partition-name <partition | |
| name>] [--partition-id <partition id>] [--filesystem <fs>] | |
| [--force-formattable] [--force-writeable] [--format] [device-selection] | |
| OPTIONS: | |
| <dirname> | |
| The directory name to list (optional) | |
| -r, --recursive | |
| List files in directories recursively | |
| Block device options | |
| -p, --partition-number <partition number> | |
| Partition number to use as block device | |
| --partition-name <partition name> | |
| Partition name to use as block device | |
| --partition-id <partition id> | |
| Partition ID to use as block device | |
| --filesystem <fs> | |
| Specify filesystem to use (littlefs|fatfs) | |
| --force-formattable | |
| Allow formatting, even if the block device is not marked as fomattable | |
| --force-writeable | |
| Allow writing, even if the block device is not marked as writeable | |
| --format | |
| Format the drive if necessary (may result in data loss) | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ### mkdir | |
| Create directory on the block device | |
| ```text | |
| $ picotool help bdev mkdir | |
| BDEV MKDIR: | |
| Create directory on the block device. | |
| SYNOPSIS: | |
| picotool bdev mkdir <dirname> [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [--format] [device-selection] | |
| OPTIONS: | |
| <dirname> | |
| The directory name | |
| Block device options | |
| -p, --partition-number <partition number> | |
| Partition number to use as block device | |
| --partition-name <partition name> | |
| Partition name to use as block device | |
| --partition-id <partition id> | |
| Partition ID to use as block device | |
| --filesystem <fs> | |
| Specify filesystem to use (littlefs|fatfs) | |
| --force-formattable | |
| Allow formatting, even if the block device is not marked as fomattable | |
| --force-writeable | |
| Allow writing, even if the block device is not marked as writeable | |
| --format | |
| Format the drive if necessary (may result in data loss) | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ### cp | |
| Copy file to/from the block device - use :filename to indicate files on the device (e.g. `cp main.py :main.py` to upload to the device, or `cp :main.py main.py` to download from the device) | |
| ```text | |
| $ picotool help bdev cp | |
| BDEV CP: | |
| Copy file to/from the block device - use :filename to indicate files on the device (eg `cp | |
| main.py :main.py` to upload to the device). | |
| SYNOPSIS: | |
| picotool bdev cp <src> <dest> [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [--format] [device-selection] | |
| OPTIONS: | |
| <src> | |
| The file name | |
| <dest> | |
| The file name | |
| Block device options | |
| -p, --partition-number <partition number> | |
| Partition number to use as block device | |
| --partition-name <partition name> | |
| Partition name to use as block device | |
| --partition-id <partition id> | |
| Partition ID to use as block device | |
| --filesystem <fs> | |
| Specify filesystem to use (littlefs|fatfs) | |
| --force-formattable | |
| Allow formatting, even if the block device is not marked as fomattable | |
| --force-writeable | |
| Allow writing, even if the block device is not marked as writeable | |
| --format | |
| Format the drive if necessary (may result in data loss) | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ### rm | |
| Delete a file or an empty directory on the block device | |
| ```text | |
| $ picotool help bdev rm | |
| BDEV RM: | |
| Delete a file or an empty directory on the block device. | |
| SYNOPSIS: | |
| picotool bdev rm <filename> [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [--format] [device-selection] | |
| OPTIONS: | |
| <filename> | |
| The file name | |
| Block device options | |
| -p, --partition-number <partition number> | |
| Partition number to use as block device | |
| --partition-name <partition name> | |
| Partition name to use as block device | |
| --partition-id <partition id> | |
| Partition ID to use as block device | |
| --filesystem <fs> | |
| Specify filesystem to use (littlefs|fatfs) | |
| --force-formattable | |
| Allow formatting, even if the block device is not marked as fomattable | |
| --force-writeable | |
| Allow writing, even if the block device is not marked as writeable | |
| --format | |
| Format the drive if necessary (may result in data loss) | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ### cat | |
| Print contents of file on the block device | |
| ```text | |
| $ picotool help bdev cat | |
| BDEV CAT: | |
| Print contents of file on the block device. | |
| SYNOPSIS: | |
| picotool bdev cat <filename> [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [--format] [device-selection] | |
| OPTIONS: | |
| <filename> | |
| The file name | |
| Block device options | |
| -p, --partition-number <partition number> | |
| Partition number to use as block device | |
| --partition-name <partition name> | |
| Partition name to use as block device | |
| --partition-id <partition id> | |
| Partition ID to use as block device | |
| --filesystem <fs> | |
| Specify filesystem to use (littlefs|fatfs) | |
| --force-formattable | |
| Allow formatting, even if the block device is not marked as fomattable | |
| --force-writeable | |
| Allow writing, even if the block device is not marked as writeable | |
| --format | |
| Format the drive if necessary (may result in data loss) | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ### format | |
| Format the block device - may result in data loss | |
| ```text | |
| $ picotool help bdev format | |
| BDEV FORMAT: | |
| Format the block device. | |
| SYNOPSIS: | |
| picotool bdev format [-p <partition number>] [--partition-name <partition name>] | |
| [--partition-id <partition id>] [--filesystem <fs>] [--force-formattable] | |
| [--force-writeable] [device-selection] | |
| OPTIONS: | |
| Block device options | |
| -p, --partition-number <partition number> | |
| Partition number to use as block device | |
| --partition-name <partition name> | |
| Partition name to use as block device | |
| --partition-id <partition id> | |
| Partition ID to use as block device | |
| --filesystem <fs> | |
| Specify filesystem to use (littlefs|fatfs) | |
| --force-formattable | |
| Allow formatting, even if the block device is not marked as fomattable | |
| --force-writeable | |
| Allow writing, even if the block device is not marked as writeable | |
| Target device selection | |
| See "picotool help device-selection" for available options | |
| ``` | |
| ## Help topics | |
| `picotool help <topic>` shows additional documentation that applies across multiple commands, rather than to a single command. | |
| ### device-selection | |
| ```text | |
| $ picotool help device-selection | |
| Options for Target Device Selection and Rebooting: | |
| Options for selecting or filtering the target RP-series device(s), including rebooting | |
| devices to BOOTSEL mode first. These options are accepted by most commands which target a | |
| device. | |
| For the `-f/F` options, compatible code is defined as code which uses stdio_usb or the | |
| pico_usb_reset library, and which is still running. See Forced Reboots in the README | |
| (https://github.com/raspberrypi/picotool#forced-reboots) for more information. | |
| OPTIONS: | |
| --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 | |
| --rp2040 | |
| Assume the device is an RP2040 - this is only required when using a custom vid/pid | |
| with an RP2040 on Windows, and is ignored on other operating systems | |
| -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 USB drive mounted | |
| --bootsel-led <gpio> | |
| Specify the GPIO for the BOOTSEL activity LED to flash (default none, ignored by | |
| RP2350A-A2 in Arm mode) - only applicable if this command reboots the device to | |
| BOOTSEL mode | |
| --bootsel-led-active-low | |
| The BOOTSEL activity LED is active low (ignored by RP2040 and RP2350-A4) | |
| ``` | |
| ### family-ids | |
| ```text | |
| $ picotool help family-ids | |
| Valid Family IDs: | |
| A family ID identifies the target chip and/or image type of a UF2 file, and is accepted by | |
| the --family option of several commands. | |
| Valid family IDs are: data, absolute, rp2040, rp2350-arm-s, rp2350-arm-ns, rp2350-riscv, | |
| cyw43-firmware. | |
| A family ID may also be given directly as a 32 bit hex value, e.g. 0x12345678. | |
| ``` | |
| ## 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: | |
| ```text | |
| $ 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. | |
| ```text | |
| $ 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: | |
| ```text | |
| $ 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: | |
| ```c | |
| 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: | |
| ```c | |
| 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 | |
| ```c | |
| 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. | |
| ```c | |
| 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 | |
| ```c | |
| #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 | |
| ```c | |
| #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. | |
| ```c | |
| #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 | |
| ```c | |
| 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 | |
| ```cmake | |
| 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, and they can be accessed with the [`bdev`](#bdev) commands. In the future, backup/restore and even fuse mount might be interesting additions. | |
| These can be tagged using the `bi_block_device` macro: | |
| ```c | |
| #define bi_block_device(_tag, _name, _offset, _size, _extra, _flags) | |
| ``` | |
| using the following flags | |
| ```c | |
| 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 | |
| }; | |
| ``` | |
| For more information see the Pico SDK, where this macro and flags are defined. | |
| ### 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](https://github.com/raspberrypi/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 or the pico_usb_reset library - | |
| If your binary calls `stdio_init_all()`, does not use TinyUSB directly (i.e. does not link `tinyusb_device`), and you have `pico_enable_stdio_usb(<yourTargetName> 1)` in your CMakeLists.txt file, then you meet | |
| this requirement (see the [hello_usb](https://github.com/raspberrypi/pico-examples/tree/master/hello_world/usb) example). If you are using TinyUSB directly, see the [library documentation](https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_usb_reset) or the [dev_multi_cdc](https://github.com/raspberrypi/pico-examples/tree/master/usb/device/dev_multi_cdc) example for more details on how to enable the `pico_usb_reset` library. | |
| ### 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). | |
| ### Zadig | |
| To communicate with RP2040 in BOOTSEL mode on Windows, you will need to install a driver. To do this, download and run [Zadig](http://zadig.akeo.ie), select `RP2 Boot (Interface 1)` from the dropdown box and select `WinUSB` as the driver, and click on the "Install Driver" button. Wait for the installation to complete - this may take a few minutes. | |
| This is only required for RP2040. |