2018-06-28 07:01 AM
I am currently facing some problems with STM32F4, the process 'hangs' and I am not able to understand at what point it 'locked'. When this happened, I collected the following values for the following variables (I created the variable stepError to 'translate' the CFSR variable):
void prvGetRegistersFromStack (uint32_t * pulFaultStackAddress)
{volatile uint32_t CFSRValue = SCB-> CFSR;volatile uint32_t HFSRValue = SCB-> HFSR;char stepError [1024] = '';if ((HFSRValue & (1 << 30)) = 0) {CFSRValue >> = 16;if ((CFSRValue & (1 << 9)) = 0) strcpy (stepError, 'Divide by zero');if ((CFSRValue & (1 << 8))! = 0) strcpy (stepError, 'Unaligned access');if ((CFSRValue & (1 << 3)) = 0) strcpy (stepError, 'No UsageFault coprocessor');if ((CFSRValue & (1 << 2)) = 0) strcpy (stepError, 'Invalid PC load UsageFault');if ((CFSRValue & (1 << 1))! = 0) strcpy (stepError, 'Invalid state');if ((CFSRValue & (1 << 0))! = 0) strcpy (stepError, 'Undefined instruction');}/ * These are volatile to try and prevent the compiler / linker optimizing them
away the variables never actually get used. If the debugger will not show thevalues of the variables, make them global my moving their declaration outsideof this function. * /volatile uint32_t r0;volatile uint32_t r1;volatile uint32_t r2;volatile uint32_t r3;volatile uint32_t r12;volatile uint32_t lr; / * Link register. * /volatile uint32_t pc; / * Program counter. * /volatile uint32_t psr; / * Program status register. * /r0 = pulFaultStackAddress [0];
r1 = pulFaultStackAddress [1];r2 = pulFaultStackAddress [2];r3 = pulFaultStackAddress [3];r12 = pulFaultStackAddress [4];
lr = pulFaultStackAddress [5]; // Bit (2 or 3) = 0 determines MSP (Main Stack Pointer); 1 = PSP (Process Stack Pointer)pc = pulFaultStackAddress [6]; // Variable that contains the address where the error occurred. To check where it was, search the Disassembly on the screen Debug the addresspsr = pulFaultStackAddress [7];/ * When the following line is hit, the variables contain the register values. * /
// Joseph Yiu:
/ *1) Look at LR value when the core enter hardfault, if bit 2 is 0, then read the value of MSP. Otherwise, read the value of PSP.2) Based on the MSP / PSP value, you should be able to locate the start of stack frame, stacked PC is in address SP + 24.3) Generate a disassembled listing of the program you run, and try to locate the stack PC address in the disassembled program list.* /GPIO_WriteLed (0,1);
for (int i = 0; i <= 10; i ++){PWM_Change_DutyCycle (i, 0);}for (;;);}HFSRValue 1073741824
CFSRValue 0StepError 0x2001fbb0 ''r0 0
r1 0r2 0r3 11r12 536890019lr 134334773pc 0x0801bab0 <prvGetRegistersFromStack + 420>psr 3221225472But I can not know from these values where the error occurred, whether it was caused by usb, serial, encoder or ADC converter and etc.
How to implement void HardFault_Handler (void) so I can recognize where the error occurs?#hard-fault #debug #stm32f4072018-06-28 07:14 AM
You could start by looking at listing fIle or disassembly at the PC address. Or within the named function at the depth described as a percentage of the function listed in the map file.
If using pointers you could sanity check them, and work back up the call trees to see where the value comes from, add additional checks along the way.
Check stack depth/utilization.