Вам необходимо установить PICO_SDK_PATH в среде или передать его в cmake с помощью -DPICO_SDK_PATH=/path/to/pico-sdk
. Чтобы использовать такие функции, как подпись или хеширование, вам необходимо убедиться, что подмодуль mbedtls в SDK извлечен — это можно сделать, запустив его из каталога SDK.
git submodule update --init lib/mbedtls
Вам также необходимо установить libusb-1.0
.
Используйте свой любимый пакетный инструмент для установки зависимостей. Например, в Ubuntu:
sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake
Затем просто создайте как обычный проект CMake:
mkdir build
cd build
cmake ..
make
В Linux вы можете добавить правила udev, чтобы запускать picotool без sudo:
sudo cp udev/99-picotool.rules /etc/udev/rules.d/
Загрузите libUSB отсюда https://libusb.info/
установите переменную среды LIBUSB_ROOT в каталог установки.
mkdir build
cd build
cmake -G "NMake Makefiles" ..
nmake
Загрузите libUSB отсюда https://libusb.info/
установите переменную среды LIBUSB_ROOT в каталог установки.
mkdir build
cd build
cmake ..
make
Нет необходимости загружать libusb отдельно или устанавливать LIBUSB_ROOT
.
pacman -S $MINGW_PACKAGE_PREFIX-{toolchain,cmake,libusb}
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX
cmake --build .
В Raspberry Pi Pico SDK (pico-sdk) версии 2.0.0 и выше используется picotool
для преобразования ELF в UF2, которое ранее выполнялось инструментом elf2uf2
в SDK. SDK также использует picotool
для хеширования и подписания двоичных файлов.
Хотя SDK может загружать picotool отдельно для каждого проекта, если у вас несколько проектов или конфигураций сборки, предпочтительнее установить одну копию picotool
локально. Проще всего это можно сделать с помощью make install
или cmake --install .
; SDK будет использовать эту установленную версию по умолчанию.
Кроме того, вы можете установить по собственному пути через:
cmake -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR -DPICOTOOL_FLAT_INSTALL=1 ..
Чтобы SDK мог найти picotool
по этому пользовательскому пути, вам необходимо установить переменную picotool_DIR
в вашем проекте, установив переменную среды picotool_DIR
, передав -Dpicotool_DIR=$MY_INSTALL_DIR/picotool
в команду cmake
или добавив set(picotool_DIR $MY_INSTALL_DIR/picotool)
в ваш файл CMakeLists.txt.
picotool
— это инструмент для работы с двоичными файлами RP2040/RP2350 и взаимодействия с устройствами RP2040/RP2350, когда они находятся в режиме BOOTSEL. (Начиная с версии 1.1 picotool
также можно взаимодействовать с устройствами, которые не находятся в режиме BOOTSEL, но используют поддержку USB stdio из Raspberry Pi Pico SDK, используя аргумент -f
picotool
).
Примечание: дополнительную документацию см. 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
Обратите внимание, что команды, которые не действуют на файлы, требуют подключения устройства в режиме BOOTSEL.
Поддержка двоичной информации в SDK позволяет легко хранить компактную информацию, которую может найти picotool
(см. раздел «Двоичная информация» ниже). Команда info предназначена для чтения этой информации.
Информацию можно считать либо с одного или нескольких подключенных устройств в режиме BOOTSEL, либо из файла. Этот файл может быть в формате ELF, UF2 или 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
Обратите внимание, что аргументы -f немного различаются для платформ Windows и macOS/Unix.
например
$ picotool info Имя информации о программе: hello_world функции: стандартный вывод в 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 Имя информации о программе: hello_world функции: стандартный вывод в UART
Информация о фиксированном контакте 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 позволяет вам настроить двоичную информацию на устройстве, если ее можно настроить. В частности, вы можете настроить bi_ptr_int32
и 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
позволяет записать данные из файла на устройство (либо запись во флэш, либо в оперативную память)
$ 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
например
$ picotool load blink.uf2
Loading into Flash: [==============================] 100%
save
позволяет сохранить диапазон оперативной памяти, программу во флэш-памяти или явный диапазон флэш-памяти устройства в файл BIN или файл 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
например, сначала посмотрим, что находится на устройстве...
$ picotool info
Program Information
name: lcd_1602_i2c
web site: https://github.com/raspberrypi/pico-examples/tree/HEAD/i2c/lcd_1602_i2c
...сохраняю в файл...
$ picotool save spoon.uf2
Saving file: [==============================] 100%
Wrote 51200 bytes to spoon.uf2
... и просматривая файл:
$ 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
позволяет вам подписывать и/или хешировать двоичный файл для запуска на RP2350.
По умолчанию он просто подписывает двоичный файл, но это можно настроить с помощью аргументов --hash
и --no-sign
.
Ваш ключ подписи должен быть для кривой secp256k1 в формате PEM. Вы можете создать файл .PEM с помощью:
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
позволяет зашифровать и подписать двоичный файл для использования на RP2350. По умолчанию он подпишет зашифрованный двоичный файл, но это можно настроить аналогично picotool sign
.
Зашифрованный двоичный файл будет иметь следующую структуру:
Ключ AES должен быть предоставлен в виде 256-битного файла .bin с ключом AES, который будет использоваться для шифрования.
$ 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
Команды partition
позволяют взаимодействовать с таблицами разделов на устройствах RP2350, а также создавать их.
$ 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
Эта команда позволяет создавать таблицы разделов, а также дополнительно встраивать их в цикл блоков ELF-файлов (например, для загрузчиков). По умолчанию все таблицы разделов хешируются, и вы также можете их подписать.
$ 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)
Команды uf2
позволяют создавать UF2, а cam предоставляет информацию в случае сбоя загрузки UF2.
Эта команда заменяет функциональность elf2uf2, которая ранее была в Raspberry Pi Pico SDK. Он попытается автоматически определить идентификатор семейства, но если это не удастся, вы можете указать его вручную с помощью аргумента --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)
Эта команда считывает с устройства информацию о том, почему загрузка UF2 не удалась. Он предоставит информацию только в том случае, если последняя загрузка не удалась.
$ 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
Команды otp
предназначены для взаимодействия с памятью OTP RP2350. Они недоступны на устройствах RP2040, поскольку RP2040 не имеет OTP.
Обратите внимание, что память OTP является однократно программируемой, что означает, что после изменения бита с 0 на 1 его невозможно изменить обратно. Поэтому следует соблюдать осторожность при использовании этих команд, поскольку они могут привести к блокировке вашего устройства RP2350. Например, если вы установите SECURE_BOOT_ENABLE, но не зададите ключ загрузки и отключите интерфейс PICOBOOT, ваше устройство станет непригодным для использования.
Для команд list
, set
, get
и load
вы можете определить свой собственный макет OTP в файле JSON и передать его с аргументом -i
. Эти строки будут добавлены к строкам по умолчанию при анализе.
$ 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)
Эти команды будут устанавливать/получать определенные строки OTP. По умолчанию они будут записывать/читать все избыточные строки, но это можно переопределить с помощью аргумента -c
Эта команда позволяет загрузить на устройство диапазон строк OTP. Источником может быть двоичный файл или файл JSON, например файл, выводимый picotool sign
. Например, если вы хотите подписать двоичный файл, а затем протестировать с его помощью безопасную загрузку, вы можете запустить следующий набор команд:
$ 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
Эта команда позволяет использовать белую метку OTP, которая устанавливает конфигурацию USB, используемую устройством, в режим BOOTSEL. Это можно настроить из файла JSON, пример которого находится в 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
...
Эта команда запустит двоичный файл на вашем устройстве, чтобы установить разрешения OTP, поскольку они недоступны напрямую из picotool
из-за настроек разрешений по умолчанию, необходимых для исправления ошибки XXX на RP2350. Поскольку он запускает двоичный файл, его необходимо подписать, если включена безопасная загрузка. Двоичный файл будет печатать то, что он делает, через uart, который можно настроить с помощью аргументов конфигурации UART. Вы можете определить свои разрешения OTP в файле JSON, пример которого находится в файле 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.
Двоичная информация может быть обнаружена машиной и, как правило, потребляется машиной. Я говорю «в общем», потому что любой может включить любую информацию, и мы можем отличить ее от нашей, но от них зависит, сделают ли они свои данные самоописывающими.
Обратите внимание, что со временем мы обязательно добавим больше двоичной информации, но я бы хотел, чтобы минимальный базовый набор был включен в большинство двоичных файлов с момента запуска!
Эта информация очень полезна, когда вы берете в руки Pico и не знаете, что на нем!
Основная информация включает в себя
Двоичная информация является самоописываемой/расширяемой, поэтому программы могут включать информацию, о которой picotool не знает (например, MicroPython включает список встроенных библиотек).
Это, безусловно, удобно, когда у вас есть исполняемый файл hello_world.elf, но вы забыли, для какой доски он создан...
Статические (фиксированные) назначения выводов можно записать в двоичном виде в очень компактной форме:
$ 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
Это очень удобно, если вы хотите иметь возможность изменять параметры в двоичном файле без необходимости его перекомпиляции.
$ picotool config -s name Jane
name = "Billy"
setting name -> "Jane"
Двоичная информация объявляется в программе макросами (мерзкими искажёнными макросами); для примера булавок:
$ 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
... в функции 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 ));
Два номера контактов и функция UART сохраняются, а затем декодируются в их фактические имена функций (UART1 TX и т. д.) с помощью picotool. bi_decl_if_func_used
гарантирует, что двоичная информация будет включена только в том случае, если вызывается содержащая функция.
Аналогично, видеокод содержит несколько таких строк:
bi_decl_if_func_used ( bi_pin_mask_with_name ( 0x1f << ( PICO_SCANVIDEO_COLOR_PIN_BASE + PICO_SCANVIDEO_DPI_PIXEL_RSHIFT ), "Red 0-4" ));
Для примера конфигурации вы помещаете строку
bi_decl ( bi_ptr_string ( 0x1111 , 0x3333 , name , "Billy" , 128 ));
в ваш код, который затем создаст переменную имени, которую вы сможете впоследствии распечатать. Параметрами являются тег, идентификатор, имя переменной, значение по умолчанию и максимальная длина строки.
printf ( "Name is %sn" , name );
Все спроектировано так, чтобы тратить как можно меньше места, но вы можете отключить все с помощью переменной препроцессора PICO_NO_BINARY_INFO=1
. Кроме того, любой код SDK, вставляющий двоичную информацию, можно отдельно исключить с помощью собственной переменной препроцессора.
Вам нужно
#include "pico/binary_info.h"
По сути, вы либо используете bi_decl(bi_blah(...))
для безусловного включения двоичной информации, либо bi_decl_if_func_used(bi_blah(...))
для двоичной информации, которая может быть удалена, если охватывающая функция не включена в двоичный файл с помощью компоновщик (например, --gc-sections
)
В шапках куча макросов bi_
#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 ) ...
которые используют базовые макросы, например
#define bi_program_url ( url ) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_URL, url)
ПРИМЕЧАНИЕ. Легко забыть заключить их в bi_decl
и т. д., поэтому была предпринята попытка (за счет большого количества котят) сделать сборку неудачной с несколько полезным сообщением об ошибке, если вы это сделаете.
Например, пытаясь скомпилировать
bi_1pin_with_name ( 0 , "Toaster activator" );
дает
/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
Вы можете использовать
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" )
Обратите внимание, что все они передаются в качестве аргументов командной строки при компиляции, поэтому, если вы планируете использовать кавычки, символы новой строки и т. д., возможно, вам больше повезет, определив их через bi_decl в коде.
MicroPython и CircuitPython, в конечном итоге SDK и другие могут поддерживать одно или несколько флэш-устройств хранения данных. У нас уже есть макросы для их определения, хотя picotool пока ничего с ними не делает... но резервное копирование/восстановление/копирование файлов и даже монтирование предохранителей в будущем могут быть интересными.
Предлагаю отметить их сейчас...
Вот что у меня сейчас пришло в голову (на тот момент)
#define bi_block_device ( _tag , _name , _offset , _size , _extra , _flags )
с данными, поступающими в
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 ;
и
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
};
Для запуска команд с -f/F
на устройстве должен быть запущен совместимый код. Определение совместимого кода для двоичных файлов, скомпилированных с использованием pico-sdk, — это код, который
-f/F
не будет работать. Вместо этого вы можете установить определение компиляции PICO_ENTER_USB_BOOT_ON_EXIT
для перезагрузки и быть доступным для picotool после завершения выполнения вашего кода, например, с помощью target_compile_definitions( PRIVATE PICO_ENTER_USB_BOOT_ON_EXIT=1)
stdio_init_all()
и у вас есть pico_enable_stdio_usb( 1)
в файле CMakeLists.txt, то вы соответствуете этому требованию (см. пример hello_usb). Если вы нажмете Ctrl+C в середине длительной операции, то libusb, похоже, немного запутается, а это означает, что мы не сможем разблокировать блокировку записи USB MSD (мы отключили ее, чтобы пользователь не мог наступить себе на ногу). Простой повторный запуск picotool info
разблокирует его правильно в следующий раз (или вы можете перезагрузить устройство).