Hi NXP,
I am trying to implement hardfault handling in the boot loader only.
I have a boot loader which will execute the main application after boot, and I want to implement the hardFault_Handler only in the boot loader. So when there is a hardfault error happened in the main application, it will jump to the boot loader and execute the HardFault_Handler in the boot loader.
However, when there is a hardfault happened in the main application, seems the program will be stuck in the main application and can never jump to the boot loader.
This is the HardFault Handler I put in the boot loader, it works fine if I put it in both the boot loader and main application.
It doesn't work if I replace the main application HardFault Handler with a function jump.
Does the boot loader and the main application have to have their own hardfault handler??
void HardFault_Handler(void)
{
#if(0)
__asm volatile
(
" tst lr, #4 \n"
" ite eq \n"
" mrseq r0, msp \n"
" mrsne r0, psp \n"
//Load the instruction that triggered had fault
" ldr r1, [r0, #24] \n"
" ldr r2, handler2_address_const \n"
" bx r2 \n"
" handler2_address_const: .word prvGetRegistersFromStack \n"
);
#endif
__asm( ".syntax unified\n"
// Check which stack is in use
"MOVS R0, #4 \n"
"MOV R1, LR \n"
"TST R0, R1 \n"
"BEQ _MSP \n"
"MRS R0, PSP \n"
"B _process \n"
"_MSP: \n"
"MRS R0, MSP \n"
// Load the instruction that triggered hard fault
"_process: \n"
"LDR R1,[R0,#24] \n"
"LDRH R2,[r1] \n"
// Semihosting instruction is "BKPT 0xAB" (0xBEAB)
"LDR R3,=0xBEAB \n"
"CMP R2,R3 \n"
"BEQ _semihost_return \n"
// Wasn't semihosting instruction so enter registers dump
//"B . \n" //enter inifinte loop
" ldr r2, handler2_address_const \n"
" bx r2 \n"
" handler2_address_const: .word prvGetRegistersFromStack \n"
// Was semihosting instruction, so adjust location to
// return to by 1 instruction (2 bytes), then exit function
"_semihost_return: \n"
"ADDS R1,#2 \n"
"STR R1,[R0,#24] \n"
// Set a return value from semihosting operation.
// 32 is slightly arbitrary, but appears to allow most
// C Library IO functions sitting on top of semihosting to
// continue to operate to some degree
"MOVS R1,#32 \n"
"STR R1,[ R0,#0 ] \n" // R0 is at location 0 on stack
// Return from hard fault handler to application
"BX LR \n"
".syntax divided\n") ;
}
Hi, Terence,
I think the HardFault is a general exception, you can run code in the ISR.
I see that you want to execute the bootloader code once the hardfault exception heppens, in the case, I suggest you reset the system by using the NVIC_SystemReset() function in CMSIS, which can set the SYSRESETREQ bit in NVIC->AIRCR register.
BTW, you can enable watchdog in the main() function, but in the void HardFault_Handler(void), do not feed the watchdog by disabling the Timer which feeds dog. In this way, the watchdog Reset will happen.
Hope it can help you
BR
XiangJun Rong
But after system reset, I won't be able to capture the HardFault information