Хотя бы так: #ifdef __GNUC__
#ifdef __clang__
void isr::HardFault[[clang::optnone]]()
#else
void isr::HardFault[[gnu::optimize("-O0")]]()
#endif
#endif
{
volatile uint32_t out = 0;
volatile core::ArchRegs* archregs;
// Тут можно добавить что-нибудь типа user_fault_handler()
// В нем можно сохранить информацию о проблеме и безопасно перезапустить девайс
// Автоматическая обработка
//if (user_fault_handler()) return;
// Ручная обработка
// Read fault information
shcsr.all = *(uint32_t*)(0xe000'ed24);
hfsr.all = *(uint32_t*)(0xe000'ed2c);
mfsr.all = *(uint8_t* )(0xe000'ed28);
bfsr.all = *(uint8_t* )(0xe000'ed29);
ufsr.all = *(uint16_t*)(0xe000'ed2a);
mmar = *(uint32_t*)(0xe000'ed34);
bfar = *(uint32_t*)(0xe000'ed38);
// Halt execution
// If registers indicate readable memory, change the variable value to != 0 to continue execution.
while(out == 0)
{
asm("nop");
}
out = 0;
// Get context pointer
archregs = (core::ArchRegs*)(__get_MSP()+8); // Можно модифицировать контекст и перейти куда надо
// Например вернуться за пару команд до вылета
// Halt execution
// To step out of the HardFaultHandler, change the variable value to != 0.
while(out == 0)
{
asm("nop");
}
return;
}