2016-05-04 08:05 AM
Hey guys,
I'm using Stm32F429ZGT6 on my own PCB and with STM32CubeMX code generator and Ewarm IAR workbench.I have a problem with HardFault_Handler which happens some times,very random.and when I checked the SHCSR register during debugging using ST-linkI saw that whenever I have hard fault error my PC jumps to this handler and LR is a irrelevant address:(and the SHCSR register indicates a 0x00000800 which according to cortex m4 datasheet the 1 bit is for the SYSTICKACT and as I understood it's the systick exception active bit. which means when the interrupt for systick handler have had longer time than the systick itself! and that means we should have another interrupt with higher priority which takes longer time,and that's what I don't have really! and systick is in the highest priority.I don't know whether the problem is this or something else but this random situation occurrence increase whenever I increase the main clock frequency!which I thought it shouldn't be.I'm really open to try new thoughts and know the reason of this, so please if anyone know what causes this and what should I do, please let me know.Thanks in advance:)2016-05-04 08:12 AM
Look at some basic Hard Fault Handler code, see Joseph Yiu
The LR passed in is going to be a magic number, like 0xFFFFFFFD, to indicate how the processor needs to unravel the stack context. You need to use LR to pick the correct stack point, and decompose the stacked state to understand what the PC was when it faulted.Stuff is documented, lots of examples, things have been covered on the forum extensively. Review the size of your initial stack allocation, and that it is correctly aligned.Don't confuse priority with preemption2016-05-04 08:48 AM
2016-05-04 10:32 AM
Sorry I was using ''site: st.com hardfault'' in google, to find sth.
but searching the forum search box found me more interesting stuff:))could you please direct me to those you know ,would better answer my questions?2016-05-07 12:25 AM
Hi everyone,
Ok, I did these stuff to get the registers at hardfault:
in my startup_stm32f429xx.s startup assembly file ,I've added this at top of the module :
EXTERN hard_fault_handler_c
PUBLIC HardFault_Handlerand this one:
PUBWEAK HardFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)HardFault_Handler
; B HardFault_Handler TST LR, #4 ITE EQ MRSEQ R0, MSP MRSNE R0, PSP B hard_fault_handler_cin the handler section in startup file
and I've added this hard_fault_handler.c file to the project:
void hard_fault_handler_c (unsigned int * hardfault_args){ unsigned int stacked_r0; unsigned int stacked_r1; unsigned int stacked_r2; unsigned int stacked_r3; unsigned int stacked_r12; unsigned int stacked_lr; unsigned int stacked_pc; unsigned int stacked_psr; 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]); printf (''\n\n[Hard fault handler - all numbers in hex]\n''); printf (''R0 = %x\n'', stacked_r0); printf (''R1 = %x\n'', stacked_r1); printf (''R2 = %x\n'', stacked_r2); printf (''R3 = %x\n'', stacked_r3); printf (''R12 = %x\n'', stacked_r12); printf (''LR [R14] = %x subroutine call return address\n'', stacked_lr); printf (''PC [R15] = %x program counter\n'', stacked_pc); printf (''PSR = %x\n'', stacked_psr); printf (''BFAR = %x\n'', (*((volatile unsigned long *)(0xE000ED38)))); printf (''CFSR = %x\n'', (*((volatile unsigned long *)(0xE000ED28)))); printf (''HFSR = %x\n'', (*((volatile unsigned long *)(0xE000ED2C)))); printf (''DFSR = %x\n'', (*((volatile unsigned long *)(0xE000ED30)))); printf (''AFSR = %x\n'', (*((volatile unsigned long *)(0xE000ED3C)))); printf (''MMFAR = %x\n'', (*((volatile unsigned long *)(0xE000ED34)))); printf (''SCB_SHCSR = %x\n'', (*((volatile unsigned long *)(0xE000ED24)))); printf (''SCB_CCR = %x\n'', (*((volatile unsigned long *)(0xE000ED14)))); printf (''SCB_SHP = %x\n'', (*((volatile unsigned long *)(0xE000ED18)))); //printf (''SCB_SHCSR = %x\n'', SHCSR);0xE000ED34 while (1);}and this is the result in the terminal:
[Hard fault handler - all numbers in hex]
R0 = 0R1 = 40R2 = e000ed18R3 = 0R12 = 0LR [R14] = 8003761 subroutine call return addressPC [R15] = 0 program counterPSR = 40000000BFAR = e000ed38CFSR = 20000HFSR = 40000000DFSR = bAFSR = 0MMFAR = e000ed34SCB_SHCSR = 0SCB_CCR = 200SCB_SHP = 0BFAR and MMFAR as it's obvious are showing their own address.SCB_SHCSR is 0 wonderfully!CCR is telling STKALIGN bit is 1 which means 8-bytes aligned ?!and I'm not surehow to set stack align.and LR is pointing to this : 0x8003761which according to disassembly is here:....
.... .... 0x800373e: 0xbd00 POP {PC}__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority){HAL_InitTick: 0x8003740: 0xb510 PUSH {R4, LR} 0x8003742: 0x4604 MOV R4, R0 HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000U); 0x8003744: 0xf000 0xfe9e BL HAL_RCC_GetHCLKFreq ; 0x8004484 0x8003748: 0xf44f 0x717a MOV.W R1, #1000 ; 0x3e8 0x800374c: 0xfbb0 0xf0f1 UDIV R0, R0, R1 0x8003750: 0xf7ff 0xfe94 BL HAL_SYSTICK_Config ; 0x800347c HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0U); 0x8003754: 0x2200 MOVS R2, #0 0x8003756: 0x4621 MOV R1, R4 0x8003758: 0xf04f 0x30ff MOV.W R0, #-1 ; 0xffffffff 0x800375c: 0xf7ff 0xfe59 BL HAL_NVIC_SetPriority ; 0x8003412 return HAL_OK;0x8003760: 0x2000 MOVS R0, #0 <<<<<-----
This line Here is the last LR
0x8003762: 0xbd10 POP {R4, PC}
uwTick++;HAL_IncTick: 0x8003764: 0x4811 LDR.N R0, [PC, #0x44] ; [0x80037ac] 0x2000041c (536871964) 0x8003766: 0x6801 LDR R1, [R0] 0x8003768: 0x1c49 ADDS R1, R1, #1 0x800376a: 0x6001 STR R1, [R0]} 0x800376c: 0x4770 BX LR return uwTick;HAL_GetTick: 0x800376e: 0x480f LDR.N R0, [PC, #0x3c] ; [0x80037ac] 0x2000041c (536871964) 0x8003770: 0x6800 LDR R0, [R0] 0x8003772: 0x4770 BX LR 0x8003774: 0x0000 MOVS R0, R0 0x8003776: 0x0000 MOVS R0, R0__weak void HAL_Delay(__IO uint32_t Delay){HAL_Delay: 0x8003778: 0xb511 PUSH {R0, R4, LR} ...... ......this function is HAL_InitTick ,I'm not pretty sure why is this causing the HAL_OK to make a hardfault or accessing invalid region of memory, and why is this related to my code?I'm sure it's not always this line that cause hardfault because there are some times which my code is working properly but suddenly I have a hardfault which means that the HAL_InitTick is executed successfully some times!but I'm not sure about this. could you guys help me in this please?dear Clive1 could you kindly check this?2016-05-07 07:23 AM
The LR is the return address, so it went into HAL_NVIC_SetPriority and then vectored to zero.
You should check the Vector Table address (SCB->VTOR) and the content of the table, especially any interrupts you are using, check first the SysTick Handler address in the table.I would also print out the stack address2016-05-08 12:14 AM
2016-05-08 12:28 AM
2016-05-08 04:18 AM
I would double check where 0x80034ac points
SysTick_Handler:
0x8004f66: 0xb500 PUSH {LR}
0x8004f68: 0xb081 SUB SP, SP, #0x4
HAL_IncTick();
0x8004f6a: 0xf7fe 0xfbeb BL HAL_IncTick ; 0x8003744
HAL_SYSTICK_IRQHandler();
0x8004f6e: 0xb001 ADD SP, SP, #0x4
0x8004f70: 0xf85d 0xeb04 LDR.W LR, [SP], #0x4
0x8004f74: 0xf7fe 0xba9a B.W HAL_SYSTICK_IRQHandler ; 0x80034ac