5 years, 2 months ago.

EventFlags - behaviour

Hello EveryOne!

I'd like to get some answers on my questions according to EventFlags:

1. It is stated in the documentation that every EventFlags object can state up to 31 flags. "You can think of each instance of the EventFlags class as an event channel. There are 31 different flags available for each event.". In my inderstanding that it is like a buffer and if I put there 32 flags then the oldest one will just gone from the que. Is it correct understanding or an error will be caught?

2. EventFlag.wait_any works not as expected. Here is an example:

Flags definition

#define FLAG_BuzzerTick 100 // Buzzer Tick

Thread waiting for a flag thrown

while (true) {
    uint32_t flags_read = 0;
    flags_read = _ef.wait_any(FLAG_BuzzerTick, osWaitForever, true);
      buzz();
  }

In that example the Thread will receive any of Flags sent to the channel. And will execute buzz() routine after any of them received. I expect that it should block execution of the thread until it receives exactly FLAG_BuzzerTick and nothing more.

So, the following code works but it is a workaround I guess:

while (true) {
    uint32_t flags_read = 0;
    flags_read = _ef.wait_any(FLAG_BuzzerTick, osWaitForever, false);
    if (flags_read == FLAG_BuzzerTick) {
      buzz();
      _ef.clear(flags_read);
    }
  }

1 Answer

5 years, 2 months ago.

Hello Vladislav,

You can think of event flags as of 32-bit unsigned integers where each bit, except the most significant one, represents a flag. So it's like a bit array of 31 elements (the most significant bit is not used). In such bit array each element (bit) can be set (then the corresponding flag = 1) or cleared (the corresponding flag = 0). For example to check the flag at position three and give it a meaningful name:

#define FLAG_BuzzerTick  (1UL << 3)

or

uint32_t FLAG_BuzzerTick = (1UL << 3);    // 00000000000000000000000000001000

If you would like to check flag number 0 and 5 then:

#define FLAG_MOTOR     (1UL << 0) 
#define FLAG_SOLENOID  (1UL << 5)

#define MY_EVENT_FLAGS (FLAG_MOTOR | FLAG_SOLENOID)   // this is a bit-wise OR (not a logical OR)

or

uint32_t FLAG_MOTOR =     (1UL << 0) // 00000000000000000000000000000001
uint32_t FLAG_SOLENOID =  (1UL << 5) // 00000000000000000000000000100000
// then using a bit-wise OR (not a logical OR)
uint32_t  MY_EVENT_FLAGS = FLAG_MOTOR | FLAG_SOLENOID; // 00000000000000000000000000100001

To wait until both FLAG_MOTOR and FLAG_SOLENOID become set (both == 1) and then call buzz():

while (true) {
    myEventFlags.wait_all(MY_EVENT_FLAGS , osWaitForever, true);
    buzz();
}

Notice that the wait_all method doesn't care above the other flags (the status of other bits in myEventFlags).
The osWaitForever argument means that there is no beak from the wait loop after some timeout. Both FLAG_MOTOR and FLAG_SOLENOID must become set to continue with the buzz() function.
The true argument above means that the FLAG_MOTOR and FLAG_SOLENOID event flags will be cleared in myEventFlags afterward.
So you do not have to add:

if (flags_read == MY_EVENT_FLAGS ) {
    buzz();
    myEventFlags.clear(flags_read);
}

because that is built into the wait_all method.

Similarly, to wait until any of FLAG_MOTOR or FLAG_SOLENOID (it's enough if one of them) becomes set:

while (true) {
    myEventFlags.wait_any(MY_EVENT_FLAGS , osWaitForever, true);
    buzz();
}

Accepted Answer

Now it is clear. Thank you!

posted by Vladislav Kravchenko 06 Oct 2019