ESP32: Task Synchronization – FreeRTOS Event Groups
|In the context of multi processing, task synchronization is very important concept. In this post we will see how to use event groups for task synchronization
Task Synchronization :
Before knowing how part of synchronization, First understand what is Task synchronization.
synchronization object (SO)
when we have multiple tasks executing , there might be a situation where one task1 needs to know if the task2 and task3 reached a particular point. There can be many practical conditions where we need such synchronization checks
This many involve a conjunction (AND) or disjunction (OR) of events. Consider an example, a engine failure condition may be defined as
- low lubricant level or Temperature rise within 30sec after start-up
- low oil pressure AND high temperature
This general task synchronization is common in OS level and also at program level. In this blog, let us consider only RTOS.
RTOS provides two solutions for this type of problems.
- Event Flags / Event Flag Groups
- Semaphores as Signals (A signal is, according to the UNIX terminology, a notification sent to a process that will interrupt that process. In order to catch a signal a process must have a signal handler. This is like interrupt in software programming)
Here we will take deep dive at Event Groups
Consider for example we have two tasks , whose work is to print WiFi status whenever there is a change in WiFi state (Connected or Disconnected). One task (“printWiFiIP“) will print the IP details when ever WiFi is connected to a AP , another task (“printWiFiDiscntdMsg“) will print a message saying the network is disconnected whenever WiFi is disconnected from AP.
First we define the Event Group to hold the event flags
static EventGroupHandle_t wifi_event_group; const int CONNECTED_EVENT = BIT0; const int DISCONNECTED_EVENT = BIT1;
Important methods :
xEventGroupCreate()
xEventGroupWaitBits(EventGroup,BitsToWaitFor,ClearTheBitsOnExit,WaitForAllBits,TimeOut)
xEventGroupSetBits(EventGroup,BitsToSet)
xEventGroupClearBits(EventGroup,BitsToClear)
printWiFiIP task will wait for the CONNECTED_EVENT and creats it automatically
xEventGroupWaitBits(wifi_event_group,CONNECTED_EVENT ,true,true,portMAX_DELAY)
if you keep TimeOut as portMAX_DELAY , the task will wait until the event is set , means there is no timeout
printWiFiDiscntdMsg task will wait for the DISCONNECTED_EVENT and clears it automatically
xEventGroupWaitBits(wifi_event_group,DISCONNECTED_EVENT ,true,true,portMAX_DELAY)
The WiFi Event handler will set appropriate bits whenever there is a change in the WiFi state. For more on connecting to WiFi and WiFi Driver events read this post
full code is available at this git repo
FreeRTOS Events Group full API is available here
WiFi connection logic reference post
Disclaimer : Few RTOSs do not support the concept of Event Flags, thus no support for any form of disjunctive or conjunctive synchronisation. The usual argument for not supporting them is that it can be difficult to make timing deterministic (especially disjunction). Timing typically takes an O(N) form where N is the number of waiting tasks.
Thanks for the guide! Made it very clear by using a practical example.