Skip to content

Instantly share code, notes, and snippets.

@tridge
Created January 14, 2024 22:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tridge/8658ff7b351c5823d3b12ecec1bf5190 to your computer and use it in GitHub Desktop.
Save tridge/8658ff7b351c5823d3b12ecec1bf5190 to your computer and use it in GitHub Desktop.
/*
create a thread that checks for ECC errors in flash. We disable
fault IRQs in the thread and monitor it from the main thread. If it
doesn't complete in 1s then erase flash This is the only way I've
found to check for ECC errors without causing a bus fault or
unconditionally erasing flash
*/
struct ecccheck {
const uint32_t *start;
uint32_t size;
uint32_t sum;
bool done;
};
static void ecccheck_thread(void *arg)
{
auto *m = (struct ecccheck *)arg;
const uint32_t *p = m->start;
__disable_fault_irq();
for (uint32_t i=0; i<m->size/4; i++) {
m->sum += *p++;
}
__enable_fault_irq();
m->done = true;
}
void check_ecc_errors(void)
{
struct ecccheck m {};
m.start = (const uint32_t *)FLASH_BASE;
m.size = BOARD_FLASH_SIZE*1024;
auto *thd = chThdCreateFromHeap(NULL, 1024, "ECC_check", 1, ecccheck_thread, &m);
for (uint32_t i=0; i<1000; i++) {
thread_sleep_ms(1);
if (m.done) {
break;
}
}
if (!m.done) {
// we must have ECC errors in flash blocking the read. Erase
// flash
flash_set_keep_unlocked(true);
uint32_t page = 0;
while (stm32_flash_erasepage(flash_base_page+(page++))) ;
flash_set_keep_unlocked(false);
thread_sleep_ms(100);
}
chThdRelease(thd);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment