Skip to content

Commit

Permalink
V1.1.0 updates
Browse files Browse the repository at this point in the history
* Add version command
* Fix parsing of ELF where the program header does not directly follow the file header
* Add install-ability via `cmake install`
* Incorporate slightly modified Win32 libusb find helpers
* Add ability to access device using stdio_usb
* Add -n option to load to avoid overwriting existing program
* Add -f/-F option to force reset a cooperative RP2040 board that isnt in BOOTSEL mode
* Add a sudo suggestion when can't connect on linux/macos
  • Loading branch information
kilograham authored Nov 1, 2021
1 parent f39bdce commit 55fd880
Show file tree
Hide file tree
Showing 6 changed files with 476 additions and 165 deletions.
31 changes: 30 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.12)

project(picotool)

if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()

if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
Expand All @@ -13,6 +17,11 @@ get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMA
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()
include(${PICO_SDK_PATH}/pico_sdk_version.cmake)

if (PICO_SDK_VERSION_STRING VERSION_LESS "1.3.0")
message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.3.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
endif()

set(CMAKE_CXX_STANDARD 14)

Expand All @@ -27,9 +36,29 @@ else()
add_subdirectory(${PICO_SDK_PATH}/src/common/pico_binary_info pico_binary_info)
add_subdirectory(${PICO_SDK_PATH}/src/common/boot_uf2 boot_uf2_headers)
add_subdirectory(${PICO_SDK_PATH}/src/common/boot_picoboot boot_picoboot_headers)
add_subdirectory(${PICO_SDK_PATH}/src/common/pico_usb_reset_interface pico_usb_reset_interface)
add_subdirectory(${PICO_SDK_PATH}/src/host/pico_platform pico_platform)

add_executable(picotool main.cpp)
set(PICOTOOL_VERSION 1.1.0)
set(SYSTEM_VERSION "${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}")
set(COMPILER_INFO "${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}, ${CMAKE_BUILD_TYPE}")
target_compile_definitions(picotool PRIVATE
PICOTOOL_VERSION="${PICOTOOL_VERSION}"
SYSTEM_VERSION="${SYSTEM_VERSION}"
COMPILER_INFO="${COMPILER_INFO}"
)
target_include_directories(picotool PRIVATE ${LIBUSB_INCLUDE_DIR})
target_link_libraries(picotool pico_binary_info boot_uf2_headers boot_picoboot_headers pico_platform_headers picoboot_connection_cxx ${LIBUSB_LIBRARIES})
# todo, this is a bit of an abstraction failure; but don't want to rev the SDK just for this right now
target_include_directories(picotool PRIVATE ${PICO_SDK_PATH}/src/rp2_common/pico_stdio_usb/include)
target_link_libraries(picotool
pico_binary_info
boot_uf2_headers
boot_picoboot_headers
pico_platform_headers
pico_usb_reset_interface_headers
picoboot_connection_cxx
${LIBUSB_LIBRARIES})
# allow `make install`
install(TARGETS picotool)
endif()
81 changes: 45 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,35 +31,36 @@ nmake
```
## Overview

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

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

```text
$ picotool help
PICOTOOL:
Tool for interacting with a RP2040 device in BOOTSEL mode, or with a RP2040 binary
SYNOPSYS:
picotool info [-b] [-p] [-d] [-l] [-a] [--bus <bus>] [--address <addr>]
picotool info [-b] [-p] [-d] [-l] [-a] [--bus <bus>] [--address <addr>] [-f] [-F]
picotool info [-b] [-p] [-d] [-l] [-a] <filename> [-t <type>]
picotool load [-v] [-r] <filename> [-t <type>] [--bus <bus>] [--address <addr>]
picotool save [-p] [--bus <bus>] [--address <addr>] <filename> [-t <type>]
picotool save -a [--bus <bus>] [--address <addr>] <filename> [-t <type>]
picotool save -r <from> <to> [--bus <bus>] [--address <addr>] <filename> [-t <type>]
picotool verify [--bus <bus>] [--address <addr>] <filename> [-t <type>] [-r <from> <to>]
picotool reboot [-a] [-u] [--bus <bus>] [--address <addr>]
picotool load [-n] [-N] [-v] [-x] <filename> [-t <type>] [-o <offset>] [--bus <bus>] [--address <addr>] [-f] [-F]
picotool save [-p] [--bus <bus>] [--address <addr>] [-f] [-F] <filename> [-t <type>]
picotool save -a [--bus <bus>] [--address <addr>] [-f] [-F] <filename> [-t <type>]
picotool save -r <from> <to> [--bus <bus>] [--address <addr>] [-f] [-F] <filename> [-t <type>]
picotool verify [--bus <bus>] [--address <addr>] [-f] [-F] <filename> [-t <type>] [-r <from> <to>] [-o <offset>]
picotool reboot [-a] [-u] [--bus <bus>] [--address <addr>] [-f] [-F]
picotool version [-s]
picotool help [<cmd>]
COMMANDS:
info Display information from the target device(s) or file.
Without any arguments, this will display basic information for all connected RP2040 devices in
BOOTSEL mode
load Load the program / memory range stored in a file onto the device.
save Save the program / memory stored in flash on the device to a file.
verify Check that the device contents match those in the file.
reboot Reboot the device
help Show general help or help for a specific command
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
load Load the program / memory range stored in a file onto the device.
save Save the program / memory stored in flash on the device to a file.
verify Check that the device contents match those in the file.
reboot Reboot the device
version Display picotool version
help Show general help or help for a specific command
Use "picotool help <cmd>" for more info
```
Expand All @@ -74,15 +75,14 @@ can find (See Binary Info section below). The info command is for reading this i
The information can be either read from one or more connected RP2040 devices in BOOTSEL mode, or from
a file. This file can be an ELF, a UF2 or a BIN file.

```asciidoc
```text
$ picotool help info
INFO:
Display information from the target device(s) or file.
Without any arguments, this will display basic information for all connected RP2040 devices in USB boot
mode
Without any arguments, this will display basic information for all connected RP2040 devices in BOOTSEL mode
SYNOPSYS:
picotool info [-b] [-p] [-d] [-l] [-a] [--bus <bus>] [--address <addr>]
picotool info [-b] [-p] [-d] [-l] [-a] [--bus <bus>] [--address <addr>] [-f] [-F]
picotool info [-b] [-p] [-d] [-l] [-a] <filename> [-t <type>]
OPTIONS:
Expand All @@ -104,13 +104,23 @@ TARGET SELECTION:
Filter devices by USB bus number
--address <addr>
Filter devices by USB device address
-f, --force
Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing
the command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
-F, --force-no-reboot
Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing
the command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but
without the RPI-RP2 drive mounted
To target a file
<filename>
The file name
-t <type>
Specify file type (uf2 | elf | bin) explicitly, ignoring file extension
```

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

