Skip to content

Commit

Permalink
Bangle.js2: DFU update from flash now retries if CRC doesn't match
Browse files Browse the repository at this point in the history
  • Loading branch information
gfwilliams committed Oct 15, 2024
1 parent bcf744a commit c05f231
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 40 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
Bangle.js2: GPS now detects binary CASIC packets and splits them into their own GPS-raw event
Bangle.js2: Pass the modified touch event on through both E.showScroller and E.showMenu (to enable more complex interaction with menus).
Bangle.js: Add Bangle.setOptions({manualWatchdog:true}) to enable users to supply their own JS watchdog
Bangle.js2: DFU update from flash now retries if CRC doesn't match

2v24 : Bangle.js2: Add 'Bangle.touchRd()', 'Bangle.touchWr()'
Bangle.js2: After Bangle.showTestScreen, put Bangle.js into a hard off state (not soft off)
Expand Down
86 changes: 46 additions & 40 deletions targets/nrf5x_dfu/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,48 +264,54 @@ void flashDoUpdate(FlashHeader header, uint32_t headerAddr) {

__disable_irq(); // No IRQs - if we're updating bootloader it could really screw us up!

int percent = 0;
// Erase
size = header.size;
addr = header.address;
while (size>0) {
intFlashErase(addr);
addr += 4096;
size -= 4096;
percent = (addr-header.address)*120/header.size;
if (percent>120) percent=120;
xlcd_rect(60,182,60+percent,188,true);
NRF_WDT->RR[0] = 0x6E524635; // kick watchdog
}
// Write
size = header.size;
int inaddr = headerAddr + sizeof(FlashHeader);
int outaddr = header.address;
while (size>0) {
unsigned int l = size;
if (l>sizeof(buf)) l=sizeof(buf);
spiFlashReadAddr(buf, inaddr, l);
intFlashWrite(outaddr, buf, l);
inaddr += l;
outaddr += l;
size -= l;
percent = (outaddr-header.address)*120/header.size;
if (percent>120) percent=120;
xlcd_rect(60,192,60+percent,198,true);
while (true) {
int percent = 0;
// Erase
size = header.size;
addr = header.address;
while (size>0) {
intFlashErase(addr);
addr += 4096;
size -= 4096;
percent = (addr-header.address)*120/header.size;
if (percent>120) percent=120;
xlcd_rect(60,182,60+percent,188,true);
NRF_WDT->RR[0] = 0x6E524635; // kick watchdog
}
// Write
size = header.size;
int inaddr = headerAddr + sizeof(FlashHeader);
int outaddr = header.address;
while (size>0) {
unsigned int l = size;
if (l>sizeof(buf)) l=sizeof(buf);
spiFlashReadAddr(buf, inaddr, l);
intFlashWrite(outaddr, buf, l);
inaddr += l;
outaddr += l;
size -= l;
percent = (outaddr-header.address)*120/header.size;
if (percent>120) percent=120;
xlcd_rect(60,192,60+percent,198,true);
NRF_WDT->RR[0] = 0x6E524635; // kick watchdog
}
// clear progress bar
xlcd_rect(60,180,180,200,false);
// re-read all data to try and clear any caches (CRC does this anyway!)
lcd_println("CRC CHECK");
uint32_t crc = 0;
crc = crc32_compute(header.address, header.size, &crc);
NRF_WDT->RR[0] = 0x6E524635; // kick watchdog
if (crc != header.CRC) {
// if CRC failed, redo!
lcd_println("CRC FAIL! RETRY");
} else {
// otherwise we're done!
lcd_println("CRC OK");
while (true) NVIC_SystemReset(); // reset
}
}
// clear progress bar
xlcd_rect(60,180,180,200,false);
// re-read all data just to try and clear any caches
size = header.size;
outaddr = header.address;
volatile int v;
while (size--) {
v = *(char*)outaddr;
outaddr++;
}
// done!
while (true) NVIC_SystemReset(); // reset!

}

/// Return the size in bytes of a file based on the header
Expand Down

2 comments on commit c05f231

@fanoush
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wonder how do you get out of this if the CRC or file data is stored wrong when the firmware is uploaded? Imagine header.CRC is simply wrong and not matching the rest of the data - will this end in neverending loop? You also ping watchdog so no way to hold button to get out of this(?)

@gfwilliams
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If header.CRC is wrong then flashDoUpdate never gets called. There's a check earlier on - all we're doing here is checking that it's been written ok, because it seems in some instances it can fail

Please sign in to comment.