Issue #18: Fix bugs in safety memory handling

This commit is contained in:
Mario Hüttel 2020-09-05 15:56:52 +02:00
parent c9a5a2c2ff
commit 7434554319
3 changed files with 41 additions and 10 deletions

View File

@ -34,7 +34,7 @@
*/ */
#define SAFETY_MEMORY_HEADER_ADDRESS 0UL #define SAFETY_MEMORY_HEADER_ADDRESS 0UL
#define SAFETY_MEMORY_CONFIG_OVERRIDE_COUNT 512 #define SAFETY_MEMORY_CONFIG_OVERRIDE_COUNT 32UL
/** /**
* @brief Safety memory header * @brief Safety memory header
@ -91,6 +91,8 @@ struct config_override {
int safety_memory_init(enum safety_memory_state *found_state); int safety_memory_init(enum safety_memory_state *found_state);
int safety_memory_reinit(enum safety_memory_state *found_state);
int safety_memory_get_boot_status(struct safety_memory_boot_status *status); int safety_memory_get_boot_status(struct safety_memory_boot_status *status);
int safety_memory_get_error_entry_count(uint32_t *count); int safety_memory_get_error_entry_count(uint32_t *count);

View File

@ -328,6 +328,23 @@ static void safety_controller_handle_safety_adc()
} }
} }
static void safety_controller_handle_safety_memory_check(void)
{
static uint64_t ts = 0;
enum safety_memory_state found_state;
if (systick_ticks_have_passed(ts, 5000)) {
ts = systick_get_global_tick();
if (safety_memory_check()) {
safety_memory_reinit(&found_state);
if (found_state != SAFETY_MEMORY_INIT_VALID_MEMORY) {
safety_controller_report_error(ERR_FLAG_SAFETY_MEM_CORRUPT);
}
}
}
}
int safety_controller_handle() int safety_controller_handle()
{ {
static uint64_t last_systick; static uint64_t last_systick;
@ -338,6 +355,7 @@ int safety_controller_handle()
safety_controller_check_stack(); safety_controller_check_stack();
safety_controller_handle_safety_adc(); safety_controller_handle_safety_adc();
safety_controller_handle_safety_memory_check();
systick = systick_get_global_tick(); systick = systick_get_global_tick();
if (systick == last_systick) { if (systick == last_systick) {

View File

@ -71,10 +71,13 @@ static void safety_memory_write_new_header(void)
{ {
struct safety_memory_header header; struct safety_memory_header header;
header.boot_status_offset = sizeof(struct safety_memory_header); header.boot_status_offset = wordsize_of(struct safety_memory_header);
header.config_overrides_offset = header.boot_status_offset + sizeof(struct safety_memory_boot_status)/4; header.config_overrides_len = SAFETY_MEMORY_CONFIG_OVERRIDE_COUNT;
header.config_overrides_offset = header.boot_status_offset + wordsize_of(struct safety_memory_boot_status);
header.err_memory_offset = header.config_overrides_offset + SAFETY_MEMORY_CONFIG_OVERRIDE_COUNT; header.err_memory_offset = header.config_overrides_offset + SAFETY_MEMORY_CONFIG_OVERRIDE_COUNT;
header.err_memory_end = header.err_memory_offset; header.err_memory_end = header.err_memory_offset;
header.magic = SAFETY_MEMORY_MAGIC;
header.magic_i = ~SAFETY_MEMORY_MAGIC;
backup_ram_wipe(); backup_ram_wipe();
backup_ram_write_data(0UL, (uint32_t *)&header, wordsize_of(header)); backup_ram_write_data(0UL, (uint32_t *)&header, wordsize_of(header));
@ -140,7 +143,7 @@ static int safety_memory_gen_crc()
return 0; return 0;
} }
int safety_memory_init(enum safety_memory_state *found_state) int safety_memory_reinit(enum safety_memory_state *found_state)
{ {
struct safety_memory_header header; struct safety_memory_header header;
int res; int res;
@ -149,9 +152,6 @@ int safety_memory_init(enum safety_memory_state *found_state)
if (!found_state) if (!found_state)
return -1001; return -1001;
crc_unit_init();
backup_ram_init(true);
*found_state = safety_memory_get_header(&header); *found_state = safety_memory_get_header(&header);
switch (*found_state) { switch (*found_state) {
@ -162,28 +162,39 @@ int safety_memory_init(enum safety_memory_state *found_state)
*found_state = SAFETY_MEMORY_INIT_CORRUPTED; *found_state = SAFETY_MEMORY_INIT_CORRUPTED;
break; break;
case SAFETY_MEMORY_INIT_FRESH: case SAFETY_MEMORY_INIT_FRESH:
safety_memory_write_new_header();
break; break;
case SAFETY_MEMORY_INIT_CORRUPTED: case SAFETY_MEMORY_INIT_CORRUPTED:
break;
default: default:
*found_state = SAFETY_MEMORY_INIT_CORRUPTED; *found_state = SAFETY_MEMORY_INIT_CORRUPTED;
safety_memory_write_new_header();
break; break;
} }
/* Check if memory header was written newly */ /* Check if memory header has to be written */
if (*found_state != SAFETY_MEMORY_INIT_VALID_MEMORY) { if (*found_state != SAFETY_MEMORY_INIT_VALID_MEMORY) {
safety_memory_write_new_header();
/* If yes, generate new CRC checksum */ /* If yes, generate new CRC checksum */
res = safety_memory_gen_crc(); res = safety_memory_gen_crc();
if (res) if (res)
ret = -100; ret = -100;
else else
ret = 0; ret = 0;
} else {
ret = 0;
} }
return ret; return ret;
} }
int safety_memory_init(enum safety_memory_state *found_state)
{
crc_unit_init();
backup_ram_init(true);
return safety_memory_reinit(found_state);
}
int safety_memory_get_boot_status(struct safety_memory_boot_status *status); int safety_memory_get_boot_status(struct safety_memory_boot_status *status);
int safety_memory_get_error_entry_count(uint32_t *count); int safety_memory_get_error_entry_count(uint32_t *count);