In order for a counting semaphore to count items it should start in zero up to some positive count; then, at this point the semaphore would enqueue any other task requirement until the count is decremented.
In order for a counting semaphore to count resources it should start in some positive count up to zero; then, at this point the semaphore would enqueue any other task requirement until a resource is freed and the counter is incremented.
How can I initialize a counting semaphore (based on task notifications) with a count other than zero?
How can a task be notified when a counting semaphore reachs a given max count?
Is all that posible with such kind of semaphores (those based on task notifications)?
The FreeRTOS’ semaphore primitive can:
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount);
The promise is that semaphores based on task notifications can handle all that common functionality of regular counting semaphores.
The task notification word is just a word of storage. To set it to some number, just use xTaskNotify with a value of eSetValueWithOverWrite, and it will have that value.
Note, that the direct to task counting semaphore operation does NOT have an upper limit for how many times it can be set, so the notifying agent will never get blocked to say the count is ‘full’. If you want that sort of operation, you need to use a REAL counting semaphore that will block on gives to a full semaphore and takes on an empty semaphore.
The limitation that it doesn’t block senders isn’t seen as an issue I guess because it ISN’T handling some resource but notifications to a task, so the sender is never blocked because something isn’t available, because the ability to notify the task always is.
At this point I have no idea of the set of applications in which counting semaphores based on task notification worth, other than that in the official example, in which, BTW, there are no control of a maximum allowed value for the deferred ISRs.
There’s a FreeRTOS article that mentions that this kind of semaphores covers almost all real life applications, but now I have doubts.
Anyway, thank you for your time, I’ll be back soon with some more questions =)
First, you need to realize that by their nature, Task Notification can only block that particular task, other tasks don’t block for the notifications. If your application needs both sides to block, either you need to use a ‘real;’ semaphore, of you need to use Task Notifications on both ends.
For Example, if you have 5 buffers to communicate between two tasks, initially all free, you initialze the producer task to 5, and it can take and decrement the count, fill a buffer, then signal the other task that it has something to receive, waking up the other task.
The first thing I understood when I started to study this kind of semaphores was that of a single task is going to be woken up when a semaphore is given. That’s crystal clear, and that’s not the problem
What I don’t understand is that I can’t use it neither for counting items nor counting resources, which in turn are the regular uses of counting semaphores.
For counting items I mean free slots in a car parking system. Whenever there is not a free slots anymore, then the semaphore should notify the situation (its count reaches its maximum value), however the counting semaphores based on task notifications are tailored for tasks other than this.
RB wrote here:
Some semaphore use cases benefit from that comprehensive functionality, but the most common semaphore use cases don’t require it.
My mistake because I missunderstood the promise, and if I have to deploy such applications (like the car parking system), then I would use the regular semaphore API. For applications in which I need to count item by item, then the counting semaphores based on task notifications are the winner.
First, if the resource isn’t being controlled by a single task, the Direct-To-Task notification equivalency isn’t going to help, because that by DEFINITION deals with the control of a single task.
So if the car park system wants any ol car task to be able to come and take a spot, that is going to naturally need the general Counting Semaphore.
If there IS a central task that gets the request for a spot, then that task could use the direct to task system to keep the count, and any of the exit sensors could signal that a spot was free.
Personally, I don’t think the Block on no free spots is likely the right behavior here, so the counting semaphore system probably isn’t the right answer anyway.
For an actual resource that you want to block on, if we DO have the single producer or consumer case, then the direct to task counting semaphore could well be the answer.