2026-02-19 8:44 AM
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)
Can you help me, je débute dans l'environnement STM32CUBE...
Thanks in advance,
Eric
Solved! Go to Solution.
2026-02-25 3:27 AM - edited 2026-02-25 5:04 AM
@CLC_EricF wrote:
Here is the descriptif:
Humm well. That seems to be this example from Github:
Indeed you can start by that one. Then move on with this one (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.
2026-02-19 10:42 AM - edited 2026-02-19 12:01 PM
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:
2026-02-19 11:57 AM
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.
2026-02-20 6:39 AM
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:
@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
2026-02-20 6:50 AM
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?
2026-02-20 7:16 AM
What do you have selected as the Timebase Source in the CubeMX project?
On what physical hardware are you running your code?
2026-02-20 7:28 AM
2026-02-20 7:37 AM
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.
2026-02-20 7:52 AM
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.
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
2026-02-20 8:01 AM
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.