Skip to content

Commit 3083dc8

Browse files
Add serial ID filter
1 parent 0cb4473 commit 3083dc8

File tree

1 file changed

+54
-26
lines changed

1 file changed

+54
-26
lines changed

main.cpp

Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <memory>
2626
#include <functional>
2727
#include <ctime>
28+
#include <sstream>
2829

2930
#include "boot/uf2.h"
3031
#include "picoboot_connection_cxx.h"
@@ -255,6 +256,7 @@ struct _settings {
255256
uint32_t binary_start = FLASH_START;
256257
int bus=-1;
257258
int address=-1;
259+
string serial;
258260
uint32_t offset = 0;
259261
uint32_t from = 0;
260262
uint32_t to = 0;
@@ -292,17 +294,31 @@ struct _settings {
292294
_settings settings;
293295
std::shared_ptr<cmd> selected_cmd;
294296

295-
auto device_selection =
297+
auto device_selection = (
296298
(
297299
(option("--bus") & integer("bus").min_value(0).max_value(255).set(settings.bus)
298-
.if_missing([] { return "missing bus number"; })) % "Filter devices by USB bus number" +
299-
(option("--address") & integer("addr").min_value(1).max_value(127).set(settings.address)
300-
.if_missing([] { return "missing address"; })) % "Filter devices by USB device address"
300+
.if_missing([] { return "missing bus number"; }))
301+
% "Filter devices by USB bus number"
302+
+ (option("--address") & integer("addr").min_value(1).max_value(127).set(settings.address)
303+
.if_missing([] { return "missing address"; }))
304+
% "Filter devices by USB device address"
305+
).min(0).doc_non_optional(true) +
306+
(
307+
(option("--serial") & value("serial").set(settings.serial)
308+
.if_missing([] { return "missing serial id"; }))
309+
% "Filter devices by serial id"
301310
#if !defined(_WIN32)
302-
+ 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" +
303-
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"
311+
+ option('f', "--force").set(settings.force)
312+
% "Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. "
313+
"After executing the command (unless the command itself is a 'reboot') "
314+
"the device will be rebooted back to application mode"
315+
+ option('F', "--force-no-reboot").set(settings.force_no_reboot)
316+
% "Force a device not in BOOTSEL mode but running compatible code to reset so the command can be executed. "
317+
"After executing the command (unless the command itself is a 'reboot') the device will be left connected "
318+
"and accessible to picotool, but without the RPI-RP2 drive mounted"
304319
#endif
305-
).min(0).doc_non_optional(true);
320+
).min(0).doc_non_optional(true)
321+
).min(0).doc_non_optional(true);
306322

307323
auto file_types = (option ('t', "--type") & value("type").set(settings.file_type))
308324
% "Specify file type (uf2 | elf | bin) explicitly, ignoring file extension";
@@ -1581,28 +1597,25 @@ void info_guts(memory_access &raw_access) {
15811597
}
15821598

15831599
string missing_device_string(bool wasRetry) {
1584-
char b[256];
1585-
if (wasRetry) {
1586-
strcpy(b, "Despite the reboot attempt, no ");
1587-
} else {
1588-
strcpy(b, "No ");
1600+
std::ostringstream oss;
1601+
oss << (wasRetry ? "Despite the reboot attempt, no" : "No") << " accessible RP2040 device";
1602+
if (settings.bus != -1 && settings.serial.empty()) {
1603+
oss << 's';
1604+
}
1605+
oss << " in BOOTSEL mode";
1606+
if (!settings.serial.empty()) {
1607+
oss << " with serial ID '" << settings.serial << '\'';
1608+
}
1609+
oss << " was found";
1610+
if (settings.bus != -1) {
1611+
oss << " at bus " << settings.bus;
15891612
}
1590-
char *buf = b + strlen(b);
1591-
int buf_len = b + sizeof(b) - buf;
15921613
if (settings.address != -1) {
1593-
if (settings.bus != -1) {
1594-
snprintf(buf, buf_len, "accessible RP2040 device in BOOTSEL mode was found at bus %d, address %d.", settings.bus, settings.address);
1595-
} else {
1596-
snprintf(buf, buf_len, "accessible RP2040 devices in BOOTSEL mode were found with address %d.", settings.address);
1597-
}
1598-
} else {
1599-
if (settings.bus != -1) {
1600-
snprintf(buf, buf_len, "accessible RP2040 devices in BOOTSEL mode were found found on bus %d.", settings.bus);
1601-
} else {
1602-
snprintf(buf, buf_len,"accessible RP2040 devices in BOOTSEL mode were found.");
1603-
}
1614+
oss << (settings.bus == -1 ? " with" : ",") << " address " << settings.address;
16041615
}
1605-
return b;
1616+
oss << '.';
1617+
1618+
return oss.str();
16061619
}
16071620

16081621
bool help_command::execute(device_map &devices) {
@@ -2179,6 +2192,20 @@ void cancelled(int) {
21792192
throw cancelled_exception();
21802193
}
21812194

2195+
string get_usb_device_serial(libusb_device *device, libusb_device_handle *handle) {
2196+
struct libusb_device_descriptor desc{};
2197+
int ret = libusb_get_device_descriptor(device, &desc);
2198+
if (!ret) {
2199+
unsigned char data[33];
2200+
if (libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, data, 31)) {
2201+
data[32] = '\0';
2202+
return reinterpret_cast<char const*>(data);
2203+
}
2204+
}
2205+
2206+
return "";
2207+
}
2208+
21822209
int main(int argc, char **argv) {
21832210
libusb_context *ctx = nullptr;
21842211

@@ -2229,6 +2256,7 @@ int main(int argc, char **argv) {
22292256
if (handle) {
22302257
to_close.push_back(handle);
22312258
}
2259+
if (!settings.serial.empty() && (!handle || settings.serial != get_usb_device_serial(*dev, handle))) continue;
22322260
if (result != dr_error) {
22332261
devices[result].push_back(std::make_pair(*dev, handle));
22342262
}

0 commit comments

Comments
 (0)