diff --git a/stm-firmware/safety/safety-controller.c b/stm-firmware/safety/safety-controller.c index 42396ba..115e037 100644 --- a/stm-firmware/safety/safety-controller.c +++ b/stm-firmware/safety/safety-controller.c @@ -347,6 +347,8 @@ void safety_controller_init() /* This is usually done by the safety memory already. But, since this module also uses the CRC... */ crc_unit_init(); + stack_check_init_corruption_detect_area(); + init_safety_flag_weight_table_from_default(); if (found_memory_state == SAFETY_MEMORY_INIT_CORRUPTED) @@ -374,6 +376,10 @@ static void safety_controller_check_stack() free_stack = stack_check_get_free(); if (free_stack < SAFETY_MIN_STACK_FREE) safety_controller_report_error(ERR_FLAG_STACK); + + if (stack_check_corruption_detect_area()) { + safety_controller_report_error(ERR_FLAG_STACK); + } } static void safety_controller_handle_safety_adc() @@ -430,7 +436,7 @@ static int safety_controller_handle_memory_checks(void) enum safety_memory_state found_state; int panic_request = 0; - if (systick_ticks_have_passed(ts, 1000)) { + if (systick_ticks_have_passed(ts, 250)) { ts = systick_get_global_tick(); /* Check the safety memory */ diff --git a/stm-firmware/stack-check.c b/stm-firmware/stack-check.c index 41e55e7..d1ecb2c 100644 --- a/stm-firmware/stack-check.c +++ b/stm-firmware/stack-check.c @@ -21,6 +21,7 @@ #include #include #include +#include extern char __ld_top_of_stack; extern char __ld_end_stack; @@ -47,22 +48,27 @@ int32_t stack_check_get_free() return stack_ptr - upper_heap_boundary; } + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" + extern uint32_t __ld_start_stack_corruption_detect_area; extern uint32_t __ld_end_stack_corruption_detect_area; int stack_check_init_corruption_detect_area(void) { - volatile uint32_t *ptr = &__ld_start_stack_corruption_detect_area; - volatile uint32_t *end_ptr = &__ld_end_stack_corruption_detect_area; + uint32_t *ptr = &__ld_start_stack_corruption_detect_area; + uint32_t *end_ptr = &__ld_end_stack_corruption_detect_area; + const uint32_t area_size_in_words = &__ld_end_stack_corruption_detect_area - + &__ld_start_stack_corruption_detect_area; enum random_number_error rng_stat; uint32_t rng_number; + uint32_t crc_val; int ret = 0; - end_ptr--; - random_number_gen_init(false); - while (ptr < end_ptr) { + while (ptr < &end_ptr[-1]) { rng_stat = random_number_gen_get_number(&rng_number, true); if (rng_stat != RNG_ERROR_OK) { @@ -74,13 +80,31 @@ int stack_check_init_corruption_detect_area(void) ptr++; } + /* Init CRC unit and leave it on */ + crc_unit_init(); + crc_unit_reset(); + + crc_unit_input_array(&__ld_start_stack_corruption_detect_area, area_size_in_words - 1); + crc_val = crc_unit_get_crc(); + end_ptr[-1] = crc_val; + exit_deinit_rng: random_number_gen_deinit(); return ret; } +#pragma GCC diagnostic pop + int stack_check_corruption_detect_area(void) { - + const uint32_t area_size_in_words = &__ld_end_stack_corruption_detect_area - + &__ld_start_stack_corruption_detect_area; + crc_unit_reset(); + crc_unit_input_array(&__ld_start_stack_corruption_detect_area, area_size_in_words); + if (crc_unit_get_crc() == 0UL) { + return 0; + } else { + return -1; + } } diff --git a/stm-firmware/stm32f407vet6_flash.ld b/stm-firmware/stm32f407vet6_flash.ld index bbb2809..10e0d90 100644 --- a/stm-firmware/stm32f407vet6_flash.ld +++ b/stm-firmware/stm32f407vet6_flash.ld @@ -25,7 +25,7 @@ /* USER PARAMETERS */ __ld_stack_size = 0x3000; __ld_heap_size = 0x2100; -__stack_corruption_area_size = 64; +__stack_corruption_area_size = 128; /* END OF USER PARAMETERS */ ENTRY(Reset_Handler) @@ -151,12 +151,12 @@ SECTIONS __ld_sheap = .; . = . + __ld_heap_size; __ld_eheap = .; - . = ALIGN(4) + . = ALIGN(4); __ld_start_stack_corruption_detect_area = .; . = . + __stack_corruption_area_size; . = ALIGN(4); __ld_end_stack_corruption_detect_area = .; - __ld_end_stack = . + __ld_end_stack = .; . = . + __ld_stack_size; . = ALIGN(4); } >RAM