From a838bf3af85b66de283f14243d5a3cd0b13bc801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Tue, 8 Sep 2020 20:15:40 +0200 Subject: [PATCH] Add new Flag: ERR_FLAG_SAFETY_TAB_CORRUPT --- .../reflow-controller/safety/safety-config.h | 1 + stm-firmware/safety/safety-controller.c | 97 ++++++++++++++++--- 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/stm-firmware/include/reflow-controller/safety/safety-config.h b/stm-firmware/include/reflow-controller/safety/safety-config.h index 8ad78a0..5ffbc10 100644 --- a/stm-firmware/include/reflow-controller/safety/safety-config.h +++ b/stm-firmware/include/reflow-controller/safety/safety-config.h @@ -40,6 +40,7 @@ enum safety_flag { ERR_FLAG_DEBUG = (1<<13), ERR_FLAG_TIMING_MAIN_LOOP = (1<<14), ERR_FLAG_SAFETY_MEM_CORRUPT = (1<<15), + ERR_FLAG_SAFETY_TAB_CORRUPT = (1<<16), }; enum timing_monitor { diff --git a/stm-firmware/safety/safety-controller.c b/stm-firmware/safety/safety-controller.c index 22dec1b..83a453b 100644 --- a/stm-firmware/safety/safety-controller.c +++ b/stm-firmware/safety/safety-controller.c @@ -78,10 +78,19 @@ struct safety_weight { uint32_t end_dummy; }; +struct safety_persistency { + uint32_t start_dummy; + bool persistency; + enum safety_flag flag; + volatile struct error_flag *flag_ptr; + uint32_t end_dummy; +}; + #define ERR_FLAG_ENTRY(errflag, persistency) {.name=#errflag, .flag = (errflag), .error_state = false, .error_state_inv = true, .persistent = (persistency), .key = 0UL} #define TIM_MON_ENTRY(mon, min, max, flag) {.name=#mon, .monitor = (mon), .associated_flag=(flag), .min_delta = (min), .max_delta = (max), .last = 0ULL, .enabled= false} #define ANA_MON_ENTRY(mon, min_value, max_value, flag) {.name=#mon, .monitor = (mon), .associated_flag=(flag), .min = (min_value), .max = (max_value), .value = 0.0f, .valid = false} #define ERR_FLAG_WEIGHT_ENTRY(_flag, _weight) {.flag = (_flag), .flag_ptr = NULL, .weight = (_weight), .start_dummy = 0x11823344, .end_dummy = 0xAABBCCFD} +#define ERR_FLAG_PERSIST_ENTRY(_flag, _persist) {.flag = (_flag), .flag_ptr = NULL, .persistency = (_persist), .start_dummy = 0xFF1100BB, .end_dummy = 0xEBB439A2} static volatile struct error_flag IN_SECTION(.ccm.data) flags[] = { ERR_FLAG_ENTRY(ERR_FLAG_MEAS_ADC_OFF, false), @@ -100,6 +109,7 @@ static volatile struct error_flag IN_SECTION(.ccm.data) flags[] = { ERR_FLAG_ENTRY(ERR_FLAG_DEBUG, true), ERR_FLAG_ENTRY(ERR_FLAG_TIMING_MAIN_LOOP, false), ERR_FLAG_ENTRY(ERR_FLAG_SAFETY_MEM_CORRUPT, true), + ERR_FLAG_ENTRY(ERR_FLAG_SAFETY_TAB_CORRUPT, true), }; static volatile struct timing_mon IN_SECTION(.ccm.data) timings[] = { @@ -133,10 +143,34 @@ static const struct safety_weight default_flag_weights[] = { ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_DEBUG, SAFETY_FLAG_CONFIG_WEIGHT_NONE), ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_TIMING_MAIN_LOOP, SAFETY_FLAG_CONFIG_WEIGHT_NONE), ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_SAFETY_MEM_CORRUPT, SAFETY_FLAG_CONFIG_WEIGHT_NONE), + ERR_FLAG_WEIGHT_ENTRY(ERR_FLAG_SAFETY_TAB_CORRUPT, SAFETY_FLAG_CONFIG_WEIGHT_NONE), }; +static const struct safety_persistency default_flag_persistencies[] = { + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_MEAS_ADC_OFF, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_MEAS_ADC_WATCHDOG, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_MEAS_ADC_UNSTABLE, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_MEAS_ADC_OVERFLOW, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_TIMING_MEAS_ADC, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_TIMING_PID, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_AMON_UC_TEMP, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_AMON_VREF, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_STACK, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_SAFETY_ADC, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_SYSTICK, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_WTCHDG_FIRED, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_UNCAL, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_DEBUG, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_TIMING_MAIN_LOOP, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_SAFETY_MEM_CORRUPT, false), + ERR_FLAG_PERSIST_ENTRY(ERR_FLAG_SAFETY_TAB_CORRUPT, false), +}; + +static volatile struct safety_persistency IN_SECTION(.ccm.bss) flag_persistencies[COUNT_OF(default_flag_persistencies)]; +static uint32_t IN_SECTION(.ccm.bss) flag_persistencies_crc; + static volatile struct safety_weight IN_SECTION(.ccm.bss) flag_weights[COUNT_OF(default_flag_weights)]; -static uint32_t IN_SECTION(.ccm.data) flag_weight_crc; +static uint32_t IN_SECTION(.ccm.bss) flag_weight_crc; static int flag_weight_table_crc_check(void) { @@ -150,6 +184,17 @@ static int flag_weight_table_crc_check(void) return 0; } +static int flag_persistency_table_crc_check(void) +{ + crc_unit_reset(); + crc_unit_input_array((uint32_t*)flag_persistencies, wordsize_of(flag_persistencies)); + + if (crc_unit_get_crc() != flag_persistencies_crc) + return -1; + + return 0; +} + static volatile struct error_flag *find_error_flag(enum safety_flag flag) { uint32_t i; @@ -172,7 +217,7 @@ static void init_safety_flag_weight_table_from_default(void) volatile struct safety_weight *current_weight; /* Copy the table */ - memcpy((void *)flag_weights, default_flag_weights, wordsize_of(flag_weights)); + memcpy((void *)flag_weights, default_flag_weights, sizeof(flag_weights)); /* Fill in the flag pointers */ for (index = 0; index < COUNT_OF(flag_weights); index++) { @@ -185,6 +230,25 @@ static void init_safety_flag_weight_table_from_default(void) flag_weight_crc = crc_unit_get_crc(); } +static void init_safety_flag_persistencies_from_default(void) +{ + uint32_t index; + volatile struct safety_persistency *current_persistency; + + /* Copy values */ + memcpy((void *)flag_persistencies, default_flag_persistencies, sizeof(flag_persistencies)); + + /* Fill in flag pointers */ + for (index = 0; index < COUNT_OF(flag_persistencies); index++) { + current_persistency = &flag_persistencies[index]; + current_persistency->flag_ptr = find_error_flag(current_persistency->flag); + } + + crc_unit_reset(); + crc_unit_input_array((uint32_t *)flag_persistencies, wordsize_of(flag_persistencies)); + flag_persistencies_crc = crc_unit_get_crc(); +} + static bool error_flag_get_status(const volatile struct error_flag *flag) { if (flag->error_state == flag->error_state_inv) { @@ -375,6 +439,7 @@ void safety_controller_init() stack_check_init_corruption_detect_area(); init_safety_flag_weight_table_from_default(); + init_safety_flag_persistencies_from_default(); if (found_memory_state == SAFETY_MEMORY_INIT_CORRUPTED) safety_controller_report_error(ERR_FLAG_SAFETY_MEM_CORRUPT); @@ -453,13 +518,11 @@ static void safety_controller_handle_safety_adc() /** * @brief Check the memory structures. - * @return 0 if okay, != 0 when an error was detected. PANIC mode shall be entered in this case. */ -static int safety_controller_handle_memory_checks(void) +static void safety_controller_handle_memory_checks(void) { static uint64_t ts = 0; enum safety_memory_state found_state; - int panic_request = 0; if (systick_ticks_have_passed(ts, 250)) { ts = systick_get_global_tick(); @@ -472,10 +535,18 @@ static int safety_controller_handle_memory_checks(void) } } - panic_request = flag_weight_table_crc_check(); - } + /* If flag weight table is broken, reinit to default and set flag */ + if (flag_weight_table_crc_check()) { + safety_controller_report_error(ERR_FLAG_SAFETY_TAB_CORRUPT); + init_safety_flag_weight_table_from_default(); + } - return panic_request; + /* If persistency table is broken, reinit to default and set flag */ + if(flag_persistency_table_crc_check()) { + safety_controller_report_error(ERR_FLAG_SAFETY_TAB_CORRUPT); + init_safety_flag_persistencies_from_default(); + } + } } static void safety_controller_do_systick_checking() @@ -497,21 +568,17 @@ static void safety_controller_do_systick_checking() int safety_controller_handle() { - int panic_requested; int ret = 0; safety_controller_check_stack(); safety_controller_handle_safety_adc(); - panic_requested = safety_controller_handle_memory_checks(); - - /* Panic here. If our internal structures are broken, we cannot be sure of anything anymore */ - if (panic_requested) - panic_mode(); + safety_controller_handle_memory_checks(); safety_controller_do_systick_checking(); safety_controller_process_monitor_checks(); - /* TODO: Check flags for PID and HALT */ + + /* TODO: Check flag weights and trigger appropriate safety action */ ret |= watchdog_ack(WATCHDOG_MAGIC_KEY);