Hello everyone,
Processor : Arm Cortex-m4For an experiment, I purposely triggering hard fault exception, by making T-bit in Execution Program Status Register to 0. The program execution control reaches hard fault handler.Inside the hard fault handler I was triggering SVC instruction using "__asm volatile ("SVC #0");". After executing this line, system goes reset. May I know the reason.
static void printAdd(int var1, int var2) { printf("Sum %d\n",(var1 + var2)); } int main(void) { /* * The Program Counter (PC) is register R15. It contains the current program address. On reset, the processor loads the PC with the value of the reset vector, which is at address 0x00000004. Bit[0] of the value is loaded into the EPSR T-bit at reset and must be 1. */ /* * The Cortex-M4 processor only supports execution of instructions in Thumb state. The following can clear the T bit to 0: • instructions BLX, BX and POP{PC} • restoration from the stacked xPSR value on an exception return • bit[0] of the vector value on an exception entry or reset. Attempting to execute instructions when the T bit is 0 results in a fault or lockup. */ /* * The processor enters a lockup state if a fault occurs when executing the NMI or HardFault handlers. When the processor is in lockup state it does not execute any instructions. The processor remains in lockup state until either: • it is reset • an NMI occurs • it is halted by a debugger. Note: If lockup state occurs from the NMI handler a subsequent NMI does not cause the processor to leave lockup state. */ /* Function pointer 1, initialize with "printAdd" function with complier * (i,e) program counter is loaded with function name "printAdd" - 0x08000d19 address [PC 0th bit is 1 - Thumb State]. */ static void (*funcPtr1) (int,int) = printAdd; /* Function pointer 2, initialize with "printAdd" function without complier * (i,e) program counter is loaded with 0x08000d18 address directly [PC 0th bit is 0 - Arm State].*/ static void (*funcPtr2) (int,int) = (void*) 0x08000d18; /* call funcPtr1 - Thumb state */ funcPtr1(10,20); /* call funcPtr2 - Arm state */ funcPtr2(10,20); /* Loop forever */ for(;;); } void HardFault_Handler(void) { /* Print "Hard fault detected" */ printf("Hard fault detected\n"); /* Trigger SVC instruction */ __asm volatile ("SVC #0"); while(1); } /* SVC IRQ Handler */ void SVC_Handler(void) { /* Inside SVC Handler */ printf("Inside SVC Handler\n"); }
This is the test code I was using, for your reference.Other detailsHW : STM32F407VGIDE : STMCUBELANGUAGE : COutput console :After this point executing SVC instruction, reset happened.As per the suggestion, I was set the breakpoint on the entry of the SVC handler and it is not reaching that point.
SVC from within a hard fault handler causes lockup on Cortex M cpus. I think the default behaviour on lockup is reset. I use Silabs EFM32 cpus, which have hardware options to not reset but simply stay in lockup. Yiu's Definitive Guide to M3/M4 includes commentary on lockup.
Thank you for your input, it was really helpful.