Debe configurar PICO_SDK_PATH en el entorno o pasarlo a cmake con -DPICO_SDK_PATH=/path/to/pico-sdk
. Para utilizar funciones como firma o hash, deberá asegurarse de que el submódulo mbedtls en el SDK esté desprotegido; esto se puede hacer ejecutándolo desde su directorio SDK.
git submodule update --init lib/mbedtls
También necesitas instalar libusb-1.0
.
Utilice su herramienta de paquete favorita para instalar dependencias. Por ejemplo, en Ubuntu:
sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake
Luego simplemente construya como un proyecto CMake normal:
mkdir build
cd build
cmake ..
make
En Linux puedes agregar reglas udev para ejecutar picotool sin sudo:
sudo cp udev/99-picotool.rules /etc/udev/rules.d/
Descargue libUSB desde aquí https://libusb.info/
establezca la variable de entorno LIBUSB_ROOT en el directorio de instalación.
mkdir build
cd build
cmake -G "NMake Makefiles" ..
nmake
Descargue libUSB desde aquí https://libusb.info/
establezca la variable de entorno LIBUSB_ROOT en el directorio de instalación.
mkdir build
cd build
cmake ..
make
No es necesario descargar libusb por separado ni configurar LIBUSB_ROOT
.
pacman -S $MINGW_PACKAGE_PREFIX-{toolchain,cmake,libusb}
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
cmake --build .
La versión 2.0.0 y superior del Raspberry Pi Pico SDK (pico-sdk) utiliza picotool
para realizar la conversión de ELF a UF2 que anteriormente manejaba la herramienta elf2uf2
en el SDK. El SDK también utiliza picotool
para realizar hash y firmar archivos binarios.
Si bien el SDK puede descargar picotool por sí solo por proyecto, si tiene varios proyectos o configuraciones de compilación, es preferible instalar una única copia de picotool
localmente. Esto se puede hacer de forma más sencilla con make install
o cmake --install .
; el SDK utilizará esta versión instalada de forma predeterminada.
Alternativamente, puede instalar en una ruta personalizada a través de:
cmake -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR -DPICOTOOL_FLAT_INSTALL=1 ..
Para que el SDK encuentre picotool
en esta ruta personalizada, deberá configurar la variable picotool_DIR
en su proyecto, ya sea configurando la variable de entorno picotool_DIR
, pasando -Dpicotool_DIR=$MY_INSTALL_DIR/picotool
a su comando cmake
o agregando set(picotool_DIR $MY_INSTALL_DIR/picotool)
en su archivo CMakeLists.txt.
picotool
es una herramienta para trabajar con binarios RP2040/RP2350 e interactuar con dispositivos RP2040/RP2350 cuando están en modo BOOTSEL. (A partir de la versión 1.1 de picotool
también es posible interactuar con dispositivos que no están en modo BOOTSEL, pero que utilizan soporte USB stdio del SDK Raspberry Pi Pico usando el argumento -f
de picotool
).
Nota para obtener documentación adicional, consulte 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] [-t ]
picotool config [-s ] [-g ] [device-selection]
picotool config [-s ] [-g ] [-t ]
picotool load [-p] [-n] [-N] [-u] [-v] [-x] [-t ] [-o ] [device-selection]
picotool encrypt [--quiet] [--verbose] [--hash] [--sign] [-t ] [-o ] [-t ] [-t ] [] [-t ]
picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] [-t ] [-o ] [-t ] [] [-t ] [] [-t ] [--major ] [--minor ] [--rollback [..]]
picotool link [--quiet] [--verbose] [-t ] [-t ] [-t ] [] [-t ] [-p]
picotool save [-p] [device-selection]
picotool save -a [device-selection]
picotool save -r [device-selection]
picotool verify [device-selection]
picotool reboot [-a] [-u] [-g ] [-c ] [device-selection]
picotool otp list|get|set|load|dump|permissions|white-label
picotool partition info|create
picotool uf2 info|convert
picotool version [-s] []
picotool coprodis [--quiet] [--verbose] [-t ] [-t ]
picotool help []
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 " for more info
Tenga en cuenta que los comandos que no actúan sobre archivos requieren que se conecte un dispositivo en modo BOOTSEL.
Hay soporte de información binaria en el SDK que permite almacenar fácilmente información compacta que picotool
puede encontrar (consulte la sección Información binaria a continuación). El comando info es para leer esta información.
La información se puede leer desde uno o más dispositivos conectados en modo BOOTSEL o desde un archivo. Este archivo puede ser un archivo ELF, UF2 o BIN.
$ 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] [-t ]
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
Filter devices by USB bus number
--address
Filter devices by USB device address
--vid
Filter by vendor id
--pid
Filter by product id
--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
The file name
-t
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
Tenga en cuenta que los argumentos -f varían ligeramente para las plataformas Windows frente a macOS/Unix.
p.ej
$ picotool info Información del programa nombre: hello_world características: stdout a 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 Información del programa nombre: hello_world características: stdout a UART
Información de pin fijo 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 le permite configurar la información binaria en un dispositivo, si es configurable. Específicamente, puede configurar bi_ptr_int32
y bi_ptr_string
.
$ picotool help config
CONFIG:
Display or change program configuration settings from the target device(s) or file.
SYNOPSIS:
picotool config [-s ] [-g ] [device-selection]
picotool config [-s ] [-g ] [-t ]
OPTIONS:
Variable name
New value
-g
Filter by feature group
TARGET SELECTION:
To target one or more connected RP2040 device(s) in BOOTSEL mode (the default)
--bus
Filter devices by USB bus number
--address
Filter devices by USB device address
--vid
Filter by vendor id
--pid
Filter by product id
--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
The file name
-t
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
le permite escribir datos de un archivo en el dispositivo (ya sea escribiendo en la memoria flash o en la RAM)
$ picotool help load
LOAD:
Load the program / memory range stored in a file onto the device.
SYNOPSIS:
picotool load [--ignore-partitions] [--family ] [-p ] [-n] [-N] [-u] [-v] [-x] [-t ] [-o
] [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 to use for load
-p, --partition
Specify the partition to load into
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
The file name
-t
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
BIN file options
-o, --offset
Specify the load address for a BIN file
Load offset (memory address; default 0x10000000)
Target device selection
--bus
Filter devices by USB bus number
--address
Filter devices by USB device address
--vid
Filter by vendor id
--pid
Filter by product id
--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
p.ej
$ picotool load blink.uf2
Loading into Flash: [==============================] 100%
save
le permite guardar un rango de RAM, el programa en flash o un rango explícito de flash del dispositivo en un archivo BIN o un archivo UF2.
$ 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 [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
The lower address bound in hex
The upper address bound in hex
Source device selection
--bus
Filter devices by USB bus number
--address
Filter devices by USB device address
--vid
Filter by vendor id
--pid
Filter by product id
--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
The file name
-t
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
por ejemplo, mirando primero lo que hay en el dispositivo...
$ picotool info
Program Information
name: lcd_1602_i2c
web site: https://github.com/raspberrypi/pico-examples/tree/HEAD/i2c/lcd_1602_i2c
... guardándolo en un archivo ...
$ picotool save spoon.uf2
Saving file: [==============================] 100%
Wrote 51200 bytes to spoon.uf2
... y mirando el archivo:
$ 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
le permite firmar y/o codificar un binario para ejecutarlo en RP2350.
De forma predeterminada, simplemente firmará el binario, pero esto se puede configurar con los argumentos --hash
y --no-sign
.
Su clave de firma debe ser para la curva secp256k1 , en formato PEM. Puede crear un archivo .PEM con:
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] [-t ] [-o ] [-t ] [] [-t
] [] [-t ] [--major ] [--minor ] [--rollback [..]]
OPTIONS:
--quiet
Don't print any output
--verbose
Print verbose output
--major
Add Major Version
--minor
Add Minor Version
--rollback [..]
Add Rollback Version
Configuration
--hash
Hash the file
--sign
Sign the file
--clear
Clear all of SRAM on load
File to load from
The file name
-t
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
BIN file options
-o, --offset
Specify the load address for a BIN file
Load offset (memory address; default 0x10000000)
File to save to
The file name
-t
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
Key file
The file name
-t
Specify file type (pem) explicitly, ignoring file extension
File to save OTP to (will edit existing file if it exists)
The file name
-t
Specify file type (json) explicitly, ignoring file extension
encrypt
le permite cifrar y firmar un binario para usarlo en el RP2350. De forma predeterminada, firmará el binario cifrado, pero se puede configurar de manera similar a picotool sign
.
El binario cifrado tendrá la siguiente estructura:
La clave AES debe proporcionarse como un archivo .bin de la clave AES de 256 bits que se utilizará para el cifrado.
$ picotool help encrypt
ENCRYPT:
Encrypt the program.
SYNOPSIS:
picotool encrypt [--quiet] [--verbose] [--hash] [--sign] [-t ] [-o ] [-t ] [-t ]
[] [-t ]
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
The file name
-t
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
BIN file options
-o, --offset
Specify the load address for a BIN file
Load offset (memory address; default 0x10000000)
File to save to
The file name
-t
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
AES Key
The file name
-t
Specify file type (bin) explicitly, ignoring file extension
Signing Key file
The file name
-t
Specify file type (pem) explicitly, ignoring file extension
Los comandos partition
le permiten interactuar con las tablas de particiones en dispositivos RP2350 y también crearlas.
$ picotool help partition info
PARTITION INFO:
Print the device's partition table.
SYNOPSIS:
picotool partition info -m [device-selection]
OPTIONS:
-m [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
Este comando le permite crear tablas de particiones y, además, incrustarlas en el bucle de bloque si son archivos ELF (por ejemplo, para cargadores de arranque). De forma predeterminada, todas las tablas de particiones tienen hash y también puede firmarlas.
$ picotool help partition create
PARTITION CREATE:
Create a partition table from json
SYNOPSIS:
picotool partition create [--quiet] [--verbose] [-t ] [-t ] [[-o ] [--family ]]
[] [-t ] [[--sign ] [-t ] [--no-hash] [--singleton]] [[--abs-block] []]
OPTIONS:
--quiet
Don't print any output
--verbose
Print verbose output
partition table JSON
The file name
-t
Specify file type (json) explicitly, ignoring file extension
output file
The file name
-t
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
UF2 output options
-o, --offset
Specify the load address for UF2 file output
Load offset (memory address; default 0x10000000)
--family
Specify the family if for UF2 file output
family id for UF2 (default absolute)
embed partition table into bootloader ELF
The file name
-t
Specify file type (elf) explicitly, ignoring file extension
Partition Table Options
--sign
The file name
-t
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
absolute block location (default to 0x10ffff00)
Los comandos uf2
permiten la creación de UF2 y la cámara proporciona información cuando falla la descarga de UF2.
Este comando reemplaza la funcionalidad elf2uf2 que estaba anteriormente en el SDK de Raspberry Pi Pico. Intentará detectar automáticamente el ID de la familia, pero si esto falla, puede especificar uno manualmente con el argumento --family
.
picotool help uf2 convert
UF2 CONVERT:
Convert ELF/BIN to UF2.
SYNOPSIS:
picotool uf2 convert [--quiet] [--verbose] [-t ] [-t ] [-o ] [--family ]
[[--abs-block] []]
OPTIONS:
--quiet
Don't print any output
--verbose
Print verbose output
File to load from
The file name
-t
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
File to save UF2 to
The file name
-t
Specify file type (uf2) explicitly, ignoring file extension
Packaging Options
-o, --offset
Specify the load address
Load offset (memory address; default 0x10000000 for BIN file)
UF2 Family options
family id for UF2
Errata RP2350-E9 Fix
--abs-block
Add an absolute block
absolute block location (default to 0x10ffff00)
Este comando lee la información en un dispositivo sobre por qué falló una descarga de UF2. Sólo dará información si la descarga más reciente ha fallado.
$ picotool help uf2 info
UF2 INFO:
Print info about UF2 download.
SYNOPSIS:
picotool uf2 info [device-selection]
OPTIONS:
Target device selection
--bus
Filter devices by USB bus number
--address
Filter devices by USB device address
--vid
Filter by vendor id
--pid
Filter by product id
--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
Los comandos otp
sirven para interactuar con la memoria OTP RP2350. No están disponibles en dispositivos RP2040, ya que RP2040 no tiene OTP.
Tenga en cuenta que la memoria OTP es programable una sola vez, lo que significa que una vez que un bit se cambia de 0 a 1, no se puede volver a cambiar. Por lo tanto, se debe tener precaución al utilizar estos comandos, ya que corren el riesgo de bloquear su dispositivo RP2350. Por ejemplo, si configura SECURE_BOOT_ENABLE pero no configura una clave de inicio y desactiva la interfaz PICOBOOT, su dispositivo quedará inutilizable.
Para los comandos list
, set
, get
y load
, puede definir su propio diseño OTP en un archivo JSON y pasarlo con el argumento -i
. Estas filas se agregarán a las filas predeterminadas al analizar.
$ picotool help otp
OTP:
Commands related to the RP2350 OTP (One-Time-Programmable) Memory
SYNOPSIS:
picotool otp list [-p] [-n] [-i ] [..]
picotool otp get [-c ] [-r] [-e] [-n] [-i ] [device-selection] [-z] [..]
picotool otp set [-c ] [-r] [-e] [-i ] [-z] [device-selection]
picotool otp load [-r] [-e] [-s ] [-i ] [-t ] [device-selection]
picotool otp dump [-r] [-e] [device-selection]
picotool otp permissions [-t ] [--led ] [--hash] [--sign] [] [-t ] [device-selection]
picotool otp white-label -s [-t ] [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)
Estos comandos establecerán/obtendrán filas específicas de OTP. De forma predeterminada, escribirán/leerán todas las filas redundantes, pero esto se puede anular con el argumento -c
Este comando permite cargar una variedad de filas OTP en el dispositivo. La fuente puede ser un archivo binario o un archivo JSON como el que genera picotool sign
. Por ejemplo, si desea firmar un binario y luego probar el arranque seguro con él, puede ejecutar el siguiente conjunto de comandos:
$ 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
Este comando permite el etiquetado blanco OTP, que establece la configuración USB utilizada por el dispositivo en modo BOOTSEL. Esto se puede configurar desde un archivo JSON, un ejemplo del cual se encuentra en sample-wl.json.
$ picotool help otp white-label
OTP WHITE-LABEL:
Set the white labelling values in OTP
SYNOPSIS:
picotool otp white-label -s [-t ] [device-selection]
OPTIONS:
File with white labelling values
The file name
-t
Specify file type (json) explicitly, ignoring file extension
Target device selection
--bus
Filter devices by USB bus number
--address
Filter devices by USB device address
--vid
Filter by vendor id
--pid
Filter by product id
--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
...
Este comando ejecutará un binario en su dispositivo para configurar los permisos OTP, ya que no se puede acceder a ellos directamente desde picotool
debido a la configuración de permisos predeterminada necesaria para corregir la errata XXX en RP2350. Debido a que ejecuta un binario, es necesario firmarlo si el arranque seguro está habilitado. El binario imprimirá lo que está haciendo en uart, que se puede configurar utilizando los argumentos de configuración de UART. Puede definir sus permisos OTP en un archivo json, un ejemplo del cual se encuentra en sample-permissions.json.
$ picotool help otp permissions
OTP PERMISSIONS:
Set the OTP access permissions
SYNOPSIS:
picotool otp permissions [-t ] [--led ] [--hash] [--sign] [] [-t ] [device-selection]
OPTIONS:
File to load permissions from
The file name
-t
Specify file type (json) explicitly, ignoring file extension
--led
LED Pin to flash; default 25
Signing Configuration
--hash
Hash the executable
--sign
Sign the executable
Key file
The file name
-t
Specify file type (pem) explicitly, ignoring file extension
Target device selection
--bus
Filter devices by USB bus number
--address
Filter devices by USB device address
--vid
Filter by vendor id
--pid
Filter by product id
--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.
La información binaria es localizable por la máquina y generalmente consumible por la máquina. Digo en general porque cualquiera puede incluir cualquier información, y nosotros podemos distinguirla de la nuestra, pero depende de ellos si hacen que sus datos sean autodescriptivos.
Tenga en cuenta que ciertamente agregaremos más información binaria con el tiempo, ¡pero me gustaría incluir un conjunto básico mínimo en la mayoría de los archivos binarios desde el lanzamiento!
¡Esta información es realmente útil cuando tomas un Pico y no sabes lo que contiene!
La información básica incluye
La información binaria es autodescriptiva/extensible, por lo que los programas pueden incluir información que picotool no conoce (por ejemplo, MicroPython incluye una lista de bibliotecas integradas).
Esto es ciertamente útil cuando tienes un ejecutable llamado 'hello_world.elf' pero olvidaste para qué placa está diseñado...
Las asignaciones de pines estáticas (fijas) se pueden registrar en binario de forma muy compacta:
$ 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
Esto es muy útil si desea poder modificar parámetros en un binario, sin tener que volver a compilarlo.
$ picotool config -s name Jane
name = "Billy"
setting name -> "Jane"
La información binaria se declara en el programa mediante macros (viles macros deformadas); para el ejemplo de pines:
$ 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
... hay una línea en la función setup_default_uart
:
bi_decl_if_func_used ( bi_2pins_with_func ( PICO_DEFAULT_UART_RX_PIN , PICO_DEFAULT_UART_TX_PIN , GPIO_FUNC_UART ));
Los dos números de pin y la función UART se almacenan y luego picotool los decodifica a sus nombres de función reales (UART1 TX, etc.). bi_decl_if_func_used
se asegura de que la información binaria solo se incluya si se llama a la función contenedora.
Igualmente, el código del vídeo contiene unas líneas como esta:
bi_decl_if_func_used ( bi_pin_mask_with_name ( 0x1f << ( PICO_SCANVIDEO_COLOR_PIN_BASE + PICO_SCANVIDEO_DPI_PIXEL_RSHIFT ), "Red 0-4" ));
Para el ejemplo de configuración, pones la línea
bi_decl ( bi_ptr_string ( 0x1111 , 0x3333 , name , "Billy" , 128 ));
en su código, que luego creará la variable de nombre para que la imprima posteriormente. Los parámetros son la etiqueta, el ID, el nombre de la variable, el valor predeterminado y la longitud máxima de la cadena.
printf ( "Name is %sn" , name );
Las cosas están diseñadas para desperdiciar el menor espacio posible, pero puedes desactivar todo con la variable del preprocesador PICO_NO_BINARY_INFO=1
. Además, cualquier código SDK que inserte información binaria puede excluirse por separado mediante su propia variable de preprocesador.
necesitas
#include "pico/binary_info.h"
Básicamente, puedes usar bi_decl(bi_blah(...))
para la inclusión incondicional de la información binaria blah, o bi_decl_if_func_used(bi_blah(...))
para información binaria que puede eliminarse si la función adjunta no está incluida en el binario por el enlazador (piense --gc-sections
)
Hay un montón de macros bi_ en los encabezados.
#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 ) ...
que hacen uso de macros subyacentes, por ejemplo
#define bi_program_url ( url ) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_URL, url)
NOTA: Es fácil olvidar incluirlos en bi_decl
etc., por lo que se ha hecho un esfuerzo (a expensas de muchos gatitos) para que la compilación falle con un mensaje de error algo útil si lo hace.
Por ejemplo, intentar compilar
bi_1pin_with_name ( 0 , "Toaster activator" );
da
/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
puedes usar
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" )
Tenga en cuenta que todos estos se pasan como argumentos de línea de comando para la compilación, por lo que si planea usar comillas, nuevas líneas, etc., puede tener más suerte definiéndolo a través de bi_decl en el código.
MicroPython y CircuitPython, eventualmente el SDK y otros pueden admitir uno o más dispositivos de almacenamiento en flash. Ya tenemos macros para definirlas, aunque picotool no hace nada con ellas todavía... pero realizar copias de seguridad/restaurar/copiar archivos e incluso montar fusibles en el futuro podría ser interesante.
Sugiero que los etiquetemos ahora...
Esto es lo que tengo ahora mismo en la cabeza (en ese momento)
#define bi_block_device ( _tag , _name , _offset , _size , _extra , _flags )
con los datos entrando
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 ;
y
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
};
La ejecución de comandos con -f/F
requiere que se ejecute código compatible en el dispositivo. La definición de código compatible para propósitos de binarios compilados usando pico-sdk es código que
-f/F
no funcionará; en su lugar, puede configurar la definición de compilación PICO_ENTER_USB_BOOT_ON_EXIT
para que se reinicie y sea accesible para picotool una vez que su código haya terminado de ejecutarse, por ejemplo, con target_compile_definitions( PRIVATE PICO_ENTER_USB_BOOT_ON_EXIT=1)
stdio_init_all()
y tiene pico_enable_stdio_usb( 1)
en su archivo CMakeLists.txt, entonces cumple con este requisito (consulte el ejemplo de hello_usb). Si presiona Ctrl+c en medio de una operación larga, entonces libusb parece confundirse un poco, lo que significa que no podemos desbloquear nuestro bloqueo de escrituras MSD USB (las hemos desactivado para que el usuario no pisarse los propios pies). Simplemente ejecutar picotool info
nuevamente lo desbloqueará correctamente la próxima vez (o puede reiniciar el dispositivo).