Skip to main content
Visitor II
November 10, 2021
Solved

ThreadX/AzureRTOS on STM32H7 messing with HAL tick timer. Anyone experienced the same thing?

  • November 10, 2021
  • 12 replies
  • 11620 views

HAL timebase set to use TIM6. ThreadX uses SysTick.

My code is minimalistic for the test-project when debugging this issue. ThreadX is set up to have 1000 ticks/second as opposed to the default 100 ticks/second.

I have one thread printing out HAL_GetTick() and _tx_time_get() after a tx_delay of 1000 milliseconds.

HAL_GetTick as we all know returns uwTick, which gets incremented by the TIM6 interrupt callback.

ThreadX returns the correct time, while GetTick() returns a value that gets incremented by about 15 for every 1000 ms. My only explanation for this is that ThreadX disables the interrupt that calls the TIM6 IncTick function while it does scheduling work in the background, but I have a hard time believing this as I can't find anyone else facing the same issue online.

    This topic has been closed for replies.
    Best answer by Haithem Rahmani

    Hi @KKorn.1​ 

    you are right, ThreadX is disabling all interrupts including the TIM6 one. in the ThreadX 6.1.8, there was support for the BASEPRI, allowing the application to define the subset of interrupts to mask. This should fix your issue.

    regards

    Haithem.

    12 replies

    Visitor II
    November 10, 2021

    I Can't help today but tomorrow I will get my H735-Dk

    while I'm waiting, I've been trying to compile Azure MQTT without success.

    which example did you start with ?

    which board are you using ?

    Do you have to use Tim6 ?

    I just usually install the Systick callback an have no trouble with the H7 on that.

    What priority are you using ?

    I never use RTOS. having to for the first time now.

    I wonder if RTOS is disabling interrupts... is that part of the thread safe locking mechanism ?

    KKorn.1Author
    Visitor II
    November 10, 2021

    I didn't start with an example and the board is custom-made (industrial application).

    You don't have to use TIM6, but you shouldn't use SysTick as timebase when implementing an RTOS as the RTOS is given full control over the SysTick configuration, this can lead to unpredictable behavior.

    A workaround to my issue is to override the weak HAL_GetTIck() function and make it return the ThreadX system timer once the kernel has started. Since their tick resolution is the same, this leads to identical timing behavior. Would still like to know the cause of this though.

    ST Employee
    November 14, 2021

    Hi @KKorn.1​ 

    you are right, ThreadX is disabling all interrupts including the TIM6 one. in the ThreadX 6.1.8, there was support for the BASEPRI, allowing the application to define the subset of interrupts to mask. This should fix your issue.

    regards

    Haithem.

    Visitor II
    September 6, 2022

    Hi @KKorn.1​ ,

    I think you can resolve your issue by setting priority 14 (less than 15) to TIM6 in NVIC.

    Visitor II
    November 30, 2022

    This also worked for me, i don't understand how this and "ThreadX is disabling all interrupts" can be true though?

    Visitor II
    January 18, 2023

    I got the same effect with NucleoU575

    STM32U575 which ships azure ThreadX directly integrated into CubeIDE.

    Same Effect. I use Timer 7 as Systic.

    Timer is configured correctly, but interrupt only occurs every 10th time. HAL-GetTick results in a approx. 10 times slower speed.

    Setting TIM 7 IRQ priority from 7 (highest) to 6 solves the problem.

    Question remains:

    Why is that? What is the purpose of blocking the systick-IRQ. ?

    Visitor II
    January 18, 2023

    Hi,

    I think...

    When ThreadX is in IDLE state, CPU executes __tx_ts_wait called from PendSV_Handler.​ And, the PendSV interrupt is set the lowest interrupt priority. So, while ThreadX is in IDLE state, the lowest priority is always blocked.

    Visitor II
    January 19, 2023

    Hi, Johannes,

    For your information, 7 is the lowest priority and 0 is the highest priory.​

    Visitor II
    January 19, 2023

    It is strange, that azure-RTOS insist on using a hardware timer for systic. But at the same time, the systic is bad, because of the IRQ problem described above.

    Is this because azure-RTOS uses the Cortex M System-Tic counter for its purposes, and therefore the Cortex M systic is not available for HAL_Systic?

    If so:

    A good improvement to CubeMX would be, if it would not set the IRQ of the hardware timer to lowest priority, if you use a hardware timer for HAL-Systic in combination with ThreadX

    Visitor II
    January 19, 2023

    ThreadX (also FreeRTOS) uses System-Tic interrupt in the OS porting layer implementation. And, the tick period is configurable. On the other hand HAL tick period expects 1msec. So, System-Tic is not suitable as HAL tick, I think.

    In tx_initialize_low_level.s, interrupt priority 4 is set to SysT and priority max(the lowest) is set to PendSV. So, I think the CubeMX should change the default interrupt priority value for timebase, at least when OS is enabled.

    Graduate
    February 3, 2023

    Haithem Rahmani ,

    Could you please instruct how to implement your answer" ThreadX is disabling all interrupts including the TIM6 one. in the ThreadX 6.1.8, there was support for the BASEPRI, allowing the application to define the subset of interrupts to mask. This should fix your issue."

    Is this done by modifying existing library code, via CubeMX settings, What?

    ST Employee
    February 14, 2023

    Hi @Community member​ 

    Sorry for the delay.

    Indeed you can configure this via STM32CubeMX as below.

    1. Enable the BasePRI support in the ThreadX config panel, then set the BASEPRI value to "8" for example as shown below:

    0693W00000YAiBdQAL.png 2. go to the NVIC config panel and set the TIM interrupt priority to any value greater than "8"

    0693W00000YAi1uQAD.pngdoing that the threadx will not mask the TIM 6 any more, but this may impact the overall behaviour of you application as each 1ms a TIMER interrupt will be received and needs to be managed.

    regards

    Haithem.

    Graduate
    December 30, 2023

    I had the same issue with the STM32U5A5 Eval board, where HAL-Delay() seems to run strangely when ThreadX goes to standby with peripheral interrupts disabled (is this a correct assumption?). I fixed this by pushing TIM6 to priority level 14 from 15 and enabling BASEPRI Support with level 15. I wonder if there are certain guidelines or good practices to determine the correct setting. 

    Is Microsoft really answering ThreadX query related to STM32, so far no answer for 2-3 weeks from several queries?, does the STM32 team continue to insist on deferring all Azure things to Microsoft rather than STM32? 

    Super User
    December 30, 2023

    Is Microsoft really answering ThreadX query related to STM32

    Microsoft will support the last milestone version of Azure RTOS for 5 years. The last milestone is 6.0 released in May 2020 so the support will last until May 2025. The last minor release is 6.1.3 (January 2021), these releases are supported for 2 years, so already out of support. In 2024 Azure RTOS will transition to Eclipse Foundation and won't be Microsoft's concern anymore. IIRC ST hasn't disclosed their plans for the Eclipse-branded ThreadX yet.

    HAL_Delay is ST library function so you are in the right place to ask about this.

    (short answer: your workaround is OK, and yes there are good practices to combine a RTOS with libraries like the ST "HAL", this forum is a good place to discuss them).