Skip to main content
RBack.1
Associate III
February 20, 2023
Solved

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

  • February 20, 2023
  • 4 replies
  • 2346 views

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?

This topic has been closed for replies.
Best answer by waclawek.jan

> 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

4 replies

Tesla DeLorean
Guru
February 20, 2023

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 VenmoUp vote any posts that you find helpful, it shows what's working..
RBack.1
RBack.1Author
Associate III
February 20, 2023

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.

waclawek.jan
waclawek.janBest answer
Super User
February 20, 2023

> 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
RBack.1Author
Associate III
February 20, 2023

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