Skip to content

Commit e72ef9d

Browse files
authored
Merge pull request #2060 from stefanrueger/bus-device
Ignore leading zeros in -P usb:<bus>:<device> numbers and improve `-P` documentation
2 parents 8a6b403 + d25eaf7 commit e72ef9d

File tree

18 files changed

+517
-418
lines changed

18 files changed

+517
-418
lines changed

src/avrdude.1

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
.Op Fl i Ar delay
4242
.Op Fl l, \-logfile Ar logfile
4343
.Op Fl n, \-test-memory
44-
.Op Fl O, \-osccal
44+
.Op Fl O, \-osccal
4545
.Op Fl P, \-port Ar port
4646
.Op Fl r, \-reconnect
4747
.Op Fl q, \-quell
@@ -607,6 +607,14 @@ or
607607
from the configuration file are used. If you need to use a different port,
608608
use this option to specify the alternate port name.
609609
.Pp
610+
USB-only programmers normally do not need the port option be specified as
611+
they are automatically identified via their vendor and product IDs from
612+
avrdude.conf or .avrduderc. Only when there are multiple programmers of
613+
the same type plugged into the host computer is the -P option needed, see
614+
below. Some -c programmers, however, ignore the -P option altogether, eg,
615+
teensy, ch341a or avrftdi; these cannot distinguish multiple plugged-in
616+
programmers.
617+
.Pp
610618
If
611619
.Nm
612620
has been configured with libserialport support, a serial port can be specified
@@ -663,20 +671,38 @@ The match is done after stripping any existing colons from the given
663671
serial number, and right-to-left, so only the least significant bytes
664672
from the serial number need to be given.
665673
.Pp
674+
avrdude -v -P usb:xyz -c jtag2 -p ... 2>&1 | grep ^Found
675+
.Pp
676+
lists all JTAG ICEs
677+
attached to USB, see the section
678+
.Em Example Command Line Invocations
679+
in the detailed pdf documentation.
680+
.Pp
666681
As the AVRISP mkII device can only be talked to over USB, the very
667682
same method of specifying the port is required there.
668683
.Pp
669-
For the USB programmer "AVR-Doper" running in HID mode, the port must
684+
For the USB programmer AVR-Doper running in HID mode, the port must
670685
be specified as
671686
.Ar avrdoper.
672687
Libhidapi support is required on Unix and Mac OS but not on Windows. For more
673688
information about AVR-Doper see https://www.obdev.at/products/vusb/avrdoper.html.
674689
.Pp
675-
For the USBtinyISP, which is a simplistic device not implementing
676-
serial numbers, multiple devices can be distinguished by their
677-
location in the USB hierarchy. See the respective
690+
For the USBtinyISP, which is a simplistic device not implementing serial
691+
numbers, multiple devices can be distinguished by their location in the
692+
USB hierarchy using -P usb:<busdir>:<devicefile>.
693+
.Pp
694+
For USBasp, multiple devices can also be also distinguished using -P
695+
usb:<busdir>:<devicefile> or using the serial number -P usb:<serialno>.
696+
For examples, see the respective
678697
.Em Troubleshooting
679-
entry in the detailed documentation for examples.
698+
entry in the detailed pdf documentation.
699+
.Pp
700+
The -c pickit5 programmer allows overriding the product ID with a
701+
hexadecimal number <pid> using -P usb::<pid> and the vendor and product
702+
IDs with hexadecimal numbers <vid> and <pid> using -P usb:<vid>:<pid>. The
703+
form -P usb:<serialno> requests AVRDUDE select the PICkit5 programmer with
704+
a serial number that ends in <serialno> (and with vid/pid from the
705+
configuration files).
680706
.Pp
681707
For the XBee programmer the target MCU is to be programmed wirelessly over a
682708
ZigBee mesh using the XBeeBoot bootloader. The ZigBee 64-bit address for the
@@ -968,10 +994,13 @@ The
968994
.Ar addr
969995
and
970996
.Ar len
971-
parameters of the dump, read, disasm, write, save and erase commands can be
972-
negative with the same syntax as substring computations in perl or python.
973-
The table below details their meaning with respect to an example memory of size
974-
sz=0x800 (2048 bytes).
997+
parameters of the dump, read, disasm, write, save and erase commands can
998+
be negative with the same syntax as substring computations in perl or
999+
python. The table below defines the effective memory interval
1000+
.Ar [start ,
1001+
.Ar end],
1002+
given the memory size
1003+
.Ar sz :
9751004
.Pp
9761005
.nf
9771006
addr len Memory interval Comment
@@ -982,13 +1011,31 @@ addr len Memory interval Comment
9821011
sz+addr+len-1]
9831012
neg neg [sz+addr, sz+len] Combining above two cases
9841013
any 0 empty set No action
1014+
.fi
1015+
.Pp
1016+
Note that addr must be in the range [-sz, sz-1]. After computing the memory interval
1017+
[start, end] as per above table, the effective length end-start + 1 must not be negative; if
1018+
the effective length is zero then no action is carried out. End may be beyond the available
1019+
memory for the dump, read or disasm commands, in which case the operation wraps around
1020+
the memory end, but the effective length is always limited to the memory size.
1021+
.Pp
1022+
Here some examples for a memory with size sz of 0x800 (2048) bytes:
1023+
.Pp
1024+
.nf
1025+
addr len Memory interval Comment
1026+
------------------------------------------------------------------------
9851027
0x700 12 [0x700, 0x70b] Conventional use
9861028
1024 -257 [0x400, 0x6ff] Size of memory is 2048 or 0x800
9871029
-512 512 [0x600, 0x7ff] Last 512 bytes
9881030
-256 -1 [0x700, 0x7ff] Last 256 bytes
9891031
0 49 [0, 48] First 49 bytes
9901032
0 -49 [0, 1999] All but the last 48 = |len+1| bytes
9911033
0 -1 [0, 0x7ff] All memory without knowing its size
1034+
2046 4 [0x7fe, 0x801] Wrap around for read but error for write
1035+
2046 4096 [0x7fe, 0x17fe] Read wrap around stops at 0x7fd
1036+
-1 -1 [0x7ff, 0x7ff] One byte at 0x7ff is addressed
1037+
-1 -2 [0x7ff, 0x7fe] No action: effective length is zero
1038+
-1 -3 [0x7ff, 0x7fd] Error: effective length is negative
9921039
.fi
9931040
.Pp
9941041
The following commands are implemented for all programmers:
@@ -1639,7 +1686,7 @@ to the target. If there is already a valid voltage applied to the VTG Pin,
16391686
this setting will be ignored. When AVRDUDE detects an external voltage outside
16401687
of this range, it will terminate the operation. You can disable this check by
16411688
setting the voltage to 0 V. If an XMEGA part was selected, a requested voltage
1642-
above 3.49 V will lead to an abort of operation.
1689+
above 3.49 V will lead to an abort of operation.
16431690
.It Ar hvupdi
16441691
High-voltage UPDI programming is used to enable a UPDI pin that has previously
16451692
been set to RESET or GPIO mode. Use -x hvupdi to enable high-voltage UPDI

