Skip to main content
Graduate
June 17, 2025
Solved

Nucleo-H7S3L8 with RTOS: HAL_IncTick() always returning 0

  • June 17, 2025
  • 4 replies
  • 1132 views

Hi everyone,

I'm working on an STM32H7RS project (NUCLEO-H7S3L8) with the following setup:

  • Bootloader in internal flash (0x08000000)

  • Application in external OSPI flash (XIP) at 0x70000000

  • Using Azure RTOS (ThreadX)

  • Using TIM6 as the HAL time base (not SysTick)

  • Configured using latest STM32CubeMX and STM32CubeIDE (v1.18.1)

What I already checked:

  • The vector table is correctly set in main() of the application:

 

 
int main(void)
{

 /* USER CODE BEGIN 1 */
#define APPLICATION_VECTOR_TABLE ((uint32_t)0x70000000)

SCB->VTOR = APPLICATION_VECTOR_TABLE;
__DSB();
__ISB();

 /* USER CODE END 1 */

 /* Enable the CPU Cache */

 /* Enable I-Cache---------------------------------------------------------*/
 SCB_EnableICache();

 /* Enable D-Cache---------------------------------------------------------*/

 /* MCU Configuration--------------------------------------------------------*/

 /* Update SystemCoreClock variable according to RCC registers values. */
 SystemCoreClockUpdate();

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_HPDMA1_Init();
 MX_GPDMA1_Init();
 uint32_t tickTest3 = HAL_GetTick();
 MX_ADC1_Init();
 MX_ADC2_Init();
 MX_I2C2_Init();
 MX_SBS_Init();
 MX_UART4_Init();
 MX_UART5_Init();
 MX_TIM3_Init();
 MX_TIM2_Init();
 MX_UART7_Init();
 MX_UART8_Init();
 MX_I2C3_Init();
 MX_SPI1_Init();
 MX_SPI2_Init();
 MX_ETH_Init();
 MX_FLASH_Init();
 MX_DTS_Init();
 MX_TIM1_Init();
 /* USER CODE BEGIN 2 */
 /* Initialize leds */
 BSP_LED_Init(LED_GREEN);
 BSP_LED_Init(LED_BLUE);
 BSP_LED_Init(LED_RED);


 /* USER CODE BEGIN BSP */
 /* -- Sample board code to send message over COM1 port ---- */
 printf("Welcome to STM32 world !\n\rApplication project is running...\n\r");
 /* -- Sample board code to switch on leds ---- */
 BSP_LED_On(LED_GREEN);
 BSP_LED_On(LED_BLUE);
 BSP_LED_On(LED_RED);
 /* USER CODE END BSP */
 /* USER CODE END 2 */

 MX_ThreadX_Init();
  • HAL_Init() is called before anything else

  • HAL_InitTick() has been overridden to use TIM6

  • HAL_TIM_Base_Start_IT() returns HAL_OK

  • TIM6_DAC_IRQHandler() is defined and includes a call to HAL_IncTick() via HAL_TIM_IRQHandler()

  • HAL_TIM_PeriodElapsedCallback() is implemented and includes:
if (htim->Instance == TIM6) {
 HAL_IncTick();
}
​
  • The TIM6 interrupt priority is set to 14, and NVIC config is applied

  • uwTick remains at 0 the entire time — HAL_GetTick() and HAL_Delay() don’t function

  • MX_Eth_Init works, indicating that clocks, NVIC, and system init are not completely broken

  • Using the default ThreadX integration generated by STM32CubeMX for Azure RTOS

I also upleaded my IOC file. Are there any known issues or things i have overseen?

 

    This topic has been closed for replies.
    Best answer by htxy

    SOLVED:

    Kudos: https://community.st.com/t5/stm32-mcus-embedded-software/all-irq-handler-not-called-when-using-stm32f107vct/td-p/787710

     

    Upon further inspecting the SFR, i saw that the hardware timers were increasing. By setting setting enable_irq() at the top of main(), it worked. 

    For people who will find this later, this is how uwTick works:

     

    The uwTick variable is only incremented when this chain of events happens:

    1. The TIM6 hardware counter overflows.
    2. This triggers the TIM6_IRQ_Handler to execute.
    3. TIM6_IRQ_Handler calls HAL_TIM_IRQHandler()
    4. HAL_TIM_IRQHandler() calls HAL_TIM_PeriodElapsedCallback().
    5. HAL_TIM_PeriodElapsedCallback() calls HAL_IncTick(), which finally increments uwTick.

    The chain was breaking at Step 2. The TIM6_IRQ_Handler was never being executed, even though the hardware timer is overflowing. enable_irq() enables the interrupts.

     

    4 replies

    Super User
    June 17, 2025

    14 is a lower priority than 0. You typically want SysTick (or whatever you're using for it) to be a higher priority (numerically lower) than others. It's probably an issue with this.

    htxyAuthor
    Graduate
    June 17, 2025

    This is my application NVIC:

    htxy_0-1750179941536.png
    I set everything to 1 except the not editeble interrupt handlers as wel as TIM6. Upon running, HAL_GetTick still return 0 all the time, as uwTick is not increasing.

    Super User
    June 17, 2025

    That screenshot shows systick is lower priority than everything else.

    Put TIM6 at 0 and everything else at 15.

    If that doesn't work, show the stack trace when HAL_Delay fails.

    htxyAuthor
    Graduate
    June 18, 2025

    To catch and prove that uwTick is not increasing, I have written a HAL_Delay(10) after HAL_Init(). The expected behaivior to proof that uwTick is not increasing is a "infinite loop".

    htxy_0-1750247415794.png

    That is also exactly what happened.

     

    Also here is the NVIC i used.

    htxy_1-1750247507097.png

    Super User
    June 18, 2025

    > void TIM6_IRQHandler(void)

    The relevant IRQ handler is TIM6_DAC_IRQHandler, but the stm32h7*_it.c file has TIM6_IRQHandler defined.

    In your original post, you said TIM6_DAC_IRQHandler was defined. Did something change there?

     

    If this is a CubeMX bug, please include the IOC if you can.

     

    If that's not it, here's what I would do:

    • In debug mode, ensure TIM6->CNT is increasing. Run/pause and verify in SFRs that it increases.
    • In TIM6_DAC_IRQHandler, set a breakpoint and ensure it's getting hit. Once its hit, step through and ensure it makes it to HAL_TIM_PeriodElapsedCallback.
    htxyAuthor
    Graduate
    June 18, 2025

    Very interesting that you pointed that out. 

    I had to regenerate the code due to the change of the change of the NVIC priorities. Interesting thoug, not only is there no TIM6_DAC_IRQHandler to be found anymore.

     

    Sadly i didnt have version control enabled...
    I also appended the IOC file.

    Also i recorded a video how the SFR values for TIM6 change, but upon inspection the variables, they change from beeing uninitialized to receiving 0 as value, as if uwTick isnt getting TIM6 as reference.

    htxyAuthorAnswer
    Graduate
    June 19, 2025

    SOLVED:

    Kudos: https://community.st.com/t5/stm32-mcus-embedded-software/all-irq-handler-not-called-when-using-stm32f107vct/td-p/787710

     

    Upon further inspecting the SFR, i saw that the hardware timers were increasing. By setting setting enable_irq() at the top of main(), it worked. 

    For people who will find this later, this is how uwTick works:

     

    The uwTick variable is only incremented when this chain of events happens:

    1. The TIM6 hardware counter overflows.
    2. This triggers the TIM6_IRQ_Handler to execute.
    3. TIM6_IRQ_Handler calls HAL_TIM_IRQHandler()
    4. HAL_TIM_IRQHandler() calls HAL_TIM_PeriodElapsedCallback().
    5. HAL_TIM_PeriodElapsedCallback() calls HAL_IncTick(), which finally increments uwTick.

    The chain was breaking at Step 2. The TIM6_IRQ_Handler was never being executed, even though the hardware timer is overflowing. enable_irq() enables the interrupts.