diff --git a/platform/mbed_interface.h b/platform/mbed_interface.h index 279eca727d9..cb90c95e3bf 100644 --- a/platform/mbed_interface.h +++ b/platform/mbed_interface.h @@ -168,7 +168,7 @@ void mbed_error_vprintf(const char *format, va_list arg) MBED_PRINTF(1, 0); * FileHandle::write of the stderr device is. The default * serial console is safe, either buffered or not. If the * console has not previously been initialized, an attempt - * to use this from interrupt may during console initialization. + * to use this from interrupt may crash during console initialization. * Special handling of `mbed_error` relaxes various system traps * to increase the chance of initialization working. * diff --git a/platform/source/TARGET_CORTEX_M/mbed_fault_handler.c b/platform/source/TARGET_CORTEX_M/mbed_fault_handler.c index 615842fc6f7..293742fd89e 100644 --- a/platform/source/TARGET_CORTEX_M/mbed_fault_handler.c +++ b/platform/source/TARGET_CORTEX_M/mbed_fault_handler.c @@ -21,6 +21,7 @@ #include #include "device.h" +#include "mbed_atomic.h" #include "mbed_error.h" #include "mbed_interface.h" #include "mbed_crash_data_offsets.h" @@ -39,41 +40,49 @@ mbed_fault_context_t fault_context; mbed_fault_context_t *const mbed_fault_context = &fault_context; #endif +extern bool mbed_error_in_progress; + //This is a handler function called from Fault handler to print the error information out. //This runs in fault context and uses special functions(defined in mbed_rtx_fault_handler.c) to print the information without using C-lib support. void mbed_fault_handler(uint32_t fault_type, const mbed_fault_context_t *mbed_fault_context_in) { mbed_error_status_t faultStatus = MBED_SUCCESS; - mbed_error_printf("\n++ MbedOS Fault Handler ++\n\nFaultType: "); - - switch (fault_type) { - case MEMMANAGE_FAULT_EXCEPTION: - mbed_error_printf("MemManageFault"); - faultStatus = MBED_ERROR_MEMMANAGE_EXCEPTION; - break; - - case BUS_FAULT_EXCEPTION: - mbed_error_printf("BusFault"); - faultStatus = MBED_ERROR_BUSFAULT_EXCEPTION; - break; - - case USAGE_FAULT_EXCEPTION: - mbed_error_printf("UsageFault"); - faultStatus = MBED_ERROR_USAGEFAULT_EXCEPTION; - break; - - //There is no way we can hit this code without getting an exception, so we have the default treated like hardfault - case HARD_FAULT_EXCEPTION: - default: - mbed_error_printf("HardFault"); - faultStatus = MBED_ERROR_HARDFAULT_EXCEPTION; - break; - } - mbed_error_printf("\n\nContext:"); - print_context_info(); + /* Need to set the flag to ensure prints do not trigger a "mutex in ISR" trap + * if they're first prints since boot and we have to init the I/O system. + */ + if (!core_util_atomic_exchange_bool(&mbed_error_in_progress, true)) { + mbed_error_printf("\n++ MbedOS Fault Handler ++\n\nFaultType: "); + + switch (fault_type) { + case MEMMANAGE_FAULT_EXCEPTION: + mbed_error_printf("MemManageFault"); + faultStatus = MBED_ERROR_MEMMANAGE_EXCEPTION; + break; + + case BUS_FAULT_EXCEPTION: + mbed_error_printf("BusFault"); + faultStatus = MBED_ERROR_BUSFAULT_EXCEPTION; + break; + + case USAGE_FAULT_EXCEPTION: + mbed_error_printf("UsageFault"); + faultStatus = MBED_ERROR_USAGEFAULT_EXCEPTION; + break; + + //There is no way we can hit this code without getting an exception, so we have the default treated like hardfault + case HARD_FAULT_EXCEPTION: + default: + mbed_error_printf("HardFault"); + faultStatus = MBED_ERROR_HARDFAULT_EXCEPTION; + break; + } + mbed_error_printf("\n\nContext:"); + print_context_info(); - mbed_error_printf("\n\n-- MbedOS Fault Handler --\n\n"); + mbed_error_printf("\n\n-- MbedOS Fault Handler --\n\n"); + core_util_atomic_store_bool(&mbed_error_in_progress, false); + } //Now call mbed_error, to log the error and halt the system mbed_error(faultStatus, "Fault exception", (unsigned int)mbed_fault_context_in, NULL, 0); diff --git a/platform/source/mbed_error.c b/platform/source/mbed_error.c index bc16a3d8ed9..25d64160c3e 100644 --- a/platform/source/mbed_error.c +++ b/platform/source/mbed_error.c @@ -51,7 +51,7 @@ static void print_error_report(const mbed_error_ctx *ctx, const char *, const ch #define ERROR_REPORT(ctx, error_msg, error_filename, error_line) ((void) 0) #endif -static bool error_in_progress; +bool mbed_error_in_progress; static core_util_atomic_flag halt_in_progress = CORE_UTIL_ATOMIC_FLAG_INIT; static int error_count = 0; static mbed_error_ctx first_error_ctx = {0}; @@ -121,7 +121,7 @@ static MBED_NORETURN void mbed_halt_system(void) WEAK MBED_NORETURN void error(const char *format, ...) { // Prevent recursion if error is called again during store+print attempt - if (!core_util_atomic_exchange_bool(&error_in_progress, true)) { + if (!core_util_atomic_exchange_bool(&mbed_error_in_progress, true)) { handle_error(MBED_ERROR_UNKNOWN, 0, NULL, 0, MBED_CALLER_ADDR()); ERROR_REPORT(&last_error_ctx, "Fatal Run-time error", NULL, 0); @@ -298,7 +298,7 @@ int mbed_get_error_count(void) //Reads the fatal error occurred" flag bool mbed_get_error_in_progress(void) { - return core_util_atomic_load_bool(&error_in_progress); + return core_util_atomic_load_bool(&mbed_error_in_progress); } //Sets a non-fatal error @@ -311,7 +311,7 @@ mbed_error_status_t mbed_warning(mbed_error_status_t error_status, const char *e WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) { // Prevent recursion if error is called again during store+print attempt - if (!core_util_atomic_exchange_bool(&error_in_progress, true)) { + if (!core_util_atomic_exchange_bool(&mbed_error_in_progress, true)) { //set the error reported (void) handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR());