Skip to main content
Graham1
Associate II
January 30, 2025
Solved

Using STM32WB55: FreeRTOS osThreadFlagsWait can return osErrorTimeout early

  • January 30, 2025
  • 3 replies
  • 3018 views

I have come across an issue which I believe is a bug in the implementation of the osThreadFlagsWait function.

Scenario

A thread is waiting on a flag (e.g. 0x2u) for a timeout above 0, before this timeout should occur, there are multiple other flags set on the thread (e.g. 0x1u) using osThreadFlagsSet, this results in the osThreadFlagsWait function returning with a value of osErrorTimeout sooner than the set timeout.

Cause

The xTaskNotifyWait function which is called by osThreadFlagsWait returns each time the 0x1u flag is set, resulting in this section of code being run:

Graham1_1-1738260906062.png

Note that t0 is set to the return value of xTaskGetTickCount() at the start of the wait loop, so is the start time, tout is a timeout value passed to xTaskNotifyWait, which is originally the set timeout, but is adjusted each time the xTaskNotifyWait function returns.

The issue with the code above is that the value of td is the total time that the thread has been waiting, this is subtracting from tout each time a flag is set that is not waited on e.g.

for a set timeout of 100, if the flag that is not waited on happens every 10 ticks, the value of td and tout will be as follows for each time xTaskNotifyWait returns:

  1. td = 10 therefore tout = (100 - 10) = 90
  2. td = 20 therefore tout = (90 - 20) = 70
  3. td = 30 therefore tout = (70 - 30) = 40
  4. td = 40 therefore tout = (40 - 40) = 0 // timeout is detected on the next call to xTaskNotifyWait

This gives a timeout of 40 ticks in this case instead of the desired 100.

Suggested Fix

To fix this issue, I would suggest removing the cumulative subtraction from tout, instead replacing it with a subtraction of td from the set timeout e.g.

Graham1_2-1738261376861.png

 

Best answer by mƎALLEm

Hello @Graham1 

According to an internal feedback FreeRTOS version has been updated to v10.6.2 in STM32WB release v1.24.0. Does it solve the problem reported in this post?

3 replies

TDK
Super User
January 31, 2025

The code on GitHub already has this change.

stm32-mw-freertos/Source/CMSIS_RTOS_V2/cmsis_os2.c at e41c220a37adbb55b59dca704def6e73d6258b95 · STMicroelectronics/stm32-mw-freertos

 

What exact chip and library are you using? Are you using the latest version?

 

If you have an IOC file that generates the faulty code please attach it.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Graham1
Graham1Author
Associate II
January 31, 2025

I am using an STM32WB55, using the FREERTOS middleware from STM32CubeIDEs Pinout & configuration tool with repository version STM32Cube_FW_WB_V1.21.0 which I believe is the latest.

 

https://github.com/STMicroelectronics/STM32CubeWB/blob/dcc538339a30165ced95745969706b7423e3d96d/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c#L862

STTwo-32
Technical Moderator
March 5, 2025

Hello @Graham1 @TDK 

Thank you so much for bringing this on the ST Community. I've escalated for review on the Future (under internal ticket number (204574).

Best Regards.

STTwo-32

Associate
February 19, 2026

Hi everyone,
my apologies for reviving this, but yesterday I discovered another annoying problem with this code.
I was measuring the current consumption to check if it was sufficiently low in case the system goes into stop2.
To my surprise, I discovered that it wasn't (draining 6mA instead of 30uA).
After a long search, I discovered that the high-consuming task state wasn't "suspended", but "blocked"!
A little later, I realized this would happen when I called osThreadFlagsWait.
I assumed the timout value could be osWaitForever, so the task would sleep until a signal arrives and thus be suspended.
However, in a similar scenario, tout -= td becomes the result; what's done essentially amounts to timeout -= td.
Therefore, timeout != osWaitForever, and xTaskNotifyWait will notice this and set a very long timeout.
This causes the behavior to be different (the task is blocked, not suspended).

I've currently tested this as a solution:

if (timeout != osWaitForever) {
 if (td > tout) {
 tout = 0;
 }
 else {
 tout -= td;
 }
}

 

Is this a correct sollution?


I am also using stm32wb55 and STM32CubeIDE (Version: 1.19.0 Build: 25607_20250703_0907 (UTC)) as tool to configure the hw and generate code.
It generated the FreeRTOS code (FreeRTOS Kernel V10.3.1.h states: FreeRTOS Kernel V10.3.1)

Graham1
Graham1Author
Associate II
February 25, 2026

@fvv I would recommend the following solution: 

if (timeout != osWaitForever)
{
 if (td >= timeout)
 {
 tout = 0;
 }
 else
 {
 tout = (timeout - td);
 }
}

This should address the issue I observed, and the issue you describe as well. 

mƎALLEm
mƎALLEmBest answer
Technical Moderator
February 25, 2026

Hello @Graham1 

According to an internal feedback FreeRTOS version has been updated to v10.6.2 in STM32WB release v1.24.0. Does it solve the problem reported in this post?

"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."