cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_Delay() crashes STM32 code

AReye.1
Associate II

I'm trying to upload code to an STM32F103RET6 MCU and have a simple setup by now (see image below). I have attached a LED to pin PA1 as a GPIO OUTPUT and an external oscillator at 16 MHz. The other three pins are connected to the JTAG connector that goes to the STLINK v2. 0693W00000ANu5wQAD.pngWhen i generate the code to perform a simple blink I'm having trouble with the HAL_Delay function. The code is shown below.

#include "main.h"
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
 
int main(void)
{
  HAL_Init();
 
  SystemClock_Config();
 
  MX_GPIO_Init();
 
  while (1)
  {
      HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, 1);
      HAL_Delay(500);
      HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, 0);
      HAL_Delay(500);
  }
}
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV2;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : LED_G_Pin */
  GPIO_InitStruct.Pin = LED_G_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_G_GPIO_Port, &GPIO_InitStruct);
 
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}
 
#ifdef  USE_FULL_ASSERT
 
void assert_failed(uint8_t *file, uint32_t line)
{
 
}
#endif /* USE_FULL_ASSERT */

The connection with the MCU is fine and the code starts running, so the first line that is to turn on the LED is executed correctly and the LED turns on. The problem is when the 

HAL_Delay(500)

 is executed, it stops the code and the following message pops up: No source available for "uwTickPrio() at 0x20000004" See image: 

0693W00000ANu6BQAT.pngI have tried setting the NVIC preemption priority as i have seen that was the solution to many people having a similar problem and the setup is like the following:

0693W00000ANu6fQAD.pngI have also tried many other things commented in the forums but I cannot solve this problem. Any tip could be really useful.

Many thanks for taking your time.

10 REPLIES 10
TDK
Guru

Examine the SCB->ICSR register VECTACTIVE bits to find out what interrupt the CPU is in. Verify that interrupt handler exists in your code. Probably the issue is with handling the SysTick event, as HAL_Delay is unlikely to cause issues.

Not real sure though, maybe try creating a new project.

If you feel a post has answered your question, please click "Accept as Solution".
AReye.1
Associate II

I don't really understand what is happening in this register. I add a screen capture in case it was useful. 0693W00000AOXO9QAP.png 

What I've seen while debugging step by step is that when de HAL_Delay function is called, it gets stuck in the while:

__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  uint32_t wait = Delay;
 
  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }
 
  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
}

so the MCU keeps running the following:

__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}

Until the code breaks and it exits.

JPeac.1
Senior

Never used the HAL but looking at the code there are some obvious questions to check:

Does uwTick ever change?

What happens when the wait variable overflows the 32-bit count?

Try a breakpoint in the while loop after a few thousand iterations to see if you are actually incrementing some kind of time counter. If whatever updates uwTick isn't working you have an infinite loop. Also, bear in mind you are doing unsigned math without any check on overflows for the subtraction or compare.

Jack Peacock

TDK
Guru

VECTACTIVE = 3. To find which interrupt it's handling, subtract 16 and look it up in IRQn_Type. In this case, it's executing the HardFault_IRQn interrupt, which means something in your program went wrong. Other SCB registers will shed more light into why a hard fault occurred.

Note that VECTPENDING = 0xF, which is the SysTick_IRQn, but it never gets there because it's in the hard fault handler.

If you feel a post has answered your question, please click "Accept as Solution".

The subtraction math on unsigned variables is correct, including the overflows. A very useful feature! Read more on it here:

https://stackoverflow.com/questions/7221409/is-unsigned-integer-subtraction-defined-behavior

Mustafa.Alkin
Associate II

0693W00000DnRYUQA3.pngHad same issue happening. I checked the VECTACTIVE and it's 0 in debug mode. Program cannot get out of the loop given in screenshot. I tried changing the stm board to check it is hard fault related but still same issue happening.

Also i am using CubeIDE and HAL libraries but we tried programming and debugging in standard library and it worked well. So probably problem is about HAL libraries, but i couldn't figure it out.

The code show needs a TIM to be clocking, and the number ranges need to be appropriate.

Is it a down counter, or up counter?

On a 16-bit TIM?

Could the range of the TIM always be below the threshold?

If the TIM clock isn't enabled the count will always be zero, and it will never leave the loop.

There are far better ways to do delay loops using free running timers.

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

Yep, some new gen timers even have optional overflow in cnt 32 bit registers to ease atomic timestamp processed when extending a 16 bit hw timer into a 32 bit sw+hw one...

DHall.5
Associate

I think it may be an interaction between HAL_delay and using the de ******.

I have exactly the same problem. Very simple noob setup and if I run my blinky code without stepping through it it works fine.

If I try and step through it in a debugger it hits HAL_delay and goes in to lala land.

I do wonder if it is a setting in the debug config some place. I did see some posts about 1.8.0 CubeIDE having issues so it could also be a bug.

Very frustrating.