Continuous flash memory integrity check running on background

Create a new, low priority thread that checks that the CRC of the
flash memory matches the CRC stored in flash.

8kB chunks are computed every 50 milliseconds. A reset is invoked if
CRC does not match.

Signed-off-by: Marcos Chaparro <mchaparro@powerdesigns.ca>
This commit is contained in:
Marcos Chaparro 2019-04-17 20:54:08 -03:00
parent 68ee05ea9c
commit 4fceb73db9
3 changed files with 51 additions and 4 deletions

View File

@ -56,11 +56,11 @@
#define APP_CRC_WAS_CALCULATED_FLAG ((uint32_t)0xAAAAAAAA)
#define APP_CRC_WAS_CALCULATED_FLAG_ADDRESS (uint32_t*)(APP_MAX_SIZE - 8)
#define VECTOR_TABLE_ADDRESS (uint32_t *)ADDR_FLASH_SECTOR_0
#define VECTOR_TABLE_SIZE (ADDR_FLASH_SECTOR_1 - ADDR_FLASH_SECTOR_0)
#define VECTOR_TABLE_ADDRESS ((uint32_t *)ADDR_FLASH_SECTOR_0)
#define VECTOR_TABLE_SIZE ((uint32_t)(ADDR_FLASH_SECTOR_1 - ADDR_FLASH_SECTOR_0))
#define APP_START_ADDRESS (uint32_t *)(ADDR_FLASH_SECTOR_1 + EEPROM_EMULATION_SIZE)
#define APP_SIZE (APP_MAX_SIZE - VECTOR_TABLE_SIZE - EEPROM_EMULATION_SIZE)
#define APP_START_ADDRESS ((uint32_t *)(ADDR_FLASH_SECTOR_1 + EEPROM_EMULATION_SIZE))
#define APP_SIZE ((uint32_t)(APP_MAX_SIZE - VECTOR_TABLE_SIZE - EEPROM_EMULATION_SIZE))
// Private constants
static const uint32_t flash_addr[FLASH_SECTORS] = {
@ -274,3 +274,32 @@ uint32_t flash_helper_verify_flash_memory(void) {
return FAULT_CODE_NONE;
}
}
uint32_t flash_helper_verify_flash_memory_chunk(void) {
static uint32_t index = 0;
const uint32_t chunk_size = 8192;
uint32_t res = FAULT_CODE_NONE;
uint32_t crc = 0;
// Make sure RCC_AHB1Periph_CRC is enabled
if (index == 0) {
crc32_reset();
}
if (index < VECTOR_TABLE_SIZE) {
crc32((VECTOR_TABLE_ADDRESS + index), chunk_size/4);
}
else {
crc = crc32((uint32_t*)((uint32_t)APP_START_ADDRESS + index - VECTOR_TABLE_SIZE), chunk_size/4);
}
index += chunk_size;
if (index >= (VECTOR_TABLE_SIZE + APP_SIZE)) {
index = 0;
if (crc != 0) {
res = FAULT_CODE_FLASH_CORRUPTION;
}
}
return res;
}

View File

@ -28,5 +28,6 @@ uint16_t flash_helper_write_new_app_data(uint32_t offset, uint8_t *data, uint32_
void flash_helper_jump_to_bootloader(void);
uint8_t* flash_helper_get_sector_address(uint32_t fsector);
uint32_t flash_helper_verify_flash_memory(void);
uint32_t flash_helper_verify_flash_memory_chunk(void);
#endif /* FLASH_HELPER_H_ */

17
main.c
View File

@ -75,6 +75,22 @@
// Private variables
static THD_WORKING_AREA(periodic_thread_wa, 1024);
static THD_WORKING_AREA(timer_thread_wa, 128);
static THD_WORKING_AREA(flash_integrity_check_thread_wa, 1024);
static THD_FUNCTION(flash_integrity_check_thread, arg) {
(void)arg;
chRegSetThreadName("Flash integrity check");
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
for(;;) {
if (flash_helper_verify_flash_memory_chunk() == FAULT_CODE_FLASH_CORRUPTION) {
NVIC_SystemReset();
}
chThdSleepMilliseconds(50);
}
}
static THD_FUNCTION(periodic_thread, arg) {
(void)arg;
@ -245,6 +261,7 @@ int main(void) {
// Threads
chThdCreateStatic(periodic_thread_wa, sizeof(periodic_thread_wa), NORMALPRIO, periodic_thread, NULL);
chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL);
chThdCreateStatic(flash_integrity_check_thread_wa, sizeof(flash_integrity_check_thread_wa), LOWPRIO, flash_integrity_check_thread, NULL);
#if WS2811_TEST
unsigned int color_ind = 0;