Drivers are now specified by name, rather than different switches.
This commit is contained in:
parent
9dd216e604
commit
8503cc4a85
291
main.c
291
main.c
|
@ -118,32 +118,144 @@ static void store_io(void *user_data, uint16_t pc,
|
|||
printf(" => 0x%04x\n", data);
|
||||
}
|
||||
|
||||
struct cmdline_args {
|
||||
const char *driver_name;
|
||||
const char *serial_device;
|
||||
const char *fet_force_id;
|
||||
int want_jtag;
|
||||
int no_rc;
|
||||
int vcc_mv;
|
||||
stab_t stab;
|
||||
};
|
||||
|
||||
struct driver {
|
||||
const char *name;
|
||||
const char *help;
|
||||
device_t (*func)(const struct cmdline_args *args);
|
||||
};
|
||||
|
||||
static device_t driver_open_fet(const struct cmdline_args *args,
|
||||
int flags, transport_t trans)
|
||||
{
|
||||
device_t dev;
|
||||
|
||||
if (!args->want_jtag)
|
||||
flags |= FET_PROTO_SPYBIWIRE;
|
||||
|
||||
dev = fet_open(trans, flags, args->vcc_mv, args->fet_force_id);
|
||||
if (!dev) {
|
||||
trans->destroy(trans);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static device_t driver_open_rf2500(const struct cmdline_args *args)
|
||||
{
|
||||
transport_t trans;
|
||||
|
||||
if (args->serial_device) {
|
||||
fprintf(stderr, "This driver does not support tty devices.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
trans = rf2500_open();
|
||||
if (!trans)
|
||||
return NULL;
|
||||
|
||||
return driver_open_fet(args, FET_PROTO_RF2500, trans);
|
||||
}
|
||||
|
||||
static device_t driver_open_olimex(const struct cmdline_args *args)
|
||||
{
|
||||
transport_t trans;
|
||||
|
||||
if (args->serial_device)
|
||||
trans = uif_open(args->serial_device, 1);
|
||||
else
|
||||
trans = olimex_open();
|
||||
|
||||
if (!trans)
|
||||
return NULL;
|
||||
|
||||
return driver_open_fet(args, FET_PROTO_OLIMEX, trans);
|
||||
}
|
||||
|
||||
static device_t driver_open_sim(const struct cmdline_args *args)
|
||||
{
|
||||
return sim_open(fetch_io, store_io, args->stab);
|
||||
}
|
||||
|
||||
static device_t driver_open_uif(const struct cmdline_args *args)
|
||||
{
|
||||
transport_t trans;
|
||||
|
||||
if (!args->serial_device) {
|
||||
fprintf(stderr, "This driver does not support USB access. "
|
||||
"Specify a tty device using -d.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
trans = uif_open(args->serial_device, 0);
|
||||
if (!trans)
|
||||
return NULL;
|
||||
|
||||
return driver_open_fet(args, 0, trans);
|
||||
}
|
||||
|
||||
static device_t driver_open_uif_bsl(const struct cmdline_args *args)
|
||||
{
|
||||
if (!args->serial_device) {
|
||||
fprintf(stderr, "This driver does not support USB access. "
|
||||
"Specify a tty device using -d.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bsl_open(args->serial_device);
|
||||
}
|
||||
|
||||
static const struct driver driver_table[] = {
|
||||
{
|
||||
.name = "rf2500",
|
||||
.help = "eZ430-RF2500 devices. Only USB connection is "
|
||||
"supported.",
|
||||
driver_open_rf2500
|
||||
},
|
||||
{ .name = "olimex",
|
||||
.help = "Olimex MSP-JTAG-TINY.",
|
||||
.func = driver_open_olimex
|
||||
},
|
||||
{
|
||||
.name = "sim",
|
||||
.help = "Simulation mode.",
|
||||
.func = driver_open_sim
|
||||
},
|
||||
{
|
||||
.name = "uif",
|
||||
.help = "TI FET430UIF and compatible devices (e.g. eZ430).",
|
||||
.func = driver_open_uif
|
||||
},
|
||||
{
|
||||
.name = "uif-bsl",
|
||||
.help = "TI FET430UIF bootloader.",
|
||||
.func = driver_open_uif_bsl
|
||||
}
|
||||
};
|
||||
|
||||
static void usage(const char *progname)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf(stderr,
|
||||
"Usage: %s [options] -R [-v voltage] [command ...]\n"
|
||||
" %s [options] -u <device> [-j] [-v voltage] [command ...]\n"
|
||||
" %s [options] -O <device> [-j] [-v voltage] [command ...]\n"
|
||||
" %s [options] -l [-j] [-v voltage] [command ...]\n"
|
||||
" %s [options] -B <device> [command ...]\n"
|
||||
" %s [options] -s [command ...]\n"
|
||||
"Usage: %s [options] <driver> [command ...]\n"
|
||||
"\n"
|
||||
" -R\n"
|
||||
" Open the first available RF2500 device on the USB bus.\n"
|
||||
" -u device\n"
|
||||
" Open the given tty device (FET430UIF compatible devices).\n"
|
||||
" -O device\n"
|
||||
" Open the given tty device (Olimex MSP430-JTAG-TINY).\n"
|
||||
" -l\n"
|
||||
" Open the first available Olimex MSP430-JTAG-TINY using libusb.\n"
|
||||
" -d device\n"
|
||||
" Connect via the given tty device, rather than USB.\n"
|
||||
" -j\n"
|
||||
" Use JTAG, rather than Spy-Bi-Wire (UIF devices only).\n"
|
||||
" -v voltage\n"
|
||||
" Set the supply voltage, in millivolts.\n"
|
||||
" -B device\n"
|
||||
" Debug the FET itself through the bootloader.\n"
|
||||
" -s\n"
|
||||
" Start in simulation mode.\n"
|
||||
" -n\n"
|
||||
" Do not read ~/.mspdebug on startup.\n"
|
||||
" --help\n"
|
||||
|
@ -153,11 +265,19 @@ static void usage(const char *progname)
|
|||
" --fet-force-id string\n"
|
||||
" Override the device ID returned by the FET.\n"
|
||||
"\n"
|
||||
"By default, the first RF2500 device on the USB bus is opened.\n"
|
||||
"Most drivers connect by default via USB, unless told otherwise via the\n"
|
||||
"-d option.\n"
|
||||
"\n"
|
||||
"If commands are given, they will be executed. Otherwise, an interactive\n"
|
||||
"command reader is started.\n",
|
||||
progname, progname, progname, progname, progname, progname);
|
||||
"command reader is started.\n\n",
|
||||
progname);
|
||||
|
||||
printf("Available drivers are:\n");
|
||||
for (i = 0; i < ARRAY_LEN(driver_table); i++) {
|
||||
const struct driver *drv = &driver_table[i];
|
||||
|
||||
printf(" %s\n %s\n", drv->name, drv->help);
|
||||
}
|
||||
}
|
||||
|
||||
static void process_rc_file(cproc_t cp)
|
||||
|
@ -173,22 +293,6 @@ static void process_rc_file(cproc_t cp)
|
|||
cproc_process_file(cp, text);
|
||||
}
|
||||
|
||||
#define MODE_RF2500 0x01
|
||||
#define MODE_UIF 0x02
|
||||
#define MODE_UIF_BSL 0x04
|
||||
#define MODE_SIM 0x08
|
||||
#define MODE_OLIMEX 0x10
|
||||
#define MODE_OLIMEX_USB 0x20
|
||||
|
||||
struct cmdline_args {
|
||||
const char *devpath;
|
||||
const char *fet_force_id;
|
||||
int mode;
|
||||
int want_jtag;
|
||||
int no_rc;
|
||||
int vcc_mv;
|
||||
};
|
||||
|
||||
static int add_fet_device(void *user_data, const struct fet_db_record *r)
|
||||
{
|
||||
struct vector *v = (struct vector *)user_data;
|
||||
|
@ -234,12 +338,11 @@ static int parse_cmdline_args(int argc, char **argv,
|
|||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "lu:jv:B:O:sR?n",
|
||||
while ((opt = getopt_long(argc, argv, "d:jv:n",
|
||||
longopts, NULL)) >= 0)
|
||||
switch (opt) {
|
||||
case 'O':
|
||||
args->devpath = optarg;
|
||||
args->mode |= MODE_OLIMEX;
|
||||
case 'd':
|
||||
args->serial_device = optarg;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
|
@ -253,19 +356,6 @@ static int parse_cmdline_args(int argc, char **argv,
|
|||
usage(argv[0]);
|
||||
exit(0);
|
||||
|
||||
case 'R':
|
||||
args->mode |= MODE_RF2500;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
args->devpath = optarg;
|
||||
args->mode |= MODE_UIF;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
args->mode |= MODE_OLIMEX_USB;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
args->vcc_mv = atoi(optarg);
|
||||
break;
|
||||
|
@ -274,103 +364,50 @@ static int parse_cmdline_args(int argc, char **argv,
|
|||
args->want_jtag = 1;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
args->devpath = optarg;
|
||||
args->mode |= MODE_UIF_BSL;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
args->mode |= MODE_SIM;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
args->no_rc = 1;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -1;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Invalid argument: %c\n"
|
||||
"Try --help for help.\n", opt);
|
||||
fprintf(stderr, "Try --help for usage information.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check for incompatible arguments */
|
||||
if (args->mode & (args->mode - 1)) {
|
||||
fprintf(stderr, "Multiple incompatible options specified.\n"
|
||||
"Try --help for help.\n");
|
||||
if (optind >= argc) {
|
||||
fprintf(stderr, "You need to specify a driver. Try --help for "
|
||||
"a list.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!args->mode) {
|
||||
fprintf(stderr, "You need to specify an operating mode.\n"
|
||||
"Try --help for help.\n");
|
||||
return -1;
|
||||
}
|
||||
args->driver_name = argv[optind];
|
||||
optind++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_t setup_device(const struct cmdline_args *args,
|
||||
stab_t stab)
|
||||
{
|
||||
device_t msp430_dev = NULL;
|
||||
transport_t trans = NULL;
|
||||
|
||||
/* Open a device */
|
||||
if (args->mode == MODE_SIM) {
|
||||
msp430_dev = sim_open(fetch_io, store_io, stab);
|
||||
} else if (args->mode == MODE_UIF_BSL) {
|
||||
msp430_dev = bsl_open(args->devpath);
|
||||
} else {
|
||||
int flags = 0;
|
||||
|
||||
/* Open the appropriate transport */
|
||||
if (args->mode == MODE_OLIMEX) {
|
||||
trans = uif_open(args->devpath, 1);
|
||||
flags |= FET_PROTO_OLIMEX;
|
||||
} else if (args->mode == MODE_UIF) {
|
||||
trans = uif_open(args->devpath, 0);
|
||||
} else if (args->mode == MODE_OLIMEX_USB) {
|
||||
trans = olimex_open();
|
||||
flags |= FET_PROTO_OLIMEX;
|
||||
} else {
|
||||
trans = rf2500_open();
|
||||
flags |= FET_PROTO_RF2500;
|
||||
}
|
||||
|
||||
if (!trans)
|
||||
return NULL;
|
||||
|
||||
/* Then initialize the device */
|
||||
if (!args->want_jtag)
|
||||
flags |= FET_PROTO_SPYBIWIRE;
|
||||
|
||||
msp430_dev = fet_open(trans, flags, args->vcc_mv,
|
||||
args->fet_force_id);
|
||||
}
|
||||
|
||||
if (!msp430_dev) {
|
||||
if (trans)
|
||||
trans->destroy(trans);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return msp430_dev;
|
||||
}
|
||||
|
||||
cproc_t setup_cproc(const struct cmdline_args *args)
|
||||
cproc_t setup_cproc(struct cmdline_args *args)
|
||||
{
|
||||
int i;
|
||||
device_t msp430_dev;
|
||||
stab_t stab;
|
||||
cproc_t cp;
|
||||
|
||||
i = 0;
|
||||
while (i < ARRAY_LEN(driver_table) &&
|
||||
strcasecmp(driver_table[i].name, args->driver_name))
|
||||
i++;
|
||||
if (i >= ARRAY_LEN(driver_table)) {
|
||||
fprintf(stderr, "Unknown driver: %s. Try --help for a list.\n",
|
||||
args->driver_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stab = stab_new();
|
||||
if (!stab)
|
||||
return NULL;
|
||||
args->stab = stab;
|
||||
|
||||
msp430_dev = setup_device(args, stab);
|
||||
msp430_dev = driver_table[i].func(args);
|
||||
if (!msp430_dev) {
|
||||
stab_destroy(stab);
|
||||
return NULL;
|
||||
|
|
101
mspdebug.man
101
mspdebug.man
|
@ -2,21 +2,12 @@
|
|||
.SH NAME
|
||||
MSPDebug - debugging tool for MSP430 MCUs
|
||||
.SH SYNOPSIS
|
||||
\fBmspdebug\fR [options] \-R [\-v \fIvoltage\fR] [\fIcommand\fR ...]
|
||||
.br
|
||||
\fBmspdebug\fR [options] \-u \fIdevice\fR [\-j] [\-v \fIvoltage\fR] [\fIcommand\fR ...]
|
||||
.br
|
||||
\fBmspdebug\fR [options] \-O \fIdevice\fR [\-j] [\-v \fIvoltage\fR] [\fIcommand\fR ...]
|
||||
.br
|
||||
\fBmspdebug\fR [options] \-l [\-j] [\-v \fIvoltage\fR] [\fIcommand\fR ...]
|
||||
.br
|
||||
\fBmspdebug\fR [options] \-B \fIdevice\fR [\fIcommand\fR ...]
|
||||
.br
|
||||
\fBmspdebug\fR [options] \-s [\fIcommand\fR ...]
|
||||
\fBmspdebug\fR [options] \fIdriver\fR [\fIcommand\fR ...]
|
||||
.SH DESCRIPTION
|
||||
MSPDebug is a command-line tool designed for debugging and programming
|
||||
the MSP430 family of MCUs. It supports the eZ430-F2013, eZ430-RF2500
|
||||
and FET430UIF programming tools.
|
||||
the MSP430 family of MCUs. It supports the eZ430-F2013, eZ430-RF2500,
|
||||
FET430UIF and Olimex MSP-JTAG-TINY programming tools, as well as a
|
||||
simulation mode.
|
||||
|
||||
When started with appropriate options, MSPDebug will attempt to
|
||||
connect to the debugging tool specified and identify the device under
|
||||
|
@ -39,42 +30,36 @@ commands are specified on the end of the command-line, then they are
|
|||
executed after connecting to the device, and the interactive prompt is
|
||||
not started. See the section labelled \fBCOMMANDS\fR for more
|
||||
information.
|
||||
.IP "\-R"
|
||||
Connect to an eZ430-RF2500 device. The USB bus will be searched for
|
||||
the first available device. You must have write permission for usbfs
|
||||
in order for this to work. You can achieve this by running as root
|
||||
(not recommended), or by remounting usbfs using the
|
||||
devuid/devgid/devmode options.
|
||||
.IP "\-v \fIvoltage\fR"
|
||||
Set the programming voltage. The voltage should be specified as an integer
|
||||
in millivolts. It defaults to 3000 (3.0 V).
|
||||
.IP "\-u \fIdevice\fR"
|
||||
Connect to an eZ430-F2013 or a FET430UIF device. The device argument
|
||||
should be the filename of the appropriate tty device. The TI serial
|
||||
converter chips on these devices are supported by newer versions of the
|
||||
Linux kernel, and should appear as /dev/tty\fIXX\fR when attached.
|
||||
.IP "\-O \fIdevice\fR"
|
||||
Connect to an Olimex MSP430-JTAG-TINY device. The device argument
|
||||
should be the filename of the appropriate tty device.
|
||||
.IP "\-l"
|
||||
Connect to an Olimex MSP430-JTAG-TINY device using libusb. The first
|
||||
available device on the USB bus is claimed.
|
||||
.IP "\-j"
|
||||
Use JTAG instead of Spy-Bi-Wire to communicate with the MSP430. This
|
||||
option only works on FET430UIF devices.
|
||||
.IP "\-B \fIdevice\fR"
|
||||
Connect to the bootloader on a FET430UIF device. These devices contain
|
||||
MSP430F419 chips. By sending a special command sequence, you can obtain
|
||||
access to the bootloader and inspect memory on the MSP430F419 in the
|
||||
programming device itself.
|
||||
|
||||
Currently, only memory inspection is supported. CPU control via the
|
||||
bootloader is not possible. Memory erase and write is possible, but is
|
||||
currently not implemented, for lack of ability to test it. If implemented,
|
||||
this would allow firmware updates to FET430UIF devices.
|
||||
|
||||
The argument should be the filename of the appropriate tty device.
|
||||
.IP "\-s"
|
||||
.IP "\-d \fIdevice\fR"
|
||||
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 "\-n"
|
||||
Do not process the startup file (~/.mspdebug).
|
||||
.IP "\-\-help"
|
||||
Display a brief help message and exit.
|
||||
.IP "\-\-fet\-list"
|
||||
Display a list of devices supported by the FET driver (the driver used
|
||||
for \fB\-R\fR and \fB\-u\fR operating modes).
|
||||
.IP "\-\-fet\-force\-id \fIstring\fR"
|
||||
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.
|
||||
.SH DRIVERS
|
||||
A driver name must be specified on the command line for MSPDebug to
|
||||
connect to. Valid driver names are listed here.
|
||||
.IP "\fBrf2500\fR"
|
||||
Connect to an eZ430-RF2500 device. Only USB connection is supported.
|
||||
.IP "\fBolimex\fR"
|
||||
Connect to an Olimex MSP-JTAG-TINY device. Both USB and tty access are
|
||||
supported.
|
||||
.IP "\fBsim\fR"
|
||||
Do not connect to any hardware device, but instead start in simulation
|
||||
mode. A 64k buffer is allocated to simulate the device memory. The CPU
|
||||
core alone is emulated (no peripheral emulation).
|
||||
|
@ -94,17 +79,25 @@ execution.
|
|||
This mode is intended for testing of changes to MSPDebug, and for
|
||||
aiding the disassembly of MSP430 binaries (as all binary and symbol
|
||||
table formats are still usable in this mode).
|
||||
.IP "\-n"
|
||||
Do not process the startup file (~/.mspdebug).
|
||||
.IP "\-\-help"
|
||||
Display a brief help message and exit.
|
||||
.IP "\-\-fet\-list"
|
||||
Display a list of devices supported by the FET driver (the driver used
|
||||
for \fB\-R\fR and \fB\-u\fR operating modes).
|
||||
.IP "\-\-fet\-force\-id \fIstring\fR"
|
||||
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 "\fBuif\fR"
|
||||
Connect to an eZ430-F2013 or a FET430UIF device. The device argument
|
||||
should be the filename of the appropriate tty device. The TI serial
|
||||
converter chips on these devices are supported by newer versions of the
|
||||
Linux kernel, and should appear as /dev/tty\fIXX\fR when attached.
|
||||
|
||||
USB connection is not supported for this driver.
|
||||
.IP "\fBuif-bsl\fR"
|
||||
Connect to the bootloader on a FET430UIF device. These devices contain
|
||||
MSP430F419 chips. By sending a special command sequence, you can obtain
|
||||
access to the bootloader and inspect memory on the MSP430F419 in the
|
||||
programming device itself.
|
||||
|
||||
Currently, only memory inspection is supported. CPU control via the
|
||||
bootloader is not possible. Memory erase and write is possible, but is
|
||||
currently not implemented, for lack of ability to test it. If implemented,
|
||||
this would allow firmware updates to FET430UIF devices.
|
||||
|
||||
USB connection is not supported for this driver.
|
||||
.SH COMMANDS
|
||||
MSPDebug can accept commands either through an interactive prompt, or
|
||||
non-interactively when specified on the command line. The supported
|
||||
|
|
Loading…
Reference in New Issue