cancel
Showing results for 
Search instead for 
Did you mean: 

Why does my test program enter the HardFault_Handler when debugging but not when programming?

RBack.1
Senior

My test program for my STM32F746VET6 is extremely simple. Other than MX configuring the clock and GPIO, I only have a while loop that flashes some LEDS and then divides by zero.

  while (1)
  {
    /* USER CODE END WHILE */
    uint32_t bobbycounter = 0;
    uint32_t bobbycounter2 = 0;
    while(1) {
        if(bobbycounter++ & 0x100000)
        {
            STATUS_LED_1_GPIO_Port->ODR &= ~STATUS_LED_1_Pin;
            STATUS_LED_2_GPIO_Port->ODR |= STATUS_LED_2_Pin;
        }
        else
        {
            STATUS_LED_1_GPIO_Port->ODR |= STATUS_LED_1_Pin;
            STATUS_LED_2_GPIO_Port->ODR &= ~STATUS_LED_2_Pin;
        }
 
        if(bobbycounter > 0x800000) {
            bobbycounter = bobbycounter / bobbycounter2;
        }
    }

When I debug in MX, I get the expected behavior where I enter the HardFault_Handler and then flash the LEDS at a faster rate forever:

void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */
 
  /* USER CODE END HardFault_IRQn 0 */
  uint32_t bobbycounter_hf = 0;
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
      if(bobbycounter_hf++ & 0x10000)
      {
          STATUS_LED_1_GPIO_Port->ODR &= ~STATUS_LED_1_Pin;
          STATUS_LED_2_GPIO_Port->ODR |= STATUS_LED_2_Pin;
      }
      else
      {
          STATUS_LED_1_GPIO_Port->ODR |= STATUS_LED_1_Pin;
          STATUS_LED_2_GPIO_Port->ODR &= ~STATUS_LED_2_Pin;
      }
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

When I program a part using STM32CubeProgrammer, however, I never enter the HardFault_Handler. I don't have either watchdog enabled. What could be going wrong here?

1 ACCEPTED SOLUTION

Accepted Solutions

> I'll try to look into other ways of forcing a hard fault if dividing by zero isn't a proper way to do it.

As Clive explained above, dividing by zero *is* a proper way to force a fault (which by default escalates to HardFault), but you have to enable it, by setting DIV_0_TRP in SCB_CCR, as it's by default cleared (and your debugger probably sets it - you may have a respective setting in your debugger for this).

Read PM0253.

JW

View solution in original post

4 REPLIES 4

Typically that would be a UsageFault, if DIV_0_TRP is enabled. Would get the HardFault if escalated.

Perhaps the debugger is enabling things? Check CCR in non-failing case.

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

Thanks for the answer. Ultimately I just need a way to force a hard fault so I can test (my actual) function for reporting the cause. I have a much more complicated program that has evidence of going into hard faults sometimes. I'll try to look into other ways of forcing a hard fault if dividing by zero isn't a proper way to do it.

> I'll try to look into other ways of forcing a hard fault if dividing by zero isn't a proper way to do it.

As Clive explained above, dividing by zero *is* a proper way to force a fault (which by default escalates to HardFault), but you have to enable it, by setting DIV_0_TRP in SCB_CCR, as it's by default cleared (and your debugger probably sets it - you may have a respective setting in your debugger for this).

Read PM0253.

JW

RBack.1
Senior

Oh, gotcha. I misunderstood that part of his response.