Skip to content

Commit

Permalink
Add Serial ID device target filter
Browse files Browse the repository at this point in the history
  • Loading branch information
tomas-pecserke committed Jun 3, 2023
1 parent 0cb4473 commit 02f83f3
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 32 deletions.
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ 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>] [-f] [-F]
picotool info [-b] [-p] [-d] [-l] [-a] [--bus <bus>] [--address <addr>] [--serial <serial>] [-f] [-F]
picotool info [-b] [-p] [-d] [-l] [-a] <filename> [-t <type>]
picotool load [-n] [-N] [-u] [-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 load [-n] [-N] [-u] [-v] [-x] <filename> [-t <type>] [-o <offset>] [--bus <bus>] [--address <addr>] [--serial <serial>] [-f] [-F]
picotool save [-p] [--bus <bus>] [--address <addr>] [--serial <serial>] [-f] [-F] <filename> [-t <type>]
picotool save -a [--bus <bus>] [--address <addr>] [--serial <serial>] [-f] [-F] <filename> [-t <type>]
picotool save -r <from> <to> [--bus <bus>] [--address <addr>] [--serial <serial>] [-f] [-F] <filename> [-t <type>]
picotool verify [--bus <bus>] [--address <addr>] [--serial <serial>] [-f] [-F] <filename> [-t <type>] [-r <from> <to>] [-o <offset>]
picotool reboot [-a] [-u] [--bus <bus>] [--address <addr>] [--serial <serial>] [-f] [-F]
picotool version [-s]
picotool help [<cmd>]
Expand Down Expand Up @@ -133,6 +133,8 @@ TARGET SELECTION:
Filter devices by USB bus number
--address <addr>
Filter devices by USB device address
--serial <serial>
Filter devices by serial id
-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
Expand All @@ -145,7 +147,6 @@ TARGET SELECTION:
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.
Expand Down Expand Up @@ -241,6 +242,8 @@ OPTIONS:
Filter devices by USB bus number
--address <addr>
Filter devices by USB device address
--serial <serial>
Filter devices by serial id
-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
Expand Down
75 changes: 51 additions & 24 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <memory>
#include <functional>
#include <ctime>
#include <sstream>

#include "boot/uf2.h"
#include "picoboot_connection_cxx.h"
Expand Down Expand Up @@ -255,6 +256,7 @@ struct _settings {
uint32_t binary_start = FLASH_START;
int bus=-1;
int address=-1;
string serial;
uint32_t offset = 0;
uint32_t from = 0;
uint32_t to = 0;
Expand Down Expand Up @@ -295,12 +297,25 @@ std::shared_ptr<cmd> selected_cmd;
auto device_selection =
(
(option("--bus") & integer("bus").min_value(0).max_value(255).set(settings.bus)
.if_missing([] { return "missing bus number"; })) % "Filter devices by USB bus number" +
(option("--address") & integer("addr").min_value(1).max_value(127).set(settings.address)
.if_missing([] { return "missing address"; })) % "Filter devices by USB device address"
.if_missing([] { return "missing bus number"; }))
% "Filter devices by USB bus number"
+ (option("--address") & integer("addr").min_value(1).max_value(127).set(settings.address)
.if_missing([] { return "missing address"; }))
% "Filter devices by USB device address"
).min(0).doc_non_optional(true) +
(
(option("--serial") & value("serial").set(settings.serial)
.if_missing([] { return "missing serial id"; }))
% "Filter devices by serial id"
#if !defined(_WIN32)
+ option('f', "--force").set(settings.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" +
option('F', "--force-no-reboot").set(settings.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"
+ option('f', "--force").set(settings.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"
+ option('F', "--force-no-reboot").set(settings.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"
#endif
).min(0).doc_non_optional(true);

Expand Down Expand Up @@ -1581,28 +1596,25 @@ void info_guts(memory_access &raw_access) {
}

string missing_device_string(bool wasRetry) {
char b[256];
if (wasRetry) {
strcpy(b, "Despite the reboot attempt, no ");
} else {
strcpy(b, "No ");
std::ostringstream oss;
oss << (wasRetry ? "Despite the reboot attempt, no" : "No") << " accessible RP2040 device";
if (settings.bus != -1 && settings.serial.empty()) {
oss << 's';
}
oss << " in BOOTSEL mode";
if (!settings.serial.empty()) {
oss << " with serial ID '" << settings.serial << '\'';
}
oss << " was found";
if (settings.bus != -1) {
oss << " at bus " << settings.bus;
}
char *buf = b + strlen(b);
int buf_len = b + sizeof(b) - buf;
if (settings.address != -1) {
if (settings.bus != -1) {
snprintf(buf, buf_len, "accessible RP2040 device in BOOTSEL mode was found at bus %d, address %d.", settings.bus, settings.address);
} else {
snprintf(buf, buf_len, "accessible RP2040 devices in BOOTSEL mode were found with address %d.", settings.address);
}
} else {
if (settings.bus != -1) {
snprintf(buf, buf_len, "accessible RP2040 devices in BOOTSEL mode were found found on bus %d.", settings.bus);
} else {
snprintf(buf, buf_len,"accessible RP2040 devices in BOOTSEL mode were found.");
}
oss << (settings.bus == -1 ? " with" : ",") << " address " << settings.address;
}
return b;
oss << '.';

return oss.str();
}

bool help_command::execute(device_map &devices) {
Expand Down Expand Up @@ -2179,6 +2191,20 @@ void cancelled(int) {
throw cancelled_exception();
}

string get_usb_device_serial(libusb_device *device, libusb_device_handle *handle) {
struct libusb_device_descriptor desc{};
int ret = libusb_get_device_descriptor(device, &desc);
if (!ret) {
unsigned char data[33];
if (libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, data, 31)) {
data[32] = '\0';
return reinterpret_cast<char const*>(data);
}
}

return "";
}

int main(int argc, char **argv) {
libusb_context *ctx = nullptr;

Expand Down Expand Up @@ -2229,6 +2255,7 @@ int main(int argc, char **argv) {
if (handle) {
to_close.push_back(handle);
}
if (!settings.serial.empty() && (!handle || settings.serial != get_usb_device_serial(*dev, handle))) continue;
if (result != dr_error) {
devices[result].push_back(std::make_pair(*dev, handle));
}
Expand Down

0 comments on commit 02f83f3

Please sign in to comment.