src/avrftdi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,10 @@ static int avrftdi_open(PROGRAMMER *pgm, const char *port) {
641641

642642
Avrftdi_data *pdata = to_pdata(pgm);
643643

644+
pmsg_debug("%s(\"%s\")\n", __func__, port);
645+
if(!str_eq(port, "usb"))
646+
pmsg_warning("option -P %s ignored\n", port);
647+
644648
// Parameter validation
645649

646650
// Use vid/pid in following priority: config, defaults cmd-line is currently not supported

src/ch341a.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,9 @@ static int ch341a_open(PROGRAMMER *pgm, const char *port) {
201201
int errorCode = USB_ERROR_NOTFOUND;
202202
libusb_device_handle *handle = NULL;
203203

204-
pmsg_trace("ch341a_open(\"%s\")\n", port);
204+
pmsg_debug("%s(\"%s\")\n", __func__, port);
205+
if(!str_eq(port, "usb"))
206+
pmsg_warning("option -P %s ignored\n", port);
205207

206208
if(!my.USB_init) {
207209
my.USB_init = 1;

src/dfu.c

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -92,25 +92,26 @@ static char *get_usb_string(usb_dev_handle *dev_handle, int index);
9292

9393
struct dfu_dev *dfu_open(const char *port_spec) {
9494
struct dfu_dev *dfu;
95-
char *bus_name = NULL;
96-
char *dev_name = NULL;
95+
char *bus_name = NULL, *dev_name = NULL;
9796

98-
/* The following USB device spec parsing code was copied from usbtiny.c. The
99-
* expected format is "usb:BUS:DEV" where BUS and DEV are the bus and device
100-
* names. We stash these away in the dfu_dev structure for the dfu_init()
101-
* function, where we actually open the device.
97+
/*
98+
* The following USB device spec parsing code was copied from usbtiny.c.
99+
* The expected format is "usb:<busdir>:<devicefile>". We stash these
100+
* away in the dfu_dev structure for the dfu_init() function, where we
101+
* actually open the device.
102102
*/
103103

104-
if(!str_starts(port_spec, "usb")) {
105-
pmsg_error("invalid port specification %s for USB device\n", port_spec);
104+
pmsg_debug("%s(\"%s\")\n", __func__, port_spec);
105+
106+
if(!str_starts(port_spec, "usb:") && !str_eq(port_spec, "usb")) {
107+
pmsg_error("invalid -P %s; drop this option or use -P usb:<busdir>:<devicefile>\n", port_spec);
106108
return NULL;
107109
}
108110

109111
if(':' == port_spec[3]) {
110112
bus_name = mmt_strdup(port_spec + 3 + 1);
111113

112-
dev_name = strchr(bus_name, ':');
113-
if(NULL != dev_name)
114+
if((dev_name = strchr(bus_name, ':')))
114115
*dev_name++ = '\0';
115116
}
116117

@@ -138,17 +139,19 @@ int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) {
138139
struct usb_device *dev;
139140
struct usb_bus *bus;
140141

141-
/* At last, we reach out through the USB bus to the part. There are three
142-
* ways to specify the part: by USB address, by USB vendor and product id,
143-
* and by part name. To specify the part by USB address, the user specifies
144-
* a port parameter in the form "usb:BUS:DEV" (see dfu_open()). To specify
145-
* the part by vendor and product, the user must specify a usbvid and usbpid
146-
* in the configuration file. Finally, if the user specifies the part only,
147-
* we use the default vendor and product id.
142+
/*
143+
* At last, we reach out through the USB bus to the part. There are
144+
* three ways to specify the part: by USB address, by USB vendor and
145+
* product id, and by part name. To specify the part by USB address, the
146+
* user specifies a port parameter in the form usb:<busdir>:<devicefile>
147+
* (see dfu_open()). To specify the part by vendor and product, the user
148+
* must specify a usbvid and usbpid in the configuration file. Finally,
149+
* if the user specifies the part only, we use the default vendor and
150+
* product id.
148151
*/
149152

150153
if(pid == 0 && dfu->dev_name == NULL) {
151-
pmsg_error("no DFU support for part; specify PID in config or USB address (via -P) to override\n");
154+
pmsg_error("no DFU support for part; specify <pid> in config or USB address via -P usb:<busdir>:<devicefile>\n");
152155
return -1;
153156
}
154157

@@ -164,10 +167,14 @@ int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) {
164167

165168
for(bus = usb_busses; !found && bus != NULL; bus = bus->next) {
166169
for(dev = bus->devices; !found && dev != NULL; dev = dev->next) {
167-
if(dfu->bus_name != NULL && !str_eq(bus->dirname, dfu->bus_name))
170+
if(vid == dev->descriptor.idVendor && pid == dev->descriptor.idProduct)
171+
pmsg_notice("found device with vendorID=0x%04x and productID=0x%04x, busdir:devicefile = %s:%s\n",
172+
vid, pid, bus->dirname, dev->filename);
173+
174+
if(dfu->bus_name && !str_busdev_eq(bus->dirname, dfu->bus_name))
168175
continue;
169-
if(dfu->dev_name != NULL) {
170-
if(!str_eq(dev->filename, dfu->dev_name))
176+
if(dfu->dev_name) {
177+
if(!str_busdev_eq(dev->filename, dfu->dev_name))
171178
continue;
172179
} else if(vid != dev->descriptor.idVendor)
173180
continue;
@@ -187,7 +194,7 @@ int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) {
187194
return -1;
188195
}
189196

190-
pmsg_notice2("found VID=0x%04x PID=0x%04x at %s:%s\n",
197+
pmsg_notice2("using VID=0x%04x PID=0x%04x at %s:%s\n",
191198
found->descriptor.idVendor, found->descriptor.idProduct, found->bus->dirname, found->filename);
192199

193200
dfu->dev_handle = usb_open(found);
@@ -223,14 +230,10 @@ int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) {
223230
void dfu_close(struct dfu_dev *dfu) {
224231
if(dfu->dev_handle != NULL)
225232
usb_close(dfu->dev_handle);
226-
if(dfu->bus_name != NULL)
227-
mmt_free(dfu->bus_name);
228-
if(dfu->manf_str != NULL)
229-
mmt_free(dfu->manf_str);
230-
if(dfu->prod_str != NULL)
231-
mmt_free(dfu->prod_str);
232-
if(dfu->serno_str != NULL)
233-
mmt_free(dfu->serno_str);
233+
mmt_free(dfu->bus_name);
234+
mmt_free(dfu->manf_str);
235+
mmt_free(dfu->prod_str);
236+
mmt_free(dfu->serno_str);
234237
}
235238

236239
int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status) {

0 commit comments

Comments
 (0)