Add support for read with ... "operator"

This means that you can use ... to read the "rest" of the memory.
$ read eeprom ...   will dump the entire memory
$ read eeorm 0x80 ...   will dump the memory from address 0x80 to the end address
This commit is contained in:
MCUdude 2022-02-28 22:40:17 +01:00
parent d89f695c31
commit b688b1f601
1 changed files with 62 additions and 63 deletions

View File

@ -149,12 +149,10 @@ static int nexttok(char * buf, char ** tok, char ** next)
static int hexdump_line(char * buffer, unsigned char * p, int n, int pad) static int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
{ {
char * hexdata = "0123456789abcdef"; char * hexdata = "0123456789abcdef";
char * b; char * b = buffer;
int i, j; int32_t i = 0;
int32_t j = 0;
b = buffer;
j = 0;
for (i=0; i<n; i++) { for (i=0; i<n; i++) {
if (i && ((i % 8) == 0)) if (i && ((i % 8) == 0))
b[j++] = ' '; b[j++] = ' ';
@ -183,7 +181,7 @@ static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
int i; int i;
char b [ 128 ]; char b [ 128 ];
for (i=0; i<n; i++) { for (int32_t i = 0; i < n; i++) {
memcpy(b, p, n); memcpy(b, p, n);
buffer[i] = '.'; buffer[i] = '.';
if (isalpha((int)(b[i])) || isdigit((int)(b[i])) || ispunct((int)(b[i]))) if (isalpha((int)(b[i])) || isdigit((int)(b[i])) || ispunct((int)(b[i])))
@ -203,16 +201,13 @@ static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len) static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
{ {
int addr;
int n;
unsigned char * p;
char dst1[80]; char dst1[80];
char dst2[80]; char dst2[80];
addr = startaddr; int32_t addr = startaddr;
p = (unsigned char *)buf; unsigned char * p = (unsigned char *)buf;
while (len) { while (len) {
n = 16; int32_t n = 16;
if (n > len) if (n > len)
n = len; n = len;
hexdump_line(dst1, p, n, 48); hexdump_line(dst1, p, n, 48);
@ -230,80 +225,85 @@ static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[]) int argc, char * argv[])
{ {
static char prevmem[128] = {0}; if (argc < 2) {
char * e; avrdude_message(MSG_INFO, "Usage: %s <memtype> [<start addr> <len>]\n"
unsigned char * buf; " %s <memtype> [<start addr> <...>]\n"
int maxsize; " %s <memtype> <...>\n"
unsigned long i; " %s <memtype>\n",
static unsigned long addr=0; argv[0], argv[0], argv[0], argv[0]);
static int len=64;
AVRMEM * mem;
char * memtype = NULL;
int rc;
if (!((argc == 2) || (argc == 4))) {
avrdude_message(MSG_INFO, "Usage: dump <memtype> [<addr> <len>]\n");
return -1; return -1;
} }
memtype = argv[1]; enum { read_size = 256 };
static char prevmem[128] = {0x00};
if (strncmp(prevmem, memtype, strlen(memtype)) != 0) { char * memtype = argv[1];
addr = 0; AVRMEM * mem = avr_locate_mem(p, memtype);
len = 256;
strncpy(prevmem, memtype, sizeof(prevmem)-1);
prevmem[sizeof(prevmem)-1] = 0;
}
mem = avr_locate_mem(p, memtype);
if (mem == NULL) { if (mem == NULL) {
avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n", avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
memtype, p->desc); memtype, p->desc);
return -1; return -1;
} }
uint32_t maxsize = mem->size;
// Get start address if present
char * end_ptr;
static uint32_t addr = 0;
if (argc == 4) { if (argc == 4) {
addr = strtoul(argv[2], &e, 0); addr = strtoul(argv[2], &end_ptr, 0);
if (*e || (e == argv[2])) { if (*end_ptr || (end_ptr == argv[2])) {
avrdude_message(MSG_INFO, "%s (dump): can't parse address \"%s\"\n", avrdude_message(MSG_INFO, "%s (%s): can't parse address \"%s\"\n",
progname, argv[2]); progname, argv[0], argv[2]);
return -1; return -1;
} } else if (addr >= maxsize) {
avrdude_message(MSG_INFO, "%s (%s): address 0x%05lx is out of range for %s memory\n",
len = strtol(argv[3], &e, 0); progname, argv[0], addr, mem->desc);
if (*e || (e == argv[3])) {
avrdude_message(MSG_INFO, "%s (dump): can't parse length \"%s\"\n",
progname, argv[3]);
return -1; return -1;
} }
} }
maxsize = mem->size; // Get no. bytes to read if present
static int32_t len = read_size;
if (addr >= maxsize) { if (argc >= 3) {
if (argc == 2) { memset(prevmem, 0x00, sizeof(prevmem));
/* wrap around */ if (strcmp(argv[argc - 1], "...") == 0) {
if (argc == 3)
addr = 0; addr = 0;
} len = maxsize - addr;
else { } else if (argc == 4) {
avrdude_message(MSG_INFO, "%s (dump): address 0x%05lx is out of range for %s memory\n", len = strtol(argv[3], &end_ptr, 0);
progname, addr, mem->desc); if (*end_ptr || (end_ptr == argv[3])) {
avrdude_message(MSG_INFO, "%s (%s): can't parse length \"%s\"\n",
progname, argv[0], argv[3]);
return -1; return -1;
} }
} else {
len = read_size;
}
}
// No address or length specified
else if (argc == 2) {
if (strncmp(prevmem, memtype, strlen(memtype)) != 0) {
addr = 0;
len = read_size;
strncpy(prevmem, memtype, sizeof(prevmem) - 1);
prevmem[sizeof(prevmem) - 1] = 0;
}
if (addr >= maxsize)
addr = 0; // Wrap around
} }
/* trim len if nessary to not read past the end of memory */ // Trim len if nessary to not read past the end of memory
if ((addr + len) > maxsize) if ((addr + len) > maxsize)
len = maxsize - addr; len = maxsize - addr;
buf = malloc(len); uint8_t * buf = malloc(len);
if (buf == NULL) { if (buf == NULL) {
avrdude_message(MSG_INFO, "%s (dump): out of memory\n", progname); avrdude_message(MSG_INFO, "%s (dump): out of memory\n", progname);
return -1; return -1;
} }
for (i=0; i<len; i++) { for (uint32_t i = 0; i < len; i++) {
rc = pgm->read_byte(pgm, p, mem, addr+i, &buf[i]); int32_t rc = pgm->read_byte(pgm, p, mem, addr + i, &buf[i]);
if (rc != 0) { if (rc != 0) {
avrdude_message(MSG_INFO, "error reading %s address 0x%05lx of part %s\n", avrdude_message(MSG_INFO, "error reading %s address 0x%05lx of part %s\n",
mem->desc, addr + i, p->desc); mem->desc, addr + i, p->desc);
@ -315,7 +315,6 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
} }
hexdump_buf(stdout, addr, buf, len); hexdump_buf(stdout, addr, buf, len);
fprintf(stdout, "\n"); fprintf(stdout, "\n");
free(buf); free(buf);