bfleming wrote on Monday, July 16, 2012:

_Pardon the brevity of this post, I wrote up a fairly length discussion only to have it flagged as SPAM; which instead of letting me just log in decided to just delete all my work. _

In vxWorks I could have n tasks all blocked on the same rate semaphore, and have a ‘scheduler’ task reset the rate semaphore causing all blocked tasks to become ready at which point they’d run in priority order. The biggest benefit was the ‘scheduler’ task didn’t have to know how many tasks were in the system, just when to release which rates.

How would I do something similar in freertos? I bought the PDFs hoping they would have the solution (it didn’t). The examples in the book barely discuss dealing with more than one task. If I only had 1-2 tasks I wouldn’t need an OS.

The queue API specifically says it only release ONE reader on a block, which isn’t good. And since semaphores seems to be 2nd class citizens they suffer the same unfortunate fate.


richard_damon wrote on Tuesday, July 17, 2012:

One way to active this is to have a list of semaphores to be signaled when the time comes, and rather than signal just one, run a loop and signal the whole list. If you need to do this a lot, it shouldn’t be hard to write a simple set of routines to manage this, adding the feature as a layer above the FreeRTOS kernel. The fact that is can be easily done as a user routine may be one reason the capability isn’t built into the core of FreeRTOS.

bfleming wrote on Tuesday, July 17, 2012:

I guess my one concern, and maybe it really isn’t, is that triggering the semaphores in a loop isn’t atomic. I’ll also have to setup an framework for everyone to share the semaphores that each task wants triggered if I truly want a decoupled system.

I know what I did in vxWorks was more of a trick than a feature, but I’ve looked at other APIs and it seems that doing a reset on a semaphore is common, and it may have come from posix.

richard_damon wrote on Tuesday, July 17, 2012:

If you want the operation atomic, then just disable the scheduler before signaling all the semaphores, then re-enable it after, then no task can interfere with the process by being started when it is signaled.

rtel wrote on Tuesday, July 17, 2012:

It is not always a good idea to call API functions with the scheduler disabled (depends on the API function itself), but you can temporarily raise the task priority to the highest in the system during the operation, then lower it back to its original priority afterwards.


bfleming wrote on Tuesday, July 17, 2012:

I started digging into the code and thought I could implement my own semFlush operation. It seems to simple to work, but I haven’t had a chance to try it.  Will this actually put all the waiting tasks into the ready state?

* Custom SemaphoreFlush() function; Used to release ALL blocked tasks waiting on a semaphore.
void vSemaphoreFlush( xSemaphoreHandle xSemaphore ) {
portSHORT higherPriorityTaskFlushed = pdFALSE;

//Release all tasks trying to take the semaphore
while( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
higherPriorityTaskFlushed != xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) );

//If any of the tasks release have a higher priority than the currently running task then switch
if( higherPriorityTaskFlushed == pdTRUE )
/* The unblocked task has a priority higher than our own so yield immediately.*/