Implemented GDB client driver.
This commit is contained in:
parent
f3a8df82f9
commit
57d5ea34d5
2
Makefile
2
Makefile
|
@ -65,7 +65,7 @@ mspdebug: main.o fet.o rf2500.o dis.o uif.o olimex.o ihex.o elf32.o stab.o \
|
|||
fet_db.o usbutil.o titext.o srec.o device.o coff.o opdb.o output.o \
|
||||
cmddb.o stdcmd.o prog.o flash_bsl.o list.o simio.o simio_tracer.o \
|
||||
simio_timer.o simio_wdt.o simio_hwmult.o simio_gpio.o aliasdb.o \
|
||||
gdb_proto.o
|
||||
gdb_proto.o gdbc.o
|
||||
$(CC) $(LDFLAGS) $(PORTS_LDFLAGS) -o $@ $^ -lusb $(READLINE_LIBS)
|
||||
|
||||
.c.o:
|
||||
|
|
2
gdb.c
2
gdb.c
|
@ -288,7 +288,7 @@ static int run(struct gdb_data *data, char *buf)
|
|||
if (status == DEVICE_STATUS_INTR)
|
||||
goto out;
|
||||
|
||||
while (gdb_peek(data)) {
|
||||
while (gdb_peek(data, 0)) {
|
||||
int c = gdb_getc(data);
|
||||
|
||||
if (c < 0)
|
||||
|
|
27
gdb_proto.c
27
gdb_proto.c
|
@ -51,20 +51,20 @@ void gdb_printf(struct gdb_data *data, const char *fmt, ...)
|
|||
data->outlen += len;
|
||||
}
|
||||
|
||||
static int gdb_read(struct gdb_data *data, int blocking)
|
||||
static int gdb_read(struct gdb_data *data, int timeout_ms)
|
||||
{
|
||||
fd_set r;
|
||||
int len;
|
||||
struct timeval to = {
|
||||
.tv_sec = 0,
|
||||
.tv_usec = 0
|
||||
.tv_sec = timeout_ms / 1000,
|
||||
.tv_usec = timeout_ms % 1000
|
||||
};
|
||||
|
||||
FD_ZERO(&r);
|
||||
FD_SET(data->sock, &r);
|
||||
|
||||
if (select(data->sock + 1, &r, NULL, NULL,
|
||||
blocking ? NULL : &to) < 0) {
|
||||
timeout_ms < 0 ? NULL : &to) < 0) {
|
||||
pr_error("gdb: select");
|
||||
return -1;
|
||||
}
|
||||
|
@ -90,9 +90,9 @@ static int gdb_read(struct gdb_data *data, int blocking)
|
|||
return len;
|
||||
}
|
||||
|
||||
int gdb_peek(struct gdb_data *data)
|
||||
int gdb_peek(struct gdb_data *data, int timeout_ms)
|
||||
{
|
||||
if (data->head == data->tail && gdb_read(data, 0) < 0)
|
||||
if (data->head == data->tail && gdb_read(data, timeout_ms) < 0)
|
||||
return -1;
|
||||
|
||||
return data->head != data->tail;
|
||||
|
@ -103,7 +103,7 @@ int gdb_getc(struct gdb_data *data)
|
|||
int c;
|
||||
|
||||
/* If the buffer is empty, receive some more data */
|
||||
if (data->head == data->tail && gdb_read(data, 1) < 0)
|
||||
if (data->head == data->tail && gdb_read(data, -1) < 0)
|
||||
return -1;
|
||||
|
||||
c = data->xbuf[data->head];
|
||||
|
@ -128,20 +128,21 @@ int gdb_flush_ack(struct gdb_data *data)
|
|||
{
|
||||
int c;
|
||||
|
||||
do {
|
||||
data->outbuf[data->outlen] = 0;
|
||||
#ifdef DEBUG_GDB
|
||||
printc("-> %s\n", data->outbuf);
|
||||
printc("-> %s\n", data->outbuf);
|
||||
#endif
|
||||
data->outbuf[data->outlen] = 0;
|
||||
|
||||
do {
|
||||
if (send(data->sock, data->outbuf, data->outlen, 0) < 0) {
|
||||
data->error = errno;
|
||||
pr_error("gdb: flush_ack");
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = gdb_getc(data);
|
||||
if (c < 0)
|
||||
return -1;
|
||||
do {
|
||||
c = gdb_getc(data);
|
||||
} while (c != '+' && c != '-');
|
||||
} while (c != '+');
|
||||
|
||||
data->outlen = 0;
|
||||
|
|
|
@ -39,7 +39,7 @@ void gdb_printf(struct gdb_data *data, const char *fmt, ...);
|
|||
int gdb_send(struct gdb_data *data, const char *msg);
|
||||
void gdb_packet_start(struct gdb_data *data);
|
||||
void gdb_packet_end(struct gdb_data *data);
|
||||
int gdb_peek(struct gdb_data *data);
|
||||
int gdb_peek(struct gdb_data *data, int timeout_ms);
|
||||
int gdb_getc(struct gdb_data *data);
|
||||
int gdb_flush_ack(struct gdb_data *data);
|
||||
int gdb_read_packet(struct gdb_data *data, char *buf);
|
||||
|
|
|
@ -0,0 +1,446 @@
|
|||
/* MSPDebug - debugging tool for MSP430 MCUs
|
||||
* Copyright (C) 2009-2011 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "output.h"
|
||||
#include "gdbc.h"
|
||||
#include "gdb_proto.h"
|
||||
#include "opdb.h"
|
||||
|
||||
struct gdb_client {
|
||||
struct device base;
|
||||
struct gdb_data gdb;
|
||||
int is_running;
|
||||
|
||||
struct device_breakpoint last_bps[DEVICE_MAX_BREAKPOINTS];
|
||||
};
|
||||
|
||||
static int get_xfer_size(void)
|
||||
{
|
||||
int x = opdb_get_numeric("gdbc_xfer_size");
|
||||
|
||||
if (x < 2)
|
||||
return 2;
|
||||
|
||||
if (x > GDB_MAX_XFER)
|
||||
return GDB_MAX_XFER;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static int check_ok(struct gdb_data *gdb)
|
||||
{
|
||||
char buf[GDB_BUF_SIZE];
|
||||
int len;
|
||||
|
||||
len = gdb_read_packet(gdb, buf);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
if (len < 1 || buf[0] == 'E') {
|
||||
printc_err("gdbc: bad response: %s\n", buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gdbc_destroy(device_t dev_base)
|
||||
{
|
||||
struct gdb_client *c = (struct gdb_client *)dev_base;
|
||||
|
||||
shutdown(c->gdb.sock, 2);
|
||||
close(c->gdb.sock);
|
||||
free(c);
|
||||
}
|
||||
|
||||
static int gdbc_readmem(device_t dev_base, address_t addr,
|
||||
uint8_t *mem, address_t len)
|
||||
{
|
||||
struct gdb_client *dev = (struct gdb_client *)dev_base;
|
||||
int xfer_size = get_xfer_size();
|
||||
char buf[GDB_BUF_SIZE];
|
||||
|
||||
while (len) {
|
||||
int plen = len > xfer_size ? xfer_size : len;
|
||||
int r;
|
||||
int i;
|
||||
|
||||
gdb_packet_start(&dev->gdb);
|
||||
gdb_printf(&dev->gdb, "m%04x,%x", addr, plen);
|
||||
gdb_packet_end(&dev->gdb);
|
||||
if (gdb_flush_ack(&dev->gdb) < 0)
|
||||
return -1;
|
||||
|
||||
r = gdb_read_packet(&dev->gdb, buf);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
|
||||
if (r < plen * 2) {
|
||||
printc_err("gdbc: short read at 0x%04x: expected %d "
|
||||
"bytes, got %d\n", addr, plen, r / 2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i * 2 < r; i++)
|
||||
mem[i] = (hexval(buf[i * 2]) << 4) |
|
||||
hexval(buf[i * 2 + 1]);
|
||||
|
||||
mem += plen;
|
||||
len -= plen;
|
||||
addr += plen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdbc_writemem(device_t dev_base, address_t addr,
|
||||
const uint8_t *mem, address_t len)
|
||||
{
|
||||
struct gdb_client *dev = (struct gdb_client *)dev_base;
|
||||
int xfer_size = get_xfer_size();
|
||||
|
||||
while (len) {
|
||||
int plen = len > xfer_size ? xfer_size : len;
|
||||
int i;
|
||||
|
||||
gdb_packet_start(&dev->gdb);
|
||||
gdb_printf(&dev->gdb, "M%04x,%x:", addr, plen);
|
||||
for (i = 0; i < plen; i++)
|
||||
gdb_printf(&dev->gdb, "%02x", mem[i]);
|
||||
gdb_packet_end(&dev->gdb);
|
||||
if (gdb_flush_ack(&dev->gdb) < 0)
|
||||
return -1;
|
||||
|
||||
if (check_ok(&dev->gdb) < 0)
|
||||
return -1;
|
||||
|
||||
mem += plen;
|
||||
len -= plen;
|
||||
addr += plen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdbc_getregs(device_t dev_base, address_t *regs)
|
||||
{
|
||||
struct gdb_client *dev = (struct gdb_client *)dev_base;
|
||||
char buf[GDB_BUF_SIZE];
|
||||
int len;
|
||||
int i;
|
||||
|
||||
if (gdb_send(&dev->gdb, "g") < 0)
|
||||
return -1;
|
||||
|
||||
len = gdb_read_packet(&dev->gdb, buf);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
if (len < DEVICE_NUM_REGS * 4) {
|
||||
printc_err("gdbc: short read: expected %d chars, got %d\n",
|
||||
DEVICE_NUM_REGS * 4, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < DEVICE_NUM_REGS; i++) {
|
||||
char *text = buf + i * 4;
|
||||
|
||||
regs[i] = (hexval(text[0]) << 4) | (hexval(text[1])) |
|
||||
(hexval(text[2]) << 12) | (hexval(text[3]) << 8);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdbc_setregs(device_t dev_base, const address_t *regs)
|
||||
{
|
||||
struct gdb_client *dev = (struct gdb_client *)dev_base;
|
||||
int i;
|
||||
|
||||
gdb_packet_start(&dev->gdb);
|
||||
gdb_printf(&dev->gdb, "G");
|
||||
for (i = 0; i < DEVICE_NUM_REGS; i++)
|
||||
gdb_printf(&dev->gdb, "%02x%02x",
|
||||
regs[i] & 0xff, (regs[i] >> 8) & 0xff);
|
||||
gdb_packet_end(&dev->gdb);
|
||||
if (gdb_flush_ack(&dev->gdb) < 0)
|
||||
return -1;
|
||||
|
||||
return check_ok(&dev->gdb);
|
||||
}
|
||||
|
||||
static int do_reset(struct gdb_client *dev)
|
||||
{
|
||||
char buf[GDB_BUF_SIZE];
|
||||
int len;
|
||||
|
||||
if (gdb_send(&dev->gdb, "R00") < 0)
|
||||
return -1;
|
||||
|
||||
len = gdb_read_packet(&dev->gdb, buf);
|
||||
if (!len) {
|
||||
if (gdb_send(&dev->gdb, "r") < 0)
|
||||
return -1;
|
||||
len = gdb_read_packet(&dev->gdb, buf);
|
||||
}
|
||||
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
if (len < 2 || buf[0] != 'O' || buf[1] != 'K') {
|
||||
printc_err("gdbc: reset: bad response: %s\n", buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bp_send(struct gdb_data *gdb, int c, address_t addr)
|
||||
{
|
||||
gdb_packet_start(gdb);
|
||||
gdb_printf(gdb, "%c1,%04x,2", c, addr);
|
||||
gdb_packet_end(gdb);
|
||||
if (gdb_flush_ack(gdb) < 0)
|
||||
return -1;
|
||||
|
||||
return check_ok(gdb);
|
||||
}
|
||||
|
||||
static int refresh_bps(struct gdb_client *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dev->base.max_breakpoints; i++) {
|
||||
struct device_breakpoint *bp = &dev->base.breakpoints[i];
|
||||
struct device_breakpoint *old = &dev->last_bps[i];
|
||||
|
||||
if (!(bp->flags & DEVICE_BP_DIRTY))
|
||||
continue;
|
||||
|
||||
if ((old->flags & DEVICE_BP_ENABLED) &&
|
||||
(bp_send(&dev->gdb, 'z', old->addr) < 0))
|
||||
return -1;
|
||||
|
||||
if ((bp->flags & DEVICE_BP_ENABLED) &&
|
||||
(bp_send(&dev->gdb, 'Z', bp->addr) < 0))
|
||||
return -1;
|
||||
|
||||
bp->flags &= ~DEVICE_BP_DIRTY;
|
||||
}
|
||||
|
||||
memcpy(dev->last_bps, dev->base.breakpoints, sizeof(dev->last_bps));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdbc_ctl(device_t dev_base, device_ctl_t op)
|
||||
{
|
||||
struct gdb_client *dev = (struct gdb_client *)dev_base;
|
||||
|
||||
switch (op) {
|
||||
case DEVICE_CTL_STEP:
|
||||
if (gdb_send(&dev->gdb, "s") < 0)
|
||||
return -1;
|
||||
|
||||
return check_ok(&dev->gdb);
|
||||
|
||||
case DEVICE_CTL_RUN:
|
||||
if (refresh_bps(dev) < 0)
|
||||
return -1;
|
||||
if (gdb_send(&dev->gdb, "c") < 0)
|
||||
return -1;
|
||||
dev->is_running = 1;
|
||||
return 0;
|
||||
|
||||
case DEVICE_CTL_HALT:
|
||||
if (dev->is_running) {
|
||||
if (write_all(dev->gdb.sock,
|
||||
(const uint8_t *)"\003", 1) < 0) {
|
||||
pr_error("gdbc: write");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev->is_running = 0;
|
||||
return check_ok(&dev->gdb);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case DEVICE_CTL_RESET:
|
||||
return do_reset(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdbc_erase(device_t dev_base, device_erase_type_t type,
|
||||
address_t addr)
|
||||
{
|
||||
struct gdb_client *dev = (struct gdb_client *)dev_base;
|
||||
const char *cmd = "erase";
|
||||
char buf[GDB_BUF_SIZE];
|
||||
int len;
|
||||
|
||||
gdb_packet_start(&dev->gdb);
|
||||
gdb_printf(&dev->gdb, "qRcmd,");
|
||||
while (*cmd)
|
||||
gdb_printf(&dev->gdb, "%02x", *(cmd++));
|
||||
gdb_packet_end(&dev->gdb);
|
||||
|
||||
if (gdb_flush_ack(&dev->gdb) < 0)
|
||||
return -1;
|
||||
|
||||
len = gdb_read_packet(&dev->gdb, buf);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static device_status_t gdbc_poll(device_t dev_base)
|
||||
{
|
||||
struct gdb_client *dev = (struct gdb_client *)dev_base;
|
||||
char buf[GDB_BUF_SIZE];
|
||||
int len;
|
||||
|
||||
if (!dev->is_running)
|
||||
return DEVICE_STATUS_HALTED;
|
||||
|
||||
len = gdb_peek(&dev->gdb, 50);
|
||||
if (len < 0) {
|
||||
if (errno == EINTR)
|
||||
return DEVICE_STATUS_INTR;
|
||||
|
||||
dev->is_running = 0;
|
||||
return DEVICE_STATUS_ERROR;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
return DEVICE_STATUS_RUNNING;
|
||||
|
||||
len = gdb_read_packet(&dev->gdb, buf);
|
||||
if (len < 0) {
|
||||
dev->is_running = 0;
|
||||
return DEVICE_STATUS_ERROR;
|
||||
}
|
||||
|
||||
dev->is_running = 0;
|
||||
return DEVICE_STATUS_HALTED;
|
||||
}
|
||||
|
||||
static int connect_to(const char *spec)
|
||||
{
|
||||
const char *port_text;
|
||||
int hn_len;
|
||||
int port = 2000;
|
||||
char hostname[128];
|
||||
struct hostent *ent;
|
||||
struct sockaddr_in addr;
|
||||
int sock;
|
||||
|
||||
if (!spec) {
|
||||
printc_err("gdbc: no remote target specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
port_text = strchr(spec, ':');
|
||||
if (port_text) {
|
||||
port = atoi(port_text + 1);
|
||||
hn_len = port_text - spec;
|
||||
} else {
|
||||
hn_len = strlen(spec);
|
||||
}
|
||||
|
||||
if (hn_len + 1 > sizeof(hostname))
|
||||
hn_len = sizeof(hostname) - 1;
|
||||
memcpy(hostname, spec, hn_len);
|
||||
hostname[hn_len] = 0;
|
||||
|
||||
printc_dbg("Looking up %s...\n", hostname);
|
||||
ent = gethostbyname(hostname);
|
||||
if (!ent) {
|
||||
printc_err("No such host: %s: %s\n", hostname,
|
||||
hstrerror(h_errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
sock = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (!sock) {
|
||||
printc_err("socket: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr = *(struct in_addr *)ent->h_addr;
|
||||
printc_dbg("Connecting to %s:%d...\n",
|
||||
inet_ntoa(addr.sin_addr), port);
|
||||
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
printc_err("connect: %s\n", strerror(errno));
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
static device_t gdbc_open(const struct device_args *args)
|
||||
{
|
||||
int sock = connect_to(args->path);
|
||||
struct gdb_client *dev;
|
||||
|
||||
if (sock < 0)
|
||||
return NULL;
|
||||
|
||||
dev = malloc(sizeof(struct gdb_client));
|
||||
if (!dev) {
|
||||
printc_err("gdbc: can't allocate memory: %s\n",
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
dev->base.type = &device_gdbc;
|
||||
dev->base.max_breakpoints = DEVICE_MAX_BREAKPOINTS;
|
||||
|
||||
gdb_init(&dev->gdb, sock);
|
||||
return (device_t)dev;
|
||||
}
|
||||
|
||||
const struct device_class device_gdbc = {
|
||||
.name = "gdbc",
|
||||
.help = "GDB client mode",
|
||||
.open = gdbc_open,
|
||||
.destroy = gdbc_destroy,
|
||||
.readmem = gdbc_readmem,
|
||||
.writemem = gdbc_writemem,
|
||||
.erase = gdbc_erase,
|
||||
.getregs = gdbc_getregs,
|
||||
.setregs = gdbc_setregs,
|
||||
.ctl = gdbc_ctl,
|
||||
.poll = gdbc_poll
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
/* MSPDebug - debugging tool for MSP430 MCUs
|
||||
* Copyright (C) 2009-2011 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 GDBC_H_
|
||||
#define GDBC_H_
|
||||
|
||||
#include "device.h"
|
||||
|
||||
/* GDB client implementation */
|
||||
extern const struct device_class device_gdbc;
|
||||
|
||||
#endif
|
4
main.c
4
main.c
|
@ -46,6 +46,7 @@
|
|||
#include "vector.h"
|
||||
#include "fet_db.h"
|
||||
#include "flash_bsl.h"
|
||||
#include "gdbc.h"
|
||||
|
||||
#include "uif.h"
|
||||
#include "olimex.h"
|
||||
|
@ -64,7 +65,8 @@ static const struct device_class *const driver_table[] = {
|
|||
&device_sim,
|
||||
&device_uif,
|
||||
&device_bsl,
|
||||
&device_flash_bsl
|
||||
&device_flash_bsl,
|
||||
&device_gdbc
|
||||
};
|
||||
|
||||
static const char *version_text =
|
||||
|
|
|
@ -117,6 +117,11 @@ Connect RTS to the device's TEST pin and DTR to the device's RST pin.
|
|||
Use an appropriate serial level-shifter to make the connection, if necessary.
|
||||
If connecting to a device with non-multiplexed JTAG pins, connect RTS to
|
||||
the device's TCK pin via an inverter.
|
||||
.IP "\fBgdbc\fR"
|
||||
GDB client mode. Connect to a server which implements the GDB remote
|
||||
protocol and provide an interface to it. To use this driver, specify
|
||||
the remote address in \fIhostname:port\fR format using the \fB-d\fR
|
||||
option.
|
||||
.SH COMMANDS
|
||||
MSPDebug can accept commands either through an interactive prompt, or
|
||||
non-interactively when specified on the command line. The supported
|
||||
|
@ -608,6 +613,10 @@ speed, but may cause problems with some chips.
|
|||
Automatically restart the GDB server after disconnection. If this
|
||||
option is set, then the GDB server keeps running until an error occurs,
|
||||
or the user interrupts with Ctrl+C.
|
||||
.IP "\fBgdbc_xfer_size\fR (numeric)"
|
||||
Maximum size of memory transfers for the GDB client. Increasing this
|
||||
value will result in faster transfers, but may cause problems with some
|
||||
servers.
|
||||
.IP "\fBiradix\fR (numeric)"
|
||||
Default input radix for address expressions. For address values with
|
||||
no radix specifier, this value gives the input radix, which is
|
||||
|
|
11
opdb.c
11
opdb.c
|
@ -66,6 +66,17 @@ const static struct opdb_key keys[] = {
|
|||
.defval = {
|
||||
.numeric = 64
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "gdbc_xfer_size",
|
||||
.type = OPDB_TYPE_NUMERIC,
|
||||
.help =
|
||||
"Maximum size of memory transfers for the GDB client. Increasing this\n"
|
||||
"value will result in faster transfers, but may cause problems with some\n"
|
||||
"servers.\n",
|
||||
.defval = {
|
||||
.numeric = 64
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue