您需要在環境中設定 PICO_SDK_PATH ,或使用-DPICO_SDK_PATH=/path/to/pico-sdk
將其傳遞給 cmake 。要使用簽名或雜湊等功能,您需要確保 SDK 中的 mbedtls 子模組已簽出 - 這可以透過從 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 規則以便無需 sudo 即可執行 picotool:
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
來執行先前由 SDK 中的elf2uf2
工具處理的 ELF 到 UF2 轉換。 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 模式時與它們互動的工具。 (從picotool
版本 1.1 開始,也可以與未處於 BOOTSEL 模式但使用 Raspberry Pi Pico SDK 的 USB stdio 支援的裝置進行交互,方法是使用picotool
的-f
參數)。
有關其他文件的說明,請參閱 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
請注意,Windows 與 macOS / Unix 平台的 -f 參數略有不同。
例如
$ picotool info 程式資訊名稱:hello_world 功能:stdout 轉 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 功能:stdout 到 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
允許您將檔案中的資料寫入裝置(寫入快閃記憶體或 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
例如
$ picotool load blink.uf2
Loading into Flash: [==============================] 100%
save
可讓您將 RAM 範圍、快閃記憶體中的程式或快閃記憶體中的明確範圍從裝置儲存到 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 位元 AES 金鑰的 .bin 檔案形式提供,以用於加密。
$ 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 下載失敗時提供資訊。
此指令取代了 Raspberry Pi Pico SDK 中先前的 elf2uf2 功能。它將嘗試自動偵測家庭 ID,但如果失敗,您可以使用--family
參數手動指定家庭 ID。
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
指令用於與 RP2350 OTP 記憶體互動。它們在 RP2040 設備上不可用,因為 RP2040 沒有 OTP。
請注意,OTP 記憶體是一次性可編程的,這意味著一旦一位從 0 更改為 1,就無法改回原來的狀態。因此,使用這些命令時應謹慎,因為它們可能會導致 RP2350 設備變磚。例如,如果您設定了 SECURE_BOOT_ENABLE 但沒有設定啟動鍵,並停用 PICOBOOT 接口,那麼您的裝置將無法使用。
對於list
、 set
、 get
和load
指令,您可以在 JSON 檔案中定義自己的 OTP 佈局,並使用-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 白標,這會設定裝置在 BOOTSEL 模式下使用的 USB 設定。這可以從 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 權限,因為由於修復 RP2350 上的勘誤表 XXX 所需的預設權限設置,因此無法從picotool
直接存取這些權限。由於它運行二進位文件,因此如果啟用了安全啟動,則需要對二進位檔案進行簽署。二進位檔案將列印它透過 UART 執行的操作,可以使用 UART 配置參數進行配置。您可以在 json 檔案中定義 OTP 權限,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"
二進位資訊在程式中透過巨集聲明(Vile Warped Macros);對於引腳範例:
$ 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 功能,然後由 picotool 解碼為其實際功能名稱(UART1 TX 等)。 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 ));
到您的程式碼中,然後它將建立名稱變數供您隨後列印。參數包括標籤、ID、變數名稱、預設值和最大字串長度。
printf ( "Name is %sn" , name );
設計目的是浪費盡可能少的空間,但您可以使用預處理器變數PICO_NO_BINARY_INFO=1
關閉所有內容。此外,任何插入二進位資訊的 SDK 程式碼都可以透過自己的預處理器變數單獨排除。
你需要
#include "pico/binary_info.h"
基本上,您可以使用bi_decl(bi_blah(...))
無條件包含二進位資訊 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()
並且您的 CMakeLists.txt 檔案中有pico_enable_stdio_usb( 1)
那麼您就符合此要求(請參閱 hello_usb 範例)如果您在長時間操作中按 ctrl+c,那麼 libusb 似乎會有點混亂,這意味著我們無法解鎖 USB MSD 寫入的鎖定(我們已將其關閉,因此用戶無法解鎖)踩到自己的腳趾)。只需再次運行picotool info
即可在下次正確解鎖(或者您可以重新啟動裝置)。