Skip to content

Commit

Permalink
Add error checking both before and after flashing
Browse files Browse the repository at this point in the history
Before we start flashing then do a crc32 check on all payloads so if
the reloader hasn't been programmed correctly we don't proceed.

After flashing we check that what we wrote and retry if it doesn't
match.

Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
  • Loading branch information
daniel-thompson committed Jun 11, 2020
1 parent 6c403fb commit 2888b28
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 7 deletions.
46 changes: 43 additions & 3 deletions src/flash.c
Expand Up @@ -5,6 +5,8 @@

#include "flash.h"

#include <string.h>

#include <nrfx_nvmc.h>
#include <nrf_gpio.h>
#include <nrf_wdt.h>
Expand All @@ -17,7 +19,7 @@ static int percent_complete;
static uint32_t bytes_processed;
static uint32_t total_bytes;

static void progress(uint32_t nbytes)
static void progress(int32_t nbytes)
{
bytes_processed += nbytes;

Expand All @@ -28,13 +30,40 @@ static void progress(uint32_t nbytes)
}
}

/* slow but no table overhead ;-) */
uint32_t crc32(const uint8_t *data, uint32_t len)
{
uint32_t crc = 0xffffffff;

for (int i=0; i<len; i++) {
crc = crc ^ data[i];
for (int j=0; j<8; j++)
crc = (crc >> 1) ^ (0xedb88320 & -(crc & 1));
}
return ~crc;
}

static uint32_t check_segment(const struct segment *sg)
{
uint32_t sz = sg->end - sg->start;

if (sg->crc32 != crc32(sg->data, sz))
panic();

return sz;
}

static void flash_segment(const struct segment *sg)
{
uint32_t pagesz = nrfx_nvmc_flash_page_size_get();
uint32_t sz = sg->end - sg->start;
int retries = 5;

retry:

/* TODO: Haven't got code to handle the UICR yet */
if (sg->start >= 0x1000000) {
progress(sg->end - sg->start);
progress(2 * sz);
return;
}

Expand All @@ -50,6 +79,17 @@ static void flash_segment(const struct segment *sg)
((uint32_t *) sg->data)[(addr - sg->start) / 4]);
progress(4);
}

if (0 != memcmp((void *) sg->start, sg->data, sz)) {
progress(-(2 * sz));
if (retries--)
goto retry;

// We're in big trouble... the system is probably bricked but we
// don't seem to be able to do anything about it. Better to reboot
// and hope than to sit here wearing out the flash!
panic();
}
}

void flash_all(void)
Expand All @@ -61,7 +101,7 @@ void flash_all(void)
report_progress(0);

for (int i=0; i<lengthof(segments); i++)
total_bytes += 2 * (segments[i].end - segments[i].start);
total_bytes += 2 * check_segment(segments + i);

for (int i=0; i<lengthof(segments); i++)
flash_segment(segments + i);
Expand Down
19 changes: 16 additions & 3 deletions src/main.c
Expand Up @@ -9,8 +9,23 @@
#include "board.h"
#include "flash.h"
#include "st7789.h"
#include "util.h"
#include "wdt.h"

void panic(void)
{
#ifdef CONFIG_ST7789
st7789_state(-1);
#endif
reboot();
}

void reboot(void)
{
while (true)
/* stop feeding the dog and we'll automatically reboot */;
}

void report_progress(int percent)
{
#ifdef CONFIG_ST7789
Expand All @@ -35,9 +50,7 @@ int main()
#endif

flash_all();

while (true)
/* stop feeding the dog and we'll automatically reboot */;
reboot();

return 0;
}
9 changes: 8 additions & 1 deletion src/st7789.c
Expand Up @@ -228,6 +228,13 @@ void st7789_state(int percent_complete)
const uint16_t bg = 0;
uint16_t color = bg;

if (percent_complete < 0)
fg = 0xf800;
else if (percent_complete < 100)
fg = 0x033f;
else
fg = 0xffff;

for (int i=0; i<sizeof(rle); i++) {
uint8_t rl = rle[i];
while (rl) {
Expand All @@ -247,7 +254,7 @@ void st7789_state(int percent_complete)
if (bottomclip) {
memset(linebuffer+2*(240-64), 0, 64*2);
}
if (y >= (165-percent_complete)) {
if (percent_complete >= 1 && y >= (165-percent_complete)) {
fg = 0xffff;
}

Expand Down
2 changes: 2 additions & 0 deletions src/util.h
Expand Up @@ -8,6 +8,8 @@

#define lengthof(x) (sizeof(x) / sizeof((x)[0]))

void panic(void);
void reboot(void);
void report_progress(int percent);

#endif /* RELOADER_UTIL_H__ */

0 comments on commit 2888b28

Please sign in to comment.