Skip to main content
Associate
Oct 28, 2025 5:51 PM UTC
Solved

SysTick not firing when using FreeRTOS

Post edited by ST moderator to be inline with the community rules for the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code.

Hey Folks,

I am writing firmware on a STM32U5A5ZJ-Q board, I am using FreeRTOS, and am running into some issues with SysTick, originally noticed when HAL_Delay() would just hang. I was also able to verify that uwTick does not change (this may be strange, because SysTick->Val does change as expected). I read in some other forums that 

WARNING:
When RTOS is used, it is strongly recommended to use a HAL timebase source other than the SysTick. The HAL time base source can be changed from the Pinout tab under SYS.

 

My understanding is that an RTOS that has SysTick_Handler implemented overrides the __weak handler that exists in the generated code and thereby forces things using SysTick as their timing source to a low priority. Since I already have my code written, so can I just update my code to use a different time source? I'm not entirely sure how this works, although I did come across a STM32 FreeRTOS example that implements the following code

// located in stm32u5xx_it.c

void TIM6_IRQHandler(void) // TIM6 seems to be the go to alternative to SysTIck
{
 HAL_TIM_IRQHandler(&htim6);
}

so I am hoping it is a relatively simple switch.

Please let me know if you need more details. Any assistance would be appreciated.

-Dylan

 

 

 

This topic has been closed for replies.
drd1202Best answer
Associate
Oct 29, 2025 11:55 PM UTC

Hi All,

I got the issue resolved. C++ was mangling my interrupt handler names so that no interrupts were firing. Originally, I had checked SysTick's counter, and that was incrementing, but the interrupt was not firing because the interrupt handler names were different under the hood. Once I updated all of my code the follow strictly C, it started working immediately. I am pretty sure there is a way to do this with C++ (I had my interrupts in extern "C" blocks to try to prevent mangling), but apparently it's somewhat tricky. Anyway, I appreciate the assistance.

8 replies

gbm
Super User
Oct 28, 2025 6:17 PM UTC

When you create your FreeRTOS project with CubeMX, it suggests to choose another timer for HAL. TIM6/7 are obvious choices.

Anyway, it's definitely a very bad idea to use any HAL_Delay() in an RTOS-based application.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
drd1202Author
Associate
Oct 28, 2025 6:21 PM UTC

Hi gbm,

Thank for the response.

I get that you should use a different timing source, but how difficult is that to work into code that is already written? My current code uses SysTick, and I want to change it to TIM6. I am assuming it's fairly doable, but I have never done embedded work before, so I am just trying to keep an eye out for gotchas.

Also, Why is it a bad idea to use HAL_Delay() in an RTOS based system? Is it just because they can cause timing issues? If so, that shouldn't be an issue, I am only using them during the system initialization and once it's up I do not use it anywhere.

gbm
Super User
Oct 28, 2025 6:36 PM UTC

To efficiently use multithreading (that's what RTOS is made for) you should relinquish control to RTOS whenever you have nothing to do. That's how osDelay() works.

HAL_Delay() spends the thread's timeslice on waiting in a loop instead of telling the RTOS to switch to some useful task for a specified waiting time. If you call HAL_Delay(5) in two threads of the same priority, each of them will wait for 10 milliseconds or more.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
drd1202Author
Associate
Oct 28, 2025 6:43 PM UTC

Hi gmb,

Understood, and I should be safe then since I don't use it after the firmware fully initializes and FreeRTOS has been started.

Back to my other question: does that sound like it might be the source of my issue? The issue is showing up before FreeRTOS? I am assuming it is relatively simple to just swap out some of my code to point to TIM6 instead.

drd1202AuthorBest answer
Associate
Oct 29, 2025 11:55 PM UTC

Hi All,

I got the issue resolved. C++ was mangling my interrupt handler names so that no interrupts were firing. Originally, I had checked SysTick's counter, and that was incrementing, but the interrupt was not firing because the interrupt handler names were different under the hood. Once I updated all of my code the follow strictly C, it started working immediately. I am pretty sure there is a way to do this with C++ (I had my interrupts in extern "C" blocks to try to prevent mangling), but apparently it's somewhat tricky. Anyway, I appreciate the assistance.