Page 1 of 1

Using more than 24 bits in EventGroups

Posted: Thu Nov 18, 2021 6:39 am
by RichPiano
The maximum bits that an EventGroup can hold and that can subsequently be observed by xEventGroupWaitBits() is 24 bits. However, I'm using event groups extensively throughout my program and I wanted to ask if there is some established or hacky way to wait for more than 24 bits at a time in xEventGroupWaitBits()?

Re: Using more than 24 bits in EventGroups

Posted: Fri Nov 19, 2021 8:06 am
by levente
Not sure there would be a way that is safe/clean - the 8 vs 24 bit event groups are very built into FreeRTOS internals, there is even dependency on their internal use of the data types at even task implementation level. So below suggests that even if one somehow hacked the size of event groups, the way in which things are stored and manipulated by all of the FreeRTOS event group APIs would not be easily switchable to anything other than what they specify:

"The number of bits (or flags) stored within an event group is 8 if configUSE_16_BIT_TICKS is set to 1, or 24 if configUSE_16_BIT_TICKS is set to 0. The dependency on configUSE_16_BIT_TICKS results from the data type used for thread local storage in the internal implementation of tasks." (https://www.freertos.org/FreeRTOS-Event-Groups.html)

Re: Using more than 24 bits in EventGroups

Posted: Fri Nov 19, 2021 9:31 am
by RichPiano
Thanks I almost thought so. What I figured could work was if I could simultanously check bits from multiple event groups and have the thread on hold until one of the bits is set. Is that possible somehow?

Re: Using more than 24 bits in EventGroups

Posted: Fri Nov 19, 2021 12:46 pm
by levente
Hmmm haven't tried, only split things into multiple groups - but if needing to wait on multiple events bits "across" the different groups, not quite sure how it would be done. The FreeRTOS function can exit wait for a mask of expected bits but only within same event group, so would think some thinking needs to be done at calling level - one way could be to regroup bits that the particular multi-bit wait wants to wait on. If they are within same group, then the multiple flag masks would work with existing FreeRTOS function.

Re: Using more than 24 bits in EventGroups

Posted: Fri Nov 19, 2021 1:36 pm
by chegewara
RichPiano wrote: Thanks I almost thought so. What I figured could work was if I could simultanously check bits from multiple event groups and have the thread on hold until one of the bits is set. Is that possible somehow?
It may be possible, but i would try to use TaskNotify instead, if 32 bits is enough.

Re: Using more than 24 bits in EventGroups

Posted: Sat Nov 20, 2021 8:43 am
by RichPiano
The thing is I'm trying to use event bits to synchronise across mulitple threads as part of a state machine. Some states wait for others to establish and one task could free multiple other tasks. I can't make it part of the API that one module must "know" about every other thread that is waiting for it :/

Re: Using more than 24 bits in EventGroups

Posted: Sat Nov 20, 2021 12:07 pm
by chegewara
Ok, in that case i would try this, but it may be not reliable if called from multiple tasks at the same time (order is important):
1. set "lower" bits (1st events group)
2. set "higher" bits (2nd events group)
3. wait "higher" bits events group
3. wait "lower" bits events group

When you receive higher events group then you can assume that lower events group is also set.
Now you can use 8/16/24 or any number bits in lower event group and make bit shift into higher events group.

There is another option you could try to use, which is more reliable than 2 events groups.
https://docs.espressif.com/projects/esp ... event.html

Re: Using more than 24 bits in EventGroups

Posted: Wed Nov 24, 2021 10:30 am
by RichPiano
I've just had another idea:

- Divide all event groups into logical groups.
- Use one toplevel eventgroup which contains BITS corresponding to the subgroups. The idea is that tasks only listen to the toplevel eventgroup. And when bits change this is representative of one bit changing within that respective logical group, so the task only then starts listening to the respective subgroup.

This means implementation wise that..:

- I need a task that acts as a "setter" for the bit in the overarching event group. This task always listens to any bit within the group and sets the bit in the overarching group to 1 if it changes.
- The tasks listening to the overarching group always reset the bits to 1 in any case to signal that changes have been processed

Problems:
- When a task has not yet plowed through the instructions until WaitBits() then it might miss the change in another module entirely.
- Listener and setter tasks necessary in any submodule

IDK it's not really a practical solution tbh, but I figure it could work. Or I just build a wrapper for TaskNotify and globally include that so I can redirect TaskNotify calls according to my own bit settings.