cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-U575ZI-Q - HAL_GetTick returns 0

CLC_EricF
Associate II

Bonjour,

J'utilise la suite CUBEMX et CUBEIDE  pour créer mon projet à partir d'une carte de développement NUCLEO-U575ZI-Q.
J'ai réalisé mon projet sur CUBEMX en gardant et validant le BSP de la NUCLEO pour utiliser les leds et surtout le debug via ST-LINK embarqué.

J'ai ajouté des IO pour effectuer une maquette avec SPI1 et OCTO-SPI1 plus quelques IO notamment une PWM.

Pour commencer j'ai d'abord réalisé un bout de code pour faire clignoter une led (LED_GREEN); à une certaine fréquence réglée par HAL_Delay.

Le souci est que cette fonction bloque car le Tick ne semble pas être validé, (HAL_GetTick  me retourne toujours 0)...

Je crois pourtant avoir validé les interruptions :

Hello,

I am using the CUBEMX and CUBEIDE suite to create my project based on a NUCLEO-U575ZI-Q development board.
I created my project on CUBEMX, keeping the NUCLEO BSP to use the LEDs and, above all, debugging via the embedded ST-LINK.

I added I/Os to create a model with SPI1 and OCTO-SPI1, and a few I/Os, including a PWM.

To start with, I wrote a piece of code to make a LED (LED_GREEN) flash at a certain frequency set by HAL_Delay.

The problem is that this function blocks because the tick does not seem to be validated (HAL_GetTick always returns 0)...

However, I believe I have validated the interrupts:

Translated with DeepL.com (free version)

CLC_EricF_0-1771519169847.png

Can you help me, je débute dans l'environnement STM32CUBE...
Thanks in advance,

Eric

 

1 ACCEPTED SOLUTION

Accepted Solutions

@CLC_EricF wrote:

Here is the descriptif:
ExampleDescriptif.jpg


Humm well. That seems to be this example from Github:

https://github.com/STMicroelectronics/STM32CubeU5/tree/main/Projects/NUCLEO-U575ZI-Q/Examples/GPIO/GPIO_Demo

Indeed you can start by that one. Then move on with this one (GPIO_IOToggle_TrustZone):

https://github.com/STMicroelectronics/STM32CubeU5/tree/main/Projects/NUCLEO-U575ZI-Q/Examples/GPIO/GPIO_IOToggle_TrustZone

at least to inspire from the TrustZone configuration/implementation.

For SPI example refer to these examples (I think without TrustZone enabled): https://github.com/STMicroelectronics/STM32CubeU5/tree/main/Projects/NUCLEO-U575ZI-Q/Examples/SPI

If you feel one of the posts helped you/answered your question please don't hesitate to accept it as solution.

And you are welcome.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

23 REPLIES 23
mƎALLEm
ST Employee

Hello @CLC_EricF and welcome to the ST community, 

Check if the option to generate the system tick interrupt handler code is checked in the code generation tab:

mALLEm_0-1771531262370.png

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
StevenG
Associate III

Eric,

  Somewhere within your project (usually main.c) you should have a function similar to the following:

/**
  * @brief  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM6 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @PAram  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM6)
  {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */

  /* USER CODE END Callback 1 */
}

In my case I am using TIM6 to create the time base used by HAL_GetTick().  Make sure you have similar code in your application and maybe place a breakpoint on the line with HAL_IncTick() to make sure your code is getting to this point.  NOTE:  in general I always use a timer to create the system clock so I am not sure what happens if you use the SysTick. 

 

You mention that you created your project based on the NUCLEO board.  Are you running code on a NUCLEO board or on hardware you designed and built?  The NUCLEO board appears to have on-board HSE and LSE crystals/oscillators.  If you have designed a board without HSE or LSE clock sources, your code will need to use only the internal RC oscillators. 

 

The HAL code often doesn't implement fail-safe operation and will enter code loops waiting for a bit to be set/cleared without any kind of timeout.  Of course, if you are using an actual NUCLEO board, you shouldn't have a problem with this type of issue.

CLC_EricF
Associate II

Thanks  @mƎALLEm and @StevenG  for your responses.

 @mƎALLEm : Yes the option to generate the system tick interrupt handler code is checked in the code generation tab:

Capture d’écran 2026-02-20 144402.jpg

 @StevenG :No, I didn't have the function implemented in main.c, I added it by synchronizing it with TIM1 declared as OutputCompare. It doesn't go into any interrupt.
And HAL_GetTick always returns 0...
Best Regards,

Eric

Hello,

Thank you for the confirmation,

Could you please attach your project so I could reproduce the case in the next week as I don't have that board for now?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

What do you have selected as the Timebase Source in the CubeMX project?

 
 

Timebase.jpg

On what physical hardware are you running your code?

Thank you for your proposal. !

No I can't select TIM1, SysTick is the only possibility, all other proposals are grayed out...

The code runs on the physical hardware NUCLEO-U575ZI-Q, I am currently creating a prototype with an SPI display and a Quad SPI flash that will interface with the Nucleo board via the expansion connectors.

I haven't used the secure code features of the U5 series but you can see the HAL_IncTick() being called from the SysTick_Handler() in both ./Secure/Core/Src/stm32u5xx_it.c: and ./NonSecure/Core/Src/stm32u5xx_it.c

 

You have the Timebase source set as SysTick so I would suggest either stepping through the code using the debugger or grepping through the source code on a terminal and figure out if SysTick is getting set up correctly.

Timebase_SysTick.jpg

 

I find using a bash shell to be the easiest way to look through someone else's code but the STM32CubeIDE should be able to search through all the project files as well.

