Using uVision v5.27.1.0 (RTOS 1) with STM32L4xxx. In an ISR two different signals are sent to the same thread like below:
.
osSignalSet(myTask, SIGNAL_1);
osSignalSet(myTask, SIGNAL_2);
In the waiting task myTask, the following code is executed:
for (;;) {
osEvent evt = osSignalWait(0, osWaitForever);
u32 signals = evt.value.signals;
The "signals " will NOT contain SIGNAL_2. Only SIGNAL_1. In other words, the waiting task will wake up on the first of the two signals, even though both of them were posted in the same ISR at the same time.
I think it is a bug .
The work around would be, in general case, to add the following code to code above:
evt = osSignalWait(0, 0);
signals |= evt.value.signals;
Now both SIGNAL_1 and SIGNAL_2 are consumed, and are in the variable "signals " .
Cheers!
Robert,
Can you please confirm what happens in the following situation:
A task is ready to run, but preempted by a higher priority task. While being preempted, two signals are sent to it, first signal_A and then signal_B. At some point the task is finally running again and enters the wait for any signal. Since the signals are already "posted", the wait will immediately return. Which signals will be returned? Only the first qualifying signal_A?
Sergey
No. In the case you describe you will get both signals. IF A task is in a wait when the 2 signals are sent, then you will only get Signal_A. You will need to do another wait to get Signal_B.
Thanks, good to know.
It would be a nice idea to clarify the effects of the first qualifying signal for a waiting task somewhere in the documentation. None of the resources mention it.
And the last question. If a task was in a wait, but another, higher priority task, was running, and in that time two signals are sent to the waiting task. When the waiting task gets to run and immediately returns from the wait, will it also return only the first signal?
Yes. Once you are in a wait, you will get the first signal(s) that satisfy the wait. If signals are already present, you will get them all. If none are present you will get the first call to osSetSignal() that satisfies the wait. (so if the first call has multiple signals, you will get multiple signals)
****
When a task enters osWaitSignal(), and not signals are waiting, it is put into the blocked queue and set the SIGNAL WAIT state. The first call that fully satisfies the SIGNAL_WAIT causes the task to be removed from the blocked queue and the return value set to and to be osEventSignal and the value set to the signals set at this point in time. This task is then put into the ready queue. At this point, the task is not considered to be waiting on signals any more. Any signal the task receives from this point until another osSignalWait() is called will be kept as if you are not currently waiting for signals.
We are focusing too much about how it is actually implemented as opposed to what you can count on from the signals functions.
Make no assumption about when 2 signals have been set in relation to each other. Your code should not need to know or care if SIGNAL1 has been set before, after or at the same time as SIGNAL2. You only know that they are both set.
I agree. Thanks!