e.g.

```text
Expand Down Expand Up @@ -180,9 +190,9 @@ SAVE:
Save the program / memory stored in flash on the device to a file.
SYNOPSYS:
picotool save [-p] [--bus <bus>] [--address <addr>] <filename> [-t <type>]
picotool save -a [--bus <bus>] [--address <addr>] <filename> [-t <type>]
picotool save -r <from> <to> [--bus <bus>] [--address <addr>] <filename> [-t <type>]
picotool save [-p] [--bus <bus>] [--address <addr>] [-f] [-F] <filename> [-t <type>]
picotool save -a [--bus <bus>] [--address <addr>] [-f] [-F] <filename> [-t <type>]
picotool save -r <from> <to> [--bus <bus>] [--address <addr>] [-f] [-F] <filename> [-t <type>]
OPTIONS:
Selection of data to save
Expand All @@ -191,7 +201,8 @@ OPTIONS:
-a, --all
Save all of flash memory
-r, --range
Save a range of memory; note that the range is expanded to 256 byte boundaries
Save a range of memory. Note that UF2s always store complete 256 byte-aligned blocks of 256 bytes, and the range is
expanded accordingly
<from>
The lower address bound in hex
<to>
Expand All @@ -201,6 +212,13 @@ OPTIONS:
Filter devices by USB bus number
--address <addr>
Filter devices by USB device address
-f, --force
Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing
the command (unless the command itself is a 'reboot') the device will be rebooted back to application mode
-F, --force-no-reboot
Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. After executing
the command (unless the command itself is a 'reboot') the device will be left connected and accessible to picotool, but
without the RPI-RP2 drive mounted
File to save to
<filename>
The file name
Expand Down Expand Up @@ -252,11 +270,7 @@ Basic information includes
- program features - this is a list built from individual strings in the binary, that can be displayed (e.g. we will have one for UART stdio and one for USB stdio) in the SDK
- build attributes - this is a similar list of strings, for things pertaining to the binary itself (e.g. Debug Build)

Note it is my intention that things like MicroPython would include features for parts of the language/libraries they include.

This might not be as a feature string per se, but could be another aggregating list (features/attributes are well known)
but we can add another piece of binary info to name a list attribute that aggregates strings with a particular tag, so you
could trivially add "MicroPython libraries:" etc to the `picotool` output without changing the tool itself.
The binary information is self-describing/extensible, so programs can include information picotool is not aware of (e.g. MicroPython includes a list of in-built libraries)

### Pins

Expand Down Expand Up @@ -394,11 +408,6 @@ quotes, newlines etc you may have better luck defining via bi_decl in the code.

## Additional binary information/picotool features

### SDK version

Should add this; git revision in general is hard since the user may not have the SDK checked out from git, so we'll have to stick
a version number in a header

### Block devices

MicroPython and CircuitPython, eventually the SDK and others may support one or more storage devices in flash. We already
Expand Down Expand Up @@ -438,7 +447,7 @@ enum {
### USB device descriptors

Seems like tagging these might be nice (we just need to store the pointer to it assuming - as is often the case -
the descriptor is just a linear chunk of memory) ... I assume there is a tool out there to prettyify such a thing if picotool dumps the descriptor
the descriptor is just a linear chunk of memory) ... I assume there is a tool out there to prettify such a thing if picotool dumps the descriptor
in binary.

### Issues
Expand Down
6 changes: 4 additions & 2 deletions cmake/FindLIBUSB.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
pkg_check_modules(PC_LIBUSB libusb-1.0)
ENDIF(NOT WIN32)
FIND_PATH(LIBUSB_INCLUDE_DIR libusb.h
HINTS $ENV{LIBUSB_ROOT}/include/libusb-1.0
PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS})
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES usb-1.0
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb-1.0 usb-1.0 usb
HINTS $ENV{LIBUSB_ROOT}/VS2019/MS32/static
PATHS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR)
MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
Loading

0 comments on commit 55fd880

Please sign in to comment.