Created
January 14, 2024 22:17
-
-
Save tridge/516ea9c19c5548505e14dec127ce6979 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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++) { | |
/* | |
when we have an ECC double error the ldr in the following | |
line keeps repeating forever. The parent thread should then | |
timeout waiting for this thread to complete and will erase | |
all of flash, allowing the user to load a new firmware. | |
Unfortunately it doesn't work as ChibiOS never schedules the | |
parent thread again while this lower priority thread is | |
stuck executing this ldr, so it doesn't work | |
*/ | |
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", 2, 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