$ find . -name \*.c -exec grep SysTick /dev/null {} \;
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:        (++) SysTick timer is used by default as source of time base, but user
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  * @note   In the default implementation the System Timer (SysTick) is used as source of time base.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  *         The SysTick configuration is based on MSI clock, as MSI is the clock
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  *         each 1ms in the SysTick_Handler() interrupt handler.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  /* Select HCLK as SysTick clock source */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  * @note In the default implementation, SysTick timer is the source of time base.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  *       The SysTick interrupt must have higher priority (numerically lower)
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  if (READ_BIT(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk) == SysTick_CTRL_CLKSOURCE_Msk)
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:    /* HCLK selected as SysTick clock source */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:      /* HCLK_DIV8 selected as SysTick clock source */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:      /* LSI selected as SysTick clock source */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:      /* LSE selected as SysTick clock source */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  /* Configure the SysTick to have interrupt in 1ms time basis*/
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  /* Configure the SysTick IRQ priority */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  *       in SysTick ISR.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  * @note In the default implementation , SysTick timer is the source of time base.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  * @note In the default implementation , SysTick timer is the source of time base. It is
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  *       is called, the SysTick interrupt will be disabled and so Tick increment
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  /* Disable SysTick Interrupt */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  * @note In the default implementation , SysTick timer is the source of time base. It is
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  *       is called, the SysTick interrupt will be enabled and so Tick increment
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  /* Enable SysTick Interrupt */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal.c:  SysTick->CTRL  |= SysTick_CTRL_TICKINT_Msk;
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:    *** How to configure SysTick using CORTEX HAL driver ***
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:    Setup SysTick Timer for time base.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:   (+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:        (++) Configures the SysTick Reload register with value passed as function parameter.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:        (++) Configures the SysTick IRQ priority to the lowest value (0x0F).
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:        (++) Resets the SysTick Counter register.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:        (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:        (++) Enables the SysTick Interrupt.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:        (++) Starts the SysTick Counter.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:   (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:   (+) You can change the SysTick IRQ priority by calling the
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:       HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:   (+) To adjust the SysTick time base, use the following formula:
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:       Reload Value = SysTick Counter Clock (Hz) x  Desired Time base (s)
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:      SysTick functionalities
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  * @brief  Initialize the System Timer with interrupt enabled and start the System Tick Timer (SysTick):
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  if ((TicksNumb - 1UL) > SysTick_LOAD_RELOAD_Msk)
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  WRITE_REG(SysTick->LOAD, (uint32_t)(TicksNumb - 1UL));
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  /* Load the SysTick Counter Value */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  WRITE_REG(SysTick->VAL, 0UL);
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  /* Enable SysTick IRQ and SysTick Timer */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  SET_BIT(SysTick->CTRL, (SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk));
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  * @brief  Configure the SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  * @PAram  CLKSource: specifies the SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  *             @arg SYSTICK_CLKSOURCE_LSI: LSI clock selected as SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  *             @arg SYSTICK_CLKSOURCE_LSE: LSE clock selected as SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  *             @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  *             @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:      SET_BIT(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk);
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:      CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk);
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:      CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk);
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:      CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk);
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  * @brief  Get the SysTick clock source configuration.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  * @retval  SysTick clock source that can be one of the following values:
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  *             @arg SYSTICK_CLKSOURCE_LSI: LSI clock selected as SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  *             @arg SYSTICK_CLKSOURCE_LSE: LSE clock selected as SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  *             @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  *             @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  /* Read SysTick->CTRL register for internal or external clock source */
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_cortex.c:  if (READ_BIT(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk) != 0U)
./Drivers/STM32U5xx_HAL_Driver/Src/stm32u5xx_hal_pwr.c:  *         as NVIC and SysTick can run and wake up the CPU when an interrupt
./NonSecure/Core/Src/stm32u5xx_it.c:void SysTick_Handler(void)
./NonSecure/Core/Src/stm32u5xx_it.c:  /* USER CODE BEGIN SysTick_IRQn 0 */
./NonSecure/Core/Src/stm32u5xx_it.c:  /* USER CODE END SysTick_IRQn 0 */
./NonSecure/Core/Src/stm32u5xx_it.c:  /* USER CODE BEGIN SysTick_IRQn 1 */
./NonSecure/Core/Src/stm32u5xx_it.c:  /* USER CODE END SysTick_IRQn 1 */
./NonSecure/Core/Src/system_stm32u5xx_ns.c:  *                                  by the user application to setup the SysTick
./NonSecure/Core/Src/system_stm32u5xx_ns.c:  *         be used by the user application to setup the SysTick timer or configure
./Secure/Core/Src/stm32u5xx_it.c:void SysTick_Handler(void)
./Secure/Core/Src/stm32u5xx_it.c:  /* USER CODE BEGIN SysTick_IRQn 0 */
./Secure/Core/Src/stm32u5xx_it.c:  /* USER CODE END SysTick_IRQn 0 */
./Secure/Core/Src/stm32u5xx_it.c:  /* USER CODE BEGIN SysTick_IRQn 1 */
./Secure/Core/Src/stm32u5xx_it.c:  /* USER CODE END SysTick_IRQn 1 */
./Secure/Core/Src/system_stm32u5xx_s.c:  *                                  by the user application to setup the SysTick
./Secure/Core/Src/system_stm32u5xx_s.c:  *         be used by the user application to setup the SysTick timer or configure
./Secure/Core/Src/system_stm32u5xx_s.c:  *         be used by the user application to setup the SysTick timer or configure

 

I

 

I believe you need to select which domain each timer is in, secure or non-secure.  Then it will be available as a Timebase Source.  I haven't used any of the secure features yet so I can't give much more support.

Timebase_Tim6_Tim7.jpg