2022-03-10 04:33 AM
I am sending some variable's address through UART then reading and getting those data from UART, often my program stucks into hardfault handler to avoid that in handler i just added __NVIC_SystemReset(); Is there any other way to avoid Hardfault handler?
and observed that due to busfault handler(Precise data bus error) causing hardfault handler!
2022-03-10 06:38 AM
Sending and receiving data doesn't cause hard faults in general. It is due to some other issue in your code. Analyze the hard fault, understand what type it is, why it's being called. Precise hard faults are generally easy to figure out. Look at the instructions that caused the fault.
2022-03-24 06:15 AM
Dear @TDK
Thanks for your response, and I would like to know if hardfault occured does other interrupt,timer and systick timer will work?
FYI, I have removed while(1) inside hardfault handler function.
2022-03-24 06:22 AM
Is your hope that by ignoring the hard fault your program will continue to run correctly? Hard faults should be fixed, not ignored.
2022-03-24 06:26 AM
I am just making hardfault manually by dividing zero and invalid address memory access
i am just curious to know at the time of hardfault whether other pheripheral will work
2022-03-24 06:32 AM
Dear @TDK These things i have added in hardfault handler
uint32_t CFSRValue = SCB->CFSR;
uint32_t HFSRValue = SCB->HFSR;
if((CFSRValue >> 10) == 1)
{
HAL_UART_Transmit (&huart5, "PRECISERR", 9,500);
}
if((CFSRValue >> 16) == 1)
{
HAL_UART_Transmit (&huart5, "BUSFAULT", 8,500);
}
if((CFSRValue >> 17) == 1)
{
HAL_UART_Transmit (&huart5, "UNDEFINS", 8,500);
}
if((CFSRValue >> 24) == 1)
{
HAL_UART_Transmit (&huart5, "UNALIGNEDACC", 12,500);
}
if((CFSRValue >> 25) == 1)
{
HAL_UART_Transmit (&huart5, "DIVBY0", 6,500);
}
and to findout exact which line making hardfault error i have added below things would like to hear whether this will workout
HardFault_HandlerAsm();
void HardFault_HandlerAsm(void)
{
__asm( ".syntax unified\n"
"MOVS R0, #4 \n"
"MOV R1, LR \n"
"TST R0, R1 \n"
"BEQ _MSP \n"
"MRS R0, PSP \n"
"B HardFault_HandlerC \n"
"_MSP: \n"
"MRS R0, MSP \n"
"B HardFault_HandlerC \n"
".syntax divided\n") ;
}
void HardFault_HandlerC(unsigned long *hardfault_args)
{
volatile unsigned long stacked_r0 ;
volatile unsigned long stacked_r1 ;
volatile unsigned long stacked_r2 ;
volatile unsigned long stacked_r3 ;
volatile unsigned long stacked_r12 ;
volatile unsigned long stacked_lr ;
volatile unsigned long stacked_pc ;
volatile unsigned long stacked_psr ;
volatile unsigned long _CFSR ;
volatile unsigned long _HFSR ;
volatile unsigned long _DFSR ;
volatile unsigned long _AFSR ;
volatile unsigned long _BFAR ;
volatile unsigned long _MMAR ;
stacked_r0 = ((unsigned long)hardfault_args[0]) ;
stacked_r1 = ((unsigned long)hardfault_args[1]) ;
stacked_r2 = ((unsigned long)hardfault_args[2]) ;
stacked_r3 = ((unsigned long)hardfault_args[3]) ;
stacked_r12 = ((unsigned long)hardfault_args[4]) ;
stacked_lr = ((unsigned long)hardfault_args[5]) ;
stacked_pc = ((unsigned long)hardfault_args[6]) ;
stacked_psr = ((unsigned long)hardfault_args[7]) ;
_CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;
_HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;
_DFSR = (*((volatile unsigned long *)(0xE000ED30))) ;
_AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;
_MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
_BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;
}
2022-03-24 06:46 AM
>> Is there any other way to avoid Hardfault handler?
Debug what's faulting.
Add sanity checks so invalid pointers don't get used, and you figure out why .
The peripherals will all continue to function.
The processor can execute code.
Interrupts of lower priority will not occur whilst in the handler.
You can return, but won't address the underlying problem, and failure might compound.
Hard Faults tend to be the results of "gross errors", should be easy enough to identify and fix,as they are not subtle.
https://github.com/cturvey/RandomNinjaChef/blob/main/KeilHardFault.c
2022-03-24 05:15 PM
The actual exception is BUS FAULT. You get hardfault because detection of bus fault is not enabled by default, so it falls back (aka "elevates") to hardfault.
An easier way to probe for invalid address is to enable busfault detection. Then it can be masked.
Mask it before accessing the address, then check bus fault status. If bus fault occurred, clear it and unmask busfault again (because you want to catch it when unexpected).
In this way no exception handler is called at all.