diff --git a/stm-firmware/safety/safety-controller.c b/stm-firmware/safety/safety-controller.c index d7f72c9..612afe5 100644 --- a/stm-firmware/safety/safety-controller.c +++ b/stm-firmware/safety/safety-controller.c @@ -349,7 +349,13 @@ static void safety_controller_process_active_timing_mons() } } -static void safety_controller_process_monitor_checks() +/** + * @brief safety_controller_process_monitor_checks + * Process the analog and timing monitors and set the relevant flags in case of a monitor outside its limits. + * + * The checking of the analog monitors will only be armed after a startup delay of 1000 ms to allow the values to stabilize. + */ +static void safety_controller_process_monitor_checks(void) { static bool startup_completed = false; enum analog_monitor_status amon_state; @@ -359,6 +365,8 @@ static void safety_controller_process_monitor_checks() startup_completed = true; if (startup_completed) { + + amon_state = safety_controller_get_analog_mon_value(ERR_AMON_VREF, &amon_value); if (amon_state != ANALOG_MONITOR_OK) safety_controller_report_error(ERR_FLAG_AMON_VREF); @@ -373,6 +381,18 @@ static void safety_controller_process_monitor_checks() safety_controller_process_active_timing_mons(); } +/** + * @brief Internal function for setting an error flag + * + * Multiple flags can be ored together to set them in one go. + * The provided key will be set on all of the flags in order to prevent them from being reset by + * unauthorized code. If nop key shall be used, set key to zero. + * + * @param flag Enum of the flags to set. This can be an ORed value of multiple error flags. + * @param key The kex to set on the flag. + * @param prevent_error_mem_enty Prevent the flag from being stored in the error memory. + * @return 0 if successful. + */ static int report_error(enum safety_flag flag, uint32_t key, bool prevent_error_mem_enty) { uint32_t i; @@ -484,6 +504,15 @@ static int get_safety_flags_from_error_mem(enum safety_flag *flags) return 0; } +/** + * @brief Initialize the GPIOs for the external hardware watchdog. + * + * The external harware watchdog has to be periodically reset or it will reset hte controller. + * Because debugging is not possible, when the watchdog is active, it is only activated, if the application is + * compiled in release mode. Any interruption of the main programm will then trigger the internal and/or the external watchdog. + * + * @note When enabled, execute the @ref external_watchdog_toggle function to reset the external watchdog. + */ static void safety_controller_init_external_watchdog() { rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(SAFETY_EXT_WATCHDOG_RCC_MASK)); @@ -550,6 +579,15 @@ void safety_controller_init() #endif } +/** + * @brief Check the processor's stack + * + * This function checks the Stack of the application. + * The check consists of 2 parts: + * + * 1) Checking the remaining free space at the moment between stack pointer and top of heap. + * 2) Checking The CRC of the corruption detect area between heap and stack + */ static void safety_controller_check_stack() { int32_t free_stack; @@ -563,6 +601,21 @@ static void safety_controller_check_stack() } } +/** + * @brief Handle the Safety ADC + * + * This function handles the safety ADC. + * If the safety ADC ius not executing a measurment and the time since the last measurement has + * passed @ref SAFETY_CONTROLLER_ADC_DELAY_MS, the safety ADC is retriggered and will automatically perform a measurement + * on all of its channels. + * When called again, this function will retrieve the data from the safety ADC and converts it into the + * appropriate analog values for the analog value monitors. + * + * The safety ADC is configured to perform multiple measurmeents of each physical channel. Therefore, this function + * fist calculated the mean value before converting them into the physical values. + * + * The channels, the ssafety ADC will convert is defined in its header file using the define @ref SAFETY_ADC_CHANNELS. + */ static void safety_controller_handle_safety_adc() { static uint64_t last_result_timestamp = 0; @@ -610,7 +663,17 @@ static void safety_controller_handle_safety_adc() } /** - * @brief Check the memory structures. + * @brief Check the memory structures + * + * This function checks multiple memory structures. + * + * 1) The safety memory in the backup RAM is checked using @ref safety_memory_check. + * In case of an error, the safety memory is reinitialized and the @ref ERR_FLAG_SAFETY_MEM_CORRUPT + * flag is set. + * 2) The flag weight table is CRC checked. In case of an error, the @ref ERR_FLAG_SAFETY_TAB_CORRUPT flag is set. + * Aditionally, the default flag weights are restored from Flash. + * 3) The flag persistency table is CRC checked. In case of an error, the @ref ERR_FLAG_SAFETY_TAB_CORRUPT flag is set. + * Aditionally, the default values of the flag persistence is restored from Flash. */ static void safety_controller_handle_memory_checks(void) { @@ -642,6 +705,12 @@ static void safety_controller_handle_memory_checks(void) } } +/** + * @brief Check if the systick is ticking. + * + * If the systick stays constant for more than 1000 calls of this function, + * the @ref ERR_FLAG_SYSTICK flag is set. + */ static void safety_controller_do_systick_checking() { static uint64_t last_systick; @@ -659,6 +728,12 @@ static void safety_controller_do_systick_checking() last_systick = systick; } +/** + * @brief Handle weightet flags. + * + * This functions loops oer all weight entries and checks the corresponding flags. If a flag + * is set, the appropriate action defined by the flag weight is executed. + */ static void safety_controller_handle_weighted_flags() { uint32_t weight_index;