From f0f9059ade2fe39267b19738846034651aac16ae Mon Sep 17 00:00:00 2001 From: MCUdude Date: Fri, 1 Apr 2022 16:52:59 +0200 Subject: [PATCH 1/5] Tweak nexttok for better string handling Now a string that starts and ends with a quote (") is combined into a single (argc) argument rather than being split where spaces used to be --- src/term.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/term.c b/src/term.c index 5961f8df..a09880fc 100644 --- a/src/term.c +++ b/src/term.c @@ -126,12 +126,19 @@ static int nexttok(char * buf, char ** tok, char ** next) q++; /* isolate first token */ - n = q+1; - while (*n && !isspace((int)*n)) + n = q; + uint8_t quotes = 0; + while (*n && (!isspace((int)*n) || quotes)) { + if (*n == '\"') + quotes++; + else if (isspace((int)*n) && *(n-1) == '\"') + break; n++; + } if (*n) { *n = 0; + avrdude_message(MSG_INFO, "q: %s\n", q); n++; } From 8f100f5df38a7542632acd40d51916415ed838d9 Mon Sep 17 00:00:00 2001 From: MCUdude Date: Fri, 1 Apr 2022 20:35:18 +0200 Subject: [PATCH 2/5] Initial support for string write --- src/term.c | 50 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/src/term.c b/src/term.c index a09880fc..604116e1 100644 --- a/src/term.c +++ b/src/term.c @@ -404,17 +404,26 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, uint8_t size; bool is_float; bool is_signed; + char * str_ptr; // Data union union { float f; int64_t ll; uint8_t a[8]; }; - } data = {.bytes_grown = 0, .size = 0, .is_float = false, .ll = 0, .is_signed = false}; + } data = { + .bytes_grown = 0, + .size = 0, + .is_float = false, + .is_signed = false, + .str_ptr = NULL, + .ll = 0 + }; for (i = start_offset; i < len + start_offset; i++) { data.is_float = false; data.size = 0; + data.str_ptr = NULL; // Handle the next argument if (i < argc - start_offset + 3) { @@ -453,10 +462,17 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, if (argv[i][0] == '\'' && argv[i][2] == '\'') { data.ll = argv[i][1]; } else { + // Try string that starts and ends with quote + if (argv[i][0] == '\"' && argv[i][strlen(argv[i]) - 1] == '\"') { + data.str_ptr = calloc(strlen(argv[i])+0x10, sizeof(char)); + strncpy(data.str_ptr, argv[i] + 1, strlen(argv[i]) - 2); + avrdude_message(MSG_INFO, "argv: %s, malloc: %s\n", argv[i], data.str_ptr); + } else { avrdude_message(MSG_INFO, "\n%s (write): can't parse data \"%s\"\n", - progname, argv[i]); + progname, argv[i]); free(buf); return -1; + } } } } @@ -491,18 +507,24 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, data.size = 1; } } - buf[i - start_offset + data.bytes_grown] = data.a[0]; - if (llabs(data.ll) > 0x000000FF || data.size >= 2 || data.is_float) - buf[i - start_offset + ++data.bytes_grown] = data.a[1]; - if (llabs(data.ll) > 0x0000FFFF || data.size >= 4 || data.is_float) { - buf[i - start_offset + ++data.bytes_grown] = data.a[2]; - buf[i - start_offset + ++data.bytes_grown] = data.a[3]; - } - if (llabs(data.ll) > 0xFFFFFFFF || data.size == 8) { - buf[i - start_offset + ++data.bytes_grown] = data.a[4]; - buf[i - start_offset + ++data.bytes_grown] = data.a[5]; - buf[i - start_offset + ++data.bytes_grown] = data.a[6]; - buf[i - start_offset + ++data.bytes_grown] = data.a[7]; + if(data.str_ptr != NULL) { + for(int16_t j = 0; j < strlen(data.str_ptr); j++) + buf[i - start_offset + data.bytes_grown++] = (uint8_t)data.str_ptr[j]; + free(data.str_ptr); + } else { + buf[i - start_offset + data.bytes_grown] = data.a[0]; + if (llabs(data.ll) > 0x000000FF || data.size >= 2 || data.is_float) + buf[i - start_offset + ++data.bytes_grown] = data.a[1]; + if (llabs(data.ll) > 0x0000FFFF || data.size >= 4 || data.is_float) { + buf[i - start_offset + ++data.bytes_grown] = data.a[2]; + buf[i - start_offset + ++data.bytes_grown] = data.a[3]; + } + if (llabs(data.ll) > 0xFFFFFFFF || data.size == 8) { + buf[i - start_offset + ++data.bytes_grown] = data.a[4]; + buf[i - start_offset + ++data.bytes_grown] = data.a[5]; + buf[i - start_offset + ++data.bytes_grown] = data.a[6]; + buf[i - start_offset + ++data.bytes_grown] = data.a[7]; + } } } From 795dd915756bfb57924c58b4725f0fd1592baadb Mon Sep 17 00:00:00 2001 From: MCUdude Date: Fri, 1 Apr 2022 22:23:55 +0200 Subject: [PATCH 3/5] Code cleanup + formatting --- src/term.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/term.c b/src/term.c index 604116e1..e9fc6de8 100644 --- a/src/term.c +++ b/src/term.c @@ -138,7 +138,6 @@ static int nexttok(char * buf, char ** tok, char ** next) if (*n) { *n = 0; - avrdude_message(MSG_INFO, "q: %s\n", q); n++; } @@ -462,13 +461,17 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, if (argv[i][0] == '\'' && argv[i][2] == '\'') { data.ll = argv[i][1]; } else { - // Try string that starts and ends with quote + // Try string that starts and ends with quotes if (argv[i][0] == '\"' && argv[i][strlen(argv[i]) - 1] == '\"') { - data.str_ptr = calloc(strlen(argv[i])+0x10, sizeof(char)); + data.str_ptr = calloc(strlen(argv[i]), sizeof(char)); + if (data.str_ptr == NULL) { + avrdude_message(MSG_INFO, "%s (write str): out of memory\n", progname); + return -1; + } + // Strip start and end quotes strncpy(data.str_ptr, argv[i] + 1, strlen(argv[i]) - 2); - avrdude_message(MSG_INFO, "argv: %s, malloc: %s\n", argv[i], data.str_ptr); } else { - avrdude_message(MSG_INFO, "\n%s (write): can't parse data \"%s\"\n", + avrdude_message(MSG_INFO, "\n%s (write): can't parse data '%s'\n", progname, argv[i]); free(buf); return -1; @@ -507,7 +510,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, data.size = 1; } } - if(data.str_ptr != NULL) { + if(data.str_ptr) { for(int16_t j = 0; j < strlen(data.str_ptr); j++) buf[i - start_offset + data.bytes_grown++] = (uint8_t)data.str_ptr[j]; free(data.str_ptr); From 17b67da03e153a344b03bf90315a1b8ee9b7c803 Mon Sep 17 00:00:00 2001 From: MCUdude Date: Mon, 4 Apr 2022 09:38:02 +0200 Subject: [PATCH 4/5] Make sure memory can be filled with a string ... and not just the last character --- src/term.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/term.c b/src/term.c index e9fc6de8..04301304 100644 --- a/src/term.c +++ b/src/term.c @@ -422,10 +422,15 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, for (i = start_offset; i < len + start_offset; i++) { data.is_float = false; data.size = 0; - data.str_ptr = NULL; // Handle the next argument if (i < argc - start_offset + 3) { + // Free string pointer if already allocated + if(data.str_ptr) { + free(data.str_ptr); + data.str_ptr = NULL; + } + // Get suffix if present char suffix = argv[i][strlen(argv[i]) - 1]; char lsuffix = argv[i][strlen(argv[i]) - 2]; @@ -474,6 +479,8 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, avrdude_message(MSG_INFO, "\n%s (write): can't parse data '%s'\n", progname, argv[i]); free(buf); + if(data.str_ptr != NULL) + free(data.str_ptr); return -1; } } @@ -513,7 +520,6 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, if(data.str_ptr) { for(int16_t j = 0; j < strlen(data.str_ptr); j++) buf[i - start_offset + data.bytes_grown++] = (uint8_t)data.str_ptr[j]; - free(data.str_ptr); } else { buf[i - start_offset + data.bytes_grown] = data.a[0]; if (llabs(data.ll) > 0x000000FF || data.size >= 2 || data.is_float) @@ -543,6 +549,9 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p, return -1; } + if(data.str_ptr) + free(data.str_ptr); + avrdude_message(MSG_NOTICE, "\nInfo: Writing %d bytes starting from address 0x%02x", len + data.bytes_grown, addr); if (write_mode == WRITE_MODE_FILL) From 08bd5fa938a9fe2b672f503b1c9641fffbefc316 Mon Sep 17 00:00:00 2001 From: MCUdude Date: Tue, 5 Apr 2022 19:37:45 +0200 Subject: [PATCH 5/5] Add string write to terminal example --- src/doc/avrdude.texi | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi index fe3f9314..ad4a6598 100644 --- a/src/doc/avrdude.texi +++ b/src/doc/avrdude.texi @@ -1553,14 +1553,16 @@ avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.01s avrdude: Device signature = 0x1e970c (probably avr128db48) -avrdude> write eeprom 0 1234567890 'A' 'V' 'R' 2.718282 ->>> write eeprom 0 1234567890 'A' 'V' 'R' 2.718282 +avrdude> write eeprom 0 1234567890 'A' 'V' 'R' 2.718282 "Hello World!" +>>> write eeprom 0 1234567890 'A' 'V' 'R' 2.718282 "Hello World!" Warning: no size suffix specified for "1234567890". Writing 4 byte(s) +Info: Writing 24 bytes starting from address 0x00 avrdude> dump eeprom 0 32 >>> dump eeprom 0 32 -0000 d2 02 96 49 41 56 52 55 f8 2d 40 ff ff ff ff ff |...IAVRU.-@.....| -0010 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| + +0000 d2 02 96 49 41 56 52 55 f8 2d 40 48 65 6c 6c 6f |...IAVRU.-@Hello| +0010 20 57 6f 72 6c 64 21 00 ff ff ff ff ff ff ff ff | World!.........| avrdude> q @end cartouche