diff --git a/firmware/hw_layer/ports/at32/at32_common.cpp b/firmware/hw_layer/ports/at32/at32_common.cpp index 576374bd48..d5531c13f2 100644 --- a/firmware/hw_layer/ports/at32/at32_common.cpp +++ b/firmware/hw_layer/ports/at32/at32_common.cpp @@ -138,6 +138,13 @@ void baseMCUInit(void) { BOR_Set(BOR_Level_1); // one step above default value } +void causeHardFault() { + // Set the function pointer to an invalid address + void (*invalidFunction)() = (void(*)())0xDEADBEEF; + // Calling the invalid function will trigger a hard fault + invalidFunction(); +} + /* used to detect additional RAM available for LUA * TODO: find RAM on AT32 * TODO: better name */ diff --git a/firmware/hw_layer/ports/cypress/mpu_util.cpp b/firmware/hw_layer/ports/cypress/mpu_util.cpp index deabdc280a..d8eb973c27 100644 --- a/firmware/hw_layer/ports/cypress/mpu_util.cpp +++ b/firmware/hw_layer/ports/cypress/mpu_util.cpp @@ -24,6 +24,13 @@ extern "C" { void baseMCUInit(void) { } +void causeHardFault() { + // Set the function pointer to an invalid address + void (*invalidFunction)() = (void(*)())0xDEADBEEF; + // Calling the invalid function will trigger a hard fault + invalidFunction(); +} + void _unhandled_exception(void) { /*lint -restore*/ diff --git a/firmware/hw_layer/ports/kinetis/mpu_util.cpp b/firmware/hw_layer/ports/kinetis/mpu_util.cpp index 939f843654..25ac4b1c85 100644 --- a/firmware/hw_layer/ports/kinetis/mpu_util.cpp +++ b/firmware/hw_layer/ports/kinetis/mpu_util.cpp @@ -16,6 +16,13 @@ void baseMCUInit(void) { } +void causeHardFault() { + // Set the function pointer to an invalid address + void (*invalidFunction)() = (void(*)())0xDEADBEEF; + // Calling the invalid function will trigger a hard fault + invalidFunction(); +} + void _unhandled_exception(void) { /*lint -restore*/ diff --git a/firmware/hw_layer/ports/mpu_util.h b/firmware/hw_layer/ports/mpu_util.h index 306ab747cd..e0474f22c9 100644 --- a/firmware/hw_layer/ports/mpu_util.h +++ b/firmware/hw_layer/ports/mpu_util.h @@ -12,6 +12,7 @@ void jump_to_bootloader(); #if EFI_USE_OPENBLT void jump_to_openblt(); #endif +void causeHardFault(); bool allowFlashWhileRunning(); bool ramReadProbe(volatile const char *read_address); diff --git a/firmware/hw_layer/ports/stm32/stm32_common.cpp b/firmware/hw_layer/ports/stm32/stm32_common.cpp index b1338af677..d671c361b4 100644 --- a/firmware/hw_layer/ports/stm32/stm32_common.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_common.cpp @@ -110,6 +110,15 @@ void baseMCUInit(void) { BOR_Set(BOR_Level_1); // one step above default value } +void causeHardFault() { +#if EFI_PROD_CODE + // Set the function pointer to an invalid address + void (*invalidFunction)() = (void(*)())0xDEADBEEF; + // Calling the invalid function will trigger a hard fault + invalidFunction(); +#endif /* EFI_PROD_CODE */ +} + extern uint32_t __main_stack_base__; typedef struct port_intctx intctx_t; diff --git a/simulator/simulator/mpu_util.h b/simulator/simulator/mpu_util.h index bc80537b26..ff2a572a84 100644 --- a/simulator/simulator/mpu_util.h +++ b/simulator/simulator/mpu_util.h @@ -7,3 +7,4 @@ static bool isValidCanRxPin(brain_pin_e) { return true; } #endif // HAL_USE_CAN static bool allowFlashWhileRunning() { return true; } +static void causeHardFault() { }