aduke202050
aduke202050

Reputation: 161

While loop inside STM32F3xx HardFault handler does not execute forever as expected

I would like to find the cause of mysterious microcontroller resets that I am seeing in my project. The microcontroller I am using is an STM32F3 device with STM32F3xx driver library.

My setup also includes a J-link Ultra+ debugger, however frustratingly I have not yet figured out how to reproduce the resets. They occur almost always after leaving the device running for 12+ hours, and do not seem to occur when connected on a programming jig designed to interface with the debugger.

I believe that when the resets occur, the HardFault handler will be called. I have a number of these devices, and given I cannot connect them all to the debugger and the resets occur at inopportune times, I would like to be able to send some information via a serial line from the HardFault handler. The serial line would then be observed by an external device.

Further complicating things is the lack of unused UART pins. I am attempting to create a poor man's UART by flicking a GPIO on and off in the hard fault handler, with delays in between. To begin with, I just want to figure out how to flick this LED on and off with 50% duty cycle. My code currently looks something like this:

/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */
    GPIO_InitTypeDef GPIO_InitStruct = {LED_Pin, GPIO_MODE_OUTPUT_PP,
                                        GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, 0};
    HAL_GPIO_Init(LED_Port, &GPIO_InitStruct);   
  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    HAL_GPIO_WritePin(LED_Port, LED_Pin, GPIO_PIN_RESET);
    HAL_Delay(10);
    HAL_GPIO_WritePin(LED_Port, LED_Pin, GPIO_PIN_SET);
    HAL_Delay(10);
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

I am testing this by triggering a divide-by-zero reset. I have disabled all watchdogs yet I am finding that when this while loop is entered, it does not while forever, in fact the device restarts when it first hits a HAL_Delay() command.

Questions:

  1. What might be causing the resets upon reaching HAL_Delay()?
  2. Can I execute instructions indefinitely in the HardFault handler, or is there a limited amount of time I have to do things before a reset occurs?
  3. Can I use timers in the hard fault handler?

Thanks very much for your help.

Upvotes: 1

Views: 1019

Answers (1)

0___________
0___________

Reputation: 68013

HAL_Delay(10); uses systick interrupt. When in HF you will not get any interrupts and this function will wait forever and your diodes will not flash. You need to delay another way, for example:

for(unsigned x = 0; x < 100000; x++) asm("");

Can I execute instructions indefinitely in the HardFault handler, or is there a limited amount of time I have to do things before a reset occurs?

Yes you can stay there as long as you wish. But no interrupts!!!!

Can I use timers in the hard fault handler?

Yes, but no timer interrupts. Basically, you can use all the peripherals if you wish.

What might be causing the resets upon reaching HAL_Delay

Hard to say. Did you enable watchdog?

Basically do not use HAL in HF as most of the functions use HAL_Delay internally. Program bare registers instead

Upvotes: 5

Related Questions