Binary semaphore reliability

Hi, a friend of mine with greater knowledge of RTOSes than myself is arguing about the reliability of this code: 1) I have a binary semaphore created like this myMutex = xSemaphorCreateBinary(); 2) In my IRQHandler for serial input, I set a binary semaphore every time I get a new char and put it in the RX queue: xSemaphoreGiveFromISR(myMutex, …); 3) I have a task waiting for that semaphore: xSemaphoreTake(myMutex, 10); 4) Hardware is an CortexM0+ STM32F030, FreeRTOS version 7.6.0, compiler GCC The argument is that there is a possibility of loosing a byte from my IRQ handler and that I should use a counting semaphore. The question is: is it 100% safe to use a binary semaphore in this way (I got the example from the (payed) manual) or should I change to a counting semaphore as he says? Thanks for making FreeRTOS and thanks for being here to help us, Alain

Binary semaphore reliability

The answer depends on how you have structured your code. A binary semaphore will only tell you that something has happened, not how many things have happened, so you must process ALL pending events before going back to wait for the semaphore again, not just assume there is only one event (character, in your case) pending. See the code snippet on the following page, which shows a task notification being used as a binary semaphore – the concept is the same – not do do while{} loop clearing all events before looking for a notification again: http://www.freertos.org/ulTaskNotifyTake.html

Binary semaphore reliability

Yes, that is what I did but using binay semaphore. I do process all pending events before going back to taking the semaphore. But the argument is that an ISR could happen “at some special moment” and cause the xSemaphoreTake() not to wake up. Is it guaranteed that this “special moment” does not exist? And BTW, I have no mention to TaskNotify anywhere in Reference Manuas v2.0.0 for FreeRTOS v8.0.0 🙁

Binary semaphore reliability

But the argument is that an ISR could happen “at some special moment” and cause the xSemaphoreTake() not to wake up. Is it guaranteed that this “special moment” does not exist?
That “special moment” do not exist in FreeRTOS. The FreeRTOS API’s take all necessary measurements to be atomic. In some cases interrupts are masked, in other cases the scheduler will be suspended temporarily. As a result you can Give and Take semaphores ( notifications ) at any moment you like, without worrying about congruency. In most cases, the task receiving bytes will be sleeping in ulTaskNotifyTake() or xSemaphoreTake(). When the ISR comes at that moment, the function will unblock and return a non-zero value. When the ISR comes at any other moment, the task is handling UART reception. It will read all bytes available and call the Take function again. That function will return immediately. And then there may, or there may not be RX bytes available. That depends on the actual sequence of events. You won’t miss bytes using the “binary semaphore method”, unless there is a physical overflow, which may happen if the task does not get enough CPU time.

Binary semaphore reliability

Thanks very much for giving a definitive answer 🙂