In learning how to make use of low power modes on my Silicon Labs Giant Gecko MCU, which is Cortex M3 based, I learned the interactions between WFE(), SEV() and the Event Register, a 1-bit hardware component. Any firing ISR provides same 'set the ER to 1' that a call to SEV() does.
Now, I had assumed that the event register followed the same semantics as Dijkstra's binary semaphore:
the semaphore == the event register
P() == WFE()
V() == SEV()
Taking the semaphore, i.e. P(), decrements it from 1 to 0 or waits to do so if it sees the semaphore already at 0. Releasing the semaphore, i.e. V(), increments the semaphore unless a waiter is there, in which case the waiter is unblocked and the value becomes 0.
I have recently discovered that the ER does not align with this. Though I cannot find any Arm doc that categorically states that if the sequence is
WFE()
SEV() / isr
then the final ER value is 1, and NOT 0 as would be in the semaphore case, via experimentation (using a trusty LED on a Silabs starter kit), if I follow the above with
then that second WFE does NOT wait. It sees the ER at value 1, decrements it, and continues. It does NOT sleep.
Anyone care to comment on why this is the case?