How to wait on a conditional expression?

paco-torres wrote on Friday, November 08, 2019:

Hi,

I need to port a lot of code I wrote some years ago for PICs using OSA RTOS. OSA is a very compact but complete RTOS that can run even on the smallest uC and uses a cooperative scheduler. Unfortunately OSA RTOS is already dead, and I am also starting to use new uCs (STM32).

Although with little practice for now, I have read a lot of documentation of FreeRTOS, tutorials, etc… and can´t figure out how to wait on a C conditional expression to become true. OSA API has OS_Wait(any C expression as long as it only uses global variables). When a task uses OS_Wait(expression) it gets blocked until the expression becomes true, when it becomes ready.

As long as I have understood, FreeRTOS only allows waiting on FreeRTOS objects (like event groups).

Can this be done with FreeRTOS? How?

Thanks in advance.

heinbali01 wrote on Friday, November 08, 2019:

Hola Paco,

I don’t know of a FreeRTOS alternative for :

OS_Wait(any C expression as long as it only uses global variables)

Can you analyse which tasks will change the condition? You can work with Event Groups, or also with the simpler Task Notification.
Any task that changes the C expression should wake-up the task that is waiting for it.

pete-bone wrote on Friday, November 08, 2019:

Hi,

Is there any reason why you can’t just do this…


while( !(any C expression) ) vTaskDelay(10);

That is how I would approach it. You can change the number of ticks to suit your timing needs obviously…

Kind Regards,

Pete

richard_damon wrote on Friday, November 08, 2019:

Pete, that sort of works but the task doing it won’t wake up right when the expression becomes true. I suspect to worked in OSA doing doing something similar, but with the equivalent of a yield rather than a vTaskDelay.

My guess is that OS_Wait wasn’t really a function, but a macro, which may have done something like that (Which is sort of how the Co-Routines in FreeRTOS work).

The fundamental issue is that you CAN’T pass an ‘expression’ in C to a function.

pete-bone wrote on Friday, November 08, 2019:

Hi Richard,

Yes indeed, I should have mentioned that in my comment. I have used this method for non-critical tasks many times, but as you say the number of ticks you delay will make detection somewhere between 0 ticks and the value set depending on when the C expression state change takes place. Presumably if you use the yeild function it still causes at least one tick time of delay? Which pressumably can increase if another task is ready to run?

I agree also the OS_Wait must have been a macro as you say, you certainly can’t pass a C expression into a function…

Kind Regards,

Pete

richard_damon wrote on Friday, November 08, 2019:

Yield cause no delay, but allows any other ready task of the same priority to run at that time before it come back to check this task.

That sort of wait loop should really only be done at Task Priority 0, as it will block any lower task from running. My guess is that if the other OS provided this sort of operation, it likely did it sort of like that and likely had a very simple priority system too, so making the task be priority 0 may not be an issue.

richard_damon wrote on Friday, November 08, 2019:

Yield cause no delay, but allows any other ready task of the same priority to run at that time before it come back to check this task.

That sort of wait loop should really only be done at Task Priority 0, as it will block any lower task from running. My guess is that if the other OS provided this sort of operation, it likely did it sort of like that and likely had a very simple priority system too, so making the task be priority 0 may not be an issue.