cancel
Showing results for 
Search instead for 
Did you mean: 

HardFault_Handler stm32Cube Stm32F429ZGT6 SHCSR Systick

allahyarzadeh
Associate II
Posted on May 04, 2016 at 17:05

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-link

I 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:)

8 REPLIES 8
Posted on May 04, 2016 at 17:12

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 preemption

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
allahyarzadeh
Associate II
Posted on May 04, 2016 at 17:48

Thank you dear Clive :)

actually I first checked this linke :

http://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/

and I understood the way ,

but I could'nt find some complete document on this matter.

my problem is this hardfault may happen randomly even if my code is completely bare and just some GPIO write or reads. all of the stuff is comming from the Cube, why should I even encounter such problems?

about other documents,I would be grateful if you could provide me some links.

sorry to ask but my search for hardfault keyword in this forum returned no results. which keyword should I search?

and about Preemption is not set by me, Cube does it with HAL_NVIC_SetPriorityGrouping (uint32_t PriorityGroup)

should I change it for systick?

about stack, I'm not using many variables but I have 0x300 minimum size

and  0x500 heap size

my Linker configuration file .icf shows

define symbol __ICFEDIT_intvec_start__ = 0x08000000;

/*-Memory Regions-*/

define symbol __ICFEDIT_region_ROM_start__    = 0x08000000;

define symbol __ICFEDIT_region_ROM_end__      = 0x081FFFFF;

define symbol __ICFEDIT_region_RAM_start__    = 0x20000000;

define symbol __ICFEDIT_region_RAM_end__      = 0x2002FFFF;

define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;

define symbol __ICFEDIT_region_CCMRAM_end__   = 0x1000FFFF

addresses which seems fine by me,

and about the stack alignment could you explain me how to check it?

Thank you again

allahyarzadeh
Associate II
Posted on May 04, 2016 at 19:32

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?

allahyarzadeh
Associate II
Posted on May 07, 2016 at 09:25

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_Handler

 and 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_c

in 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 = 0

R1 = 40

R2 = e000ed18

R3 = 0

R12 = 0

LR [R14] = 8003761  subroutine call return address

PC [R15] = 0  program counter

PSR = 40000000

BFAR = e000ed38

CFSR = 20000

HFSR = 40000000

DFSR = b

AFSR = 0

MMFAR = e000ed34

SCB_SHCSR = 0

SCB_CCR = 200

SCB_SHP = 0

BFAR 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 : 0x8003761

which 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?

Posted on May 07, 2016 at 16:23

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 address

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
allahyarzadeh
Associate II
Posted on May 08, 2016 at 09:14

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6k5&d=%2Fa%2F0X0000000buQ%2FazzU2f.ko4tN5U5p7YAwpFffxCVVNFsbS_DmOK6d5dE&asPdf=false
allahyarzadeh
Associate II
Posted on May 08, 2016 at 09:28

I have this error some times instead of hard fault

Sun May 08, 2016 00:36:49: The stack pointer for stack 'CSTACK' (currently 0x100004A0) is outside the stack range (0x20000428 to 0x20000728) 

Posted on May 08, 2016 at 13:18

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..