From 3943e0dc0fc68a76de356cad04d06fe5f59d88a3 Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 25 Aug 2026 18:42:36 +0200 Subject: [PATCH 1/8] Localise variable definition --- src/avr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/avr.c b/src/avr.c index a5105f5c..3140ca4e 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1355,7 +1355,6 @@ int avr_verify(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, const } int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, const AVRMEM *a, int size) { - int i; unsigned char *buf1, *buf2; int vsize; AVRMEM *b; @@ -1382,7 +1381,7 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co int verror = 0, vroerror = 0, maxerrs = verbose >= MSG_DEBUG? size + 1: 10; int ro = mem_is_readonly(a); // Other memories can have known protected zones such as bootloaders - for(i = 0; i < size; i++) { + for(int i = 0; i < size; i++) { if((b->tags[i] & TAG_ALLOCATED) != 0 && buf1[i] != buf2[i]) { uint8_t bitmask = is_isp(p)? get_fuse_bitmask(a): avr_mem_bitmask(p, a, i); From e202a5c4011b66c8c33efe40fd6810c64bae7c85 Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 25 Aug 2026 18:54:39 +0200 Subject: [PATCH 2/8] Allow verification loop to finish --- src/avr.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/avr.c b/src/avr.c index 3140ca4e..4a8ea64f 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1378,7 +1378,7 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co size = vsize; } - int verror = 0, vroerror = 0, maxerrs = verbose >= MSG_DEBUG? size + 1: 10; + int verror = 0, vroerror = 0, maxerrs = verbose >= MSG_DEBUG? size: verbose >= MSG_NOTICE? 10: 1; int ro = mem_is_readonly(a); // Other memories can have known protected zones such as bootloaders for(int i = 0; i < size; i++) { @@ -1407,8 +1407,6 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co imsg_warning(" suppressing further verification errors\n"); } verror++; - if(verbose < MSG_NOTICE) - return -1; } else { // Mismatch is only in unused bits if((buf1[i] | bitmask) != 0xff) { From d73b66fbe928027934333c7d121cba3c058264d1 Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 25 Aug 2026 18:57:00 +0200 Subject: [PATCH 3/8] Remove superfluous headline --- src/avr.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/avr.c b/src/avr.c index 4a8ea64f..00a0aae5 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1387,25 +1387,18 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co if(ro || (pgm->readonly && pgm->readonly(pgm, p, a, i))) { if(quell_progress < 2) { - if(vroerror < 10) { - if(!(verror + vroerror)) - pmsg_warning("%s verification mismatch%s\n", a->desc, - mem_is_in_flash(a)? " in r/o areas, expected for vectors and/or bootloader": ""); - imsg_warning(" device 0x%02x != input 0x%02x at addr 0x%04x " - "(read only location: ignored)\n", buf1[i], buf2[i], i); - } else if(vroerror == 10) + if(vroerror < 10) + imsg_warning(" device 0x%02x != input 0x%02x at addr 0x%04x (read-only location: ignored)\n", buf1[i], buf2[i], i); + else if(vroerror == 10) imsg_warning(" suppressing further mismatches in read-only areas\n"); } vroerror++; } else if((buf1[i] & bitmask) != (buf2[i] & bitmask)) { // Mismatch is not just in unused bits - if(verror < maxerrs) { - if(!(verror + vroerror)) - pmsg_warning("%s verification mismatch\n", a->desc); + if(verror < maxerrs) imsg_error(" device 0x%02x != input 0x%02x at addr 0x%04x (error)\n", buf1[i], buf2[i], i); - } else if(verror == maxerrs) { + else if(verror == maxerrs) imsg_warning(" suppressing further verification errors\n"); - } verror++; } else { // Mismatch is only in unused bits From 49d04b598a27eddc671812aad01da495872020c3 Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 25 Aug 2026 19:00:13 +0200 Subject: [PATCH 4/8] Change detailed verification output to msg_info() --- src/avr.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/avr.c b/src/avr.c index 00a0aae5..53db6c11 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1386,19 +1386,17 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co uint8_t bitmask = is_isp(p)? get_fuse_bitmask(a): avr_mem_bitmask(p, a, i); if(ro || (pgm->readonly && pgm->readonly(pgm, p, a, i))) { - if(quell_progress < 2) { - if(vroerror < 10) - imsg_warning(" device 0x%02x != input 0x%02x at addr 0x%04x (read-only location: ignored)\n", buf1[i], buf2[i], i); - else if(vroerror == 10) - imsg_warning(" suppressing further mismatches in read-only areas\n"); - } + if(vroerror < 10) + imsg_info(" device 0x%02x != input 0x%02x at addr 0x%04x (read-only location: ignored)\n", buf1[i], buf2[i], i); + else if(vroerror == 10) + imsg_info(" suppressing further mismatches in read-only areas\n"); vroerror++; } else if((buf1[i] & bitmask) != (buf2[i] & bitmask)) { // Mismatch is not just in unused bits if(verror < maxerrs) - imsg_error(" device 0x%02x != input 0x%02x at addr 0x%04x (error)\n", buf1[i], buf2[i], i); + imsg_info(" device 0x%02x != input 0x%02x at addr 0x%04x (error)\n", buf1[i], buf2[i], i); else if(verror == maxerrs) - imsg_warning(" suppressing further verification errors\n"); + imsg_info(" suppressing further verification errors\n"); verror++; } else { // Mismatch is only in unused bits From fa4816941e07a61f71c16ad3f9742471b68e01d2 Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 25 Aug 2026 19:10:39 +0200 Subject: [PATCH 5/8] Change message for showing no further verification mismatches --- src/avr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/avr.c b/src/avr.c index 53db6c11..6ecadc73 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1389,14 +1389,14 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co if(vroerror < 10) imsg_info(" device 0x%02x != input 0x%02x at addr 0x%04x (read-only location: ignored)\n", buf1[i], buf2[i], i); else if(vroerror == 10) - imsg_info(" suppressing further mismatches in read-only areas\n"); + imsg_info(" showing no further mismatches in read-only areas\n"); vroerror++; } else if((buf1[i] & bitmask) != (buf2[i] & bitmask)) { // Mismatch is not just in unused bits if(verror < maxerrs) imsg_info(" device 0x%02x != input 0x%02x at addr 0x%04x (error)\n", buf1[i], buf2[i], i); else if(verror == maxerrs) - imsg_info(" suppressing further verification errors\n"); + imsg_info(" showing no further verification errors (increase verbosity for more)\n"); verror++; } else { // Mismatch is only in unused bits From cafb12edaf3ae499ed477fd893200efc77fce79f Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 25 Aug 2026 19:19:33 +0200 Subject: [PATCH 6/8] Count number of bit errors --- src/avr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/avr.c b/src/avr.c index 6ecadc73..c0cc1f32 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1380,6 +1380,8 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co int verror = 0, vroerror = 0, maxerrs = verbose >= MSG_DEBUG? size: verbose >= MSG_NOTICE? 10: 1; int ro = mem_is_readonly(a); // Other memories can have known protected zones such as bootloaders + int biterrs = 0, bitsset = 0; + unsigned int bdiff; for(int i = 0; i < size; i++) { if((b->tags[i] & TAG_ALLOCATED) != 0 && buf1[i] != buf2[i]) { @@ -1391,8 +1393,13 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co else if(vroerror == 10) imsg_info(" showing no further mismatches in read-only areas\n"); vroerror++; - } else if((buf1[i] & bitmask) != (buf2[i] & bitmask)) { - // Mismatch is not just in unused bits + } else if((bdiff = (buf1[i] & bitmask) ^ (buf2[i] & bitmask))) { + // Mismatch is not just in unused bits, loop over bit positions that differ + for(unsigned int lbit; bdiff; bdiff ^= lbit) { + lbit = bdiff & -bdiff; // Lowest bit that differs + biterrs++; // Number of bit mismatches + bitsset += !!(lbit & buf1[i]); // The mismatched bit was set on device + } if(verror < maxerrs) imsg_info(" device 0x%02x != input 0x%02x at addr 0x%04x (error)\n", buf1[i], buf2[i], i); else if(verror == maxerrs) From 01a5656208b21d6bda94a27cb6e2b24d955a7b71 Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 25 Aug 2026 19:57:12 +0200 Subject: [PATCH 7/8] Display statistics of verification errors --- src/avr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/avr.c b/src/avr.c index c0cc1f32..e5d68ef6 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1421,6 +1421,11 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co } } } + if(verror) + imsg_info(" %d byte%s do not match caused by %d bit error%s of which %d set and %d cleared on device\n", + verror, str_plural(verror), biterrs, str_plural(biterrs), bitsset, biterrs-bitsset); + if(verror && bitsset == 0 && mem_is_in_flash(a)) + imsg_info(" maybe flash was not erased beforehand or flash programming sections overlap?\n"); return verror? -1: size; } From d361c843ec2ea6de9fc8045378210c4af7aa2ae3 Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 25 Aug 2026 20:05:37 +0200 Subject: [PATCH 8/8] Fix grammar for single byte errors --- src/avr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/avr.c b/src/avr.c index e5d68ef6..98ba37ac 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1422,8 +1422,8 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co } } if(verror) - imsg_info(" %d byte%s do not match caused by %d bit error%s of which %d set and %d cleared on device\n", - verror, str_plural(verror), biterrs, str_plural(biterrs), bitsset, biterrs-bitsset); + imsg_info(" %d byte%s do%s not match caused by %d bit error%s of which %d set and %d cleared on device\n", + verror, str_plural(verror), verror > 1? "": "es", biterrs, str_plural(biterrs), bitsset, biterrs-bitsset); if(verror && bitsset == 0 && mem_is_in_flash(a)) imsg_info(" maybe flash was not erased beforehand or flash programming sections overlap?\n");