Added support for multiple instances of USB devices.
This commit is contained in:
parent
8503cc4a85
commit
4824ab7750
3
Makefile
3
Makefile
|
@ -45,7 +45,8 @@ install: mspdebug mspdebug.man
|
|||
|
||||
mspdebug: main.o fet.o rf2500.o dis.o uif.o olimex.o ihex.o elf32.o stab.o \
|
||||
util.o bsl.o sim.o symmap.o gdb.o btree.o rtools.o sym.o devcmd.o \
|
||||
cproc.o vector.o cproc_util.o expr.o fet_error.o binfile.o fet_db.o
|
||||
cproc.o vector.o cproc_util.o expr.o fet_error.o binfile.o fet_db.o \
|
||||
usbutil.o
|
||||
$(CC) $(LDFLAGS) -o $@ $^ -lusb $(READLINE_LIBS)
|
||||
|
||||
.c.o:
|
||||
|
|
32
main.c
32
main.c
|
@ -29,6 +29,7 @@
|
|||
#include "binfile.h"
|
||||
#include "stab.h"
|
||||
#include "util.h"
|
||||
#include "usbutil.h"
|
||||
#include "gdb.h"
|
||||
#include "rtools.h"
|
||||
#include "sym.h"
|
||||
|
@ -121,6 +122,7 @@ static void store_io(void *user_data, uint16_t pc,
|
|||
struct cmdline_args {
|
||||
const char *driver_name;
|
||||
const char *serial_device;
|
||||
const char *usb_device;
|
||||
const char *fet_force_id;
|
||||
int want_jtag;
|
||||
int no_rc;
|
||||
|
@ -160,7 +162,7 @@ static device_t driver_open_rf2500(const struct cmdline_args *args)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
trans = rf2500_open();
|
||||
trans = rf2500_open(args->usb_device);
|
||||
if (!trans)
|
||||
return NULL;
|
||||
|
||||
|
@ -174,7 +176,7 @@ static device_t driver_open_olimex(const struct cmdline_args *args)
|
|||
if (args->serial_device)
|
||||
trans = uif_open(args->serial_device, 1);
|
||||
else
|
||||
trans = olimex_open();
|
||||
trans = olimex_open(args->usb_device);
|
||||
|
||||
if (!trans)
|
||||
return NULL;
|
||||
|
@ -252,6 +254,8 @@ static void usage(const char *progname)
|
|||
"\n"
|
||||
" -d device\n"
|
||||
" Connect via the given tty device, rather than USB.\n"
|
||||
" -U bus:dev\n"
|
||||
" Specify a particular USB device to connect to.\n"
|
||||
" -j\n"
|
||||
" Use JTAG, rather than Spy-Bi-Wire (UIF devices only).\n"
|
||||
" -v voltage\n"
|
||||
|
@ -264,9 +268,11 @@ static void usage(const char *progname)
|
|||
" Show a list of devices supported by the FET driver.\n"
|
||||
" --fet-force-id string\n"
|
||||
" Override the device ID returned by the FET.\n"
|
||||
" --usb-list\n"
|
||||
" Show a list of available USB devices.\n"
|
||||
"\n"
|
||||
"Most drivers connect by default via USB, unless told otherwise via the\n"
|
||||
"-d option.\n"
|
||||
"-d option. By default, the first USB device found is opened.\n"
|
||||
"\n"
|
||||
"If commands are given, they will be executed. Otherwise, an interactive\n"
|
||||
"command reader is started.\n\n",
|
||||
|
@ -335,16 +341,28 @@ static int parse_cmdline_args(int argc, char **argv,
|
|||
{"help", 0, 0, 'H'},
|
||||
{"fet-list", 0, 0, 'L'},
|
||||
{"fet-force-id", 1, 0, 'F'},
|
||||
{"usb-list", 0, 0, 'I'},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "d:jv:n",
|
||||
while ((opt = getopt_long(argc, argv, "d:jv:nU:",
|
||||
longopts, NULL)) >= 0)
|
||||
switch (opt) {
|
||||
case 'I':
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
usbutil_list();
|
||||
exit(0);
|
||||
|
||||
case 'd':
|
||||
args->serial_device = optarg;
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
args->usb_device = optarg;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
exit(list_devices());
|
||||
|
||||
|
@ -373,6 +391,12 @@ static int parse_cmdline_args(int argc, char **argv,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (args->usb_device && args->serial_device) {
|
||||
fprintf(stderr, "You can't simultaneously specify a serial and "
|
||||
"a USB device.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (optind >= argc) {
|
||||
fprintf(stderr, "You need to specify a driver. Try --help for "
|
||||
"a list.\n");
|
||||
|
|
|
@ -40,6 +40,9 @@ option only works on FET430UIF devices.
|
|||
Specify that the driver should connect via a tty device rather than USB.
|
||||
The supported connection methods vary depending on the driver. See the
|
||||
section \fBDRIVERS\fR below for details.
|
||||
.IP "\-U \fIbus\fR:\fIdevice\fR"
|
||||
Specify a particular USB device to connect to. Without this option,
|
||||
the first device of the appropriate type is opened.
|
||||
.IP "\-n"
|
||||
Do not process the startup file (~/.mspdebug).
|
||||
.IP "\-\-help"
|
||||
|
@ -51,6 +54,8 @@ for \fB\-R\fR and \fB\-u\fR operating modes).
|
|||
When using a FET device, force the connected chip to be recognised by
|
||||
MSPDebug as one of the given type during initialization. This overrides
|
||||
the device ID returned by the FET.
|
||||
.IP "\-\-usb\-list"
|
||||
List available USB devices and exit.
|
||||
.SH DRIVERS
|
||||
A driver name must be specified on the command line for MSPDebug to
|
||||
connect to. Valid driver names are listed here.
|
||||
|
|
43
olimex.c
43
olimex.c
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "olimex.h"
|
||||
#include "util.h"
|
||||
#include "usbutil.h"
|
||||
|
||||
struct olimex_transport {
|
||||
struct transport base;
|
||||
|
@ -190,10 +191,11 @@ static void usbtr_destroy(transport_t tr_base)
|
|||
free(tr);
|
||||
}
|
||||
|
||||
transport_t olimex_open(void)
|
||||
transport_t olimex_open(const char *devpath)
|
||||
{
|
||||
struct olimex_transport *tr = malloc(sizeof(*tr));
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
char buf[64];
|
||||
|
||||
if (!tr) {
|
||||
perror(__FILE__": can't allocate memory");
|
||||
|
@ -208,26 +210,25 @@ transport_t olimex_open(void)
|
|||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||
struct usb_device *dev;
|
||||
if (devpath)
|
||||
dev = usbutil_find_by_loc(devpath);
|
||||
else
|
||||
dev = usbutil_find_by_id(USB_FET_VENDOR, USB_FET_PRODUCT);
|
||||
|
||||
for (dev = bus->devices; dev; dev = dev->next) {
|
||||
if (dev->descriptor.idVendor == USB_FET_VENDOR &&
|
||||
dev->descriptor.idProduct == USB_FET_PRODUCT &&
|
||||
!open_device(tr, dev)) {
|
||||
char buf[64];
|
||||
|
||||
/* Flush out lingering data */
|
||||
while (usb_bulk_read(tr->handle, USB_FET_IN_EP,
|
||||
buf, sizeof(buf),
|
||||
100) >= 0);
|
||||
|
||||
return (transport_t)tr;
|
||||
}
|
||||
}
|
||||
if (!dev) {
|
||||
free(tr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fprintf(stderr, __FILE__": no devices could be found\n");
|
||||
free(tr);
|
||||
return NULL;
|
||||
if (open_device(tr, dev) < 0) {
|
||||
fprintf(stderr, __FILE__ ": failed to open Olimex device\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Flush out lingering data */
|
||||
while (usb_bulk_read(tr->handle, USB_FET_IN_EP,
|
||||
buf, sizeof(buf),
|
||||
100) >= 0);
|
||||
|
||||
return (transport_t)tr;
|
||||
}
|
||||
|
|
4
olimex.h
4
olimex.h
|
@ -25,7 +25,9 @@
|
|||
/* Search the USB bus for the first Olimex MSP-JTAG-TINY, and
|
||||
* initialize it. If successful, 0 is returned and the fet_* functions
|
||||
* are ready for use. If an error occurs, -1 is returned.
|
||||
*
|
||||
* A particular USB device may be specified in bus:dev form.
|
||||
*/
|
||||
transport_t olimex_open(void);
|
||||
transport_t olimex_open(const char *usb_device);
|
||||
|
||||
#endif
|
||||
|
|
43
rf2500.c
43
rf2500.c
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "rf2500.h"
|
||||
#include "util.h"
|
||||
#include "usbutil.h"
|
||||
|
||||
struct rf2500_transport {
|
||||
struct transport base;
|
||||
|
@ -177,10 +178,11 @@ static void usbtr_destroy(transport_t tr_base)
|
|||
free(tr);
|
||||
}
|
||||
|
||||
transport_t rf2500_open(void)
|
||||
transport_t rf2500_open(const char *devpath)
|
||||
{
|
||||
struct rf2500_transport *tr = malloc(sizeof(*tr));
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
char buf[64];
|
||||
|
||||
if (!tr) {
|
||||
perror("rf2500: can't allocate memory");
|
||||
|
@ -195,26 +197,25 @@ transport_t rf2500_open(void)
|
|||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||
struct usb_device *dev;
|
||||
if (devpath)
|
||||
dev = usbutil_find_by_loc(devpath);
|
||||
else
|
||||
dev = usbutil_find_by_id(USB_FET_VENDOR, USB_FET_PRODUCT);
|
||||
|
||||
for (dev = bus->devices; dev; dev = dev->next) {
|
||||
if (dev->descriptor.idVendor == USB_FET_VENDOR &&
|
||||
dev->descriptor.idProduct == USB_FET_PRODUCT &&
|
||||
!open_device(tr, dev)) {
|
||||
char buf[64];
|
||||
|
||||
/* Flush out lingering data */
|
||||
while (usb_bulk_read(tr->handle, USB_FET_IN_EP,
|
||||
buf, sizeof(buf),
|
||||
100) >= 0);
|
||||
|
||||
return (transport_t)tr;
|
||||
}
|
||||
}
|
||||
if (!dev) {
|
||||
free(tr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fprintf(stderr, "rf2500: no devices could be found\n");
|
||||
free(tr);
|
||||
return NULL;
|
||||
if (open_device(tr, dev) < 0) {
|
||||
fprintf(stderr, "rf2500: failed to open RF2500 device\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Flush out lingering data */
|
||||
while (usb_bulk_read(tr->handle, USB_FET_IN_EP,
|
||||
buf, sizeof(buf),
|
||||
100) >= 0);
|
||||
|
||||
return (transport_t)tr;
|
||||
}
|
||||
|
|
4
rf2500.h
4
rf2500.h
|
@ -24,7 +24,9 @@
|
|||
/* Search the USB bus for the first eZ430-RF2500, and initialize it. If
|
||||
* successful, 0 is returned and the fet_* functions are ready for use.
|
||||
* If an error occurs, -1 is returned.
|
||||
*
|
||||
* A particular device may be specified in bus:dev form.
|
||||
*/
|
||||
transport_t rf2500_open(void);
|
||||
transport_t rf2500_open(const char *dev_path);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/* MSPDebug - debugging tool for MSP430 MCUs
|
||||
* Copyright (C) 2009, 2010 Daniel Beer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "usbutil.h"
|
||||
#include "util.h"
|
||||
|
||||
static const char *device_help(const struct usb_device *dev)
|
||||
{
|
||||
static const struct {
|
||||
int vendor;
|
||||
int product;
|
||||
const char *help;
|
||||
} info[] = {
|
||||
{0x0451, 0xf432, "eZ430-RF2500"},
|
||||
{0x15ba, 0x0002, "Olimex MSP-JTAG-TINY"}
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(info); i++)
|
||||
if (dev->descriptor.idProduct == info[i].product &&
|
||||
dev->descriptor.idVendor == info[i].vendor)
|
||||
return info[i].help;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void usbutil_list(void)
|
||||
{
|
||||
const struct usb_bus *bus;
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||
const struct usb_device *dev;
|
||||
int busnum = atoi(bus->dirname);
|
||||
|
||||
printf("Devices on bus %03d:\n", busnum);
|
||||
|
||||
for (dev = bus->devices; dev; dev = dev->next) {
|
||||
int devnum = atoi(dev->filename);
|
||||
|
||||
printf(" %03d:%03d %04x:%04x %s\n",
|
||||
busnum, devnum,
|
||||
dev->descriptor.idVendor,
|
||||
dev->descriptor.idProduct,
|
||||
device_help(dev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct usb_device *usbutil_find_by_id(int vendor, int product)
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||
struct usb_device *dev;
|
||||
|
||||
for (dev = bus->devices; dev; dev = dev->next)
|
||||
if (dev->descriptor.idVendor == vendor &&
|
||||
dev->descriptor.idProduct == product)
|
||||
return dev;
|
||||
}
|
||||
|
||||
fprintf(stderr, "usbutil: unable to find a device matching "
|
||||
"%04x:%04x\n", vendor, product);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct usb_device *usbutil_find_by_loc(const char *loc)
|
||||
{
|
||||
char buf[64];
|
||||
char *bus_text;
|
||||
char *dev_text;
|
||||
int target_bus;
|
||||
int target_dev;
|
||||
struct usb_bus *bus;
|
||||
|
||||
strncpy(buf, loc, sizeof(buf));
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
|
||||
bus_text = strtok(buf, ":\t\r\n");
|
||||
dev_text = strtok(NULL, ":\t\r\n");
|
||||
|
||||
if (!(bus_text && dev_text)) {
|
||||
fprintf(stderr, "usbutil: location must be specified as "
|
||||
"<bus>:<device>\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target_bus = atoi(bus_text);
|
||||
target_dev = atoi(dev_text);
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||
struct usb_device *dev;
|
||||
int busnum = atoi(bus->dirname);
|
||||
|
||||
if (busnum != target_bus)
|
||||
continue;
|
||||
|
||||
for (dev = bus->devices; dev; dev = dev->next) {
|
||||
int devnum = atoi(dev->filename);
|
||||
|
||||
if (devnum == target_dev)
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "usbutil: unable to find %03d:%03d\n",
|
||||
target_bus, target_dev);
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* MSPDebug - debugging tool for MSP430 MCUs
|
||||
* Copyright (C) 2009, 2010 Daniel Beer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef USBUTIL_H_
|
||||
#define USBUTIL_H_
|
||||
|
||||
#include <usb.h>
|
||||
|
||||
/* List all available USB devices. */
|
||||
void usbutil_list(void);
|
||||
|
||||
/* Search for the first device matching the given Vendor:Product */
|
||||
struct usb_device *usbutil_find_by_id(int vendor, int product);
|
||||
|
||||
/* Search for a device using a bus:dev location string */
|
||||
struct usb_device *usbutil_find_by_loc(const char *loc);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue