Extra 5% OFF Use Code: OL05
Free Shipping over ₹999

Event Groups

Event Groups in FreeRTOS provide a way to synchronize multiple tasks based on specific events or conditions. They allow tasks to wait for multiple events to be set or cleared, providing a convenient way to manage complex inter-task dependencies. An event group is essentially a collection of bits, each representing a specific event. Tasks can wait on certain bits within the event group to be set (or cleared), and the RTOS will unblock them once the required condition is met.

Example: Event Group Synchronization

Consider a scenario where we have multiple tasks:

  1. Sensor Task: Reads sensor data and sets an event when data is available.
  2. Network Task: Connects to a network and sets an event when connected.
  3. Processing Task: Starts processing only if both the Sensor Task has provided data and the Network Task is connected.

In this example, Processing Task will wait for both the Sensor and Network events to be set before proceeding.

Code Example

Event Groups in FreeRTOS provide a way to synchronize multiple tasks based on specific events or conditions. They allow tasks to wait for multiple events to be set or cleared, providing a convenient way to manage complex inter-task dependencies. An event group is essentially a collection of bits, each representing a specific event. Tasks can wait on certain bits within the event group to be set (or cleared), and the RTOS will unblock them once the required condition is met.

Example: Event Group Synchronization

Consider a scenario where we have multiple tasks:

  1. Sensor Task: Reads sensor data and sets an event when data is available.
  2. Network Task: Connects to a network and sets an event when connected.
  3. Processing Task: Starts processing only if both the Sensor Task has provided data and the Network Task is connected.

In this example, Processing Task will wait for both the Sensor and Network events to be set before proceeding.

Code Example

Event Groups in FreeRTOS provide a way to synchronize multiple tasks based on specific events or conditions. They allow tasks to wait for multiple events to be set or cleared, providing a convenient way to manage complex inter-task dependencies. An event group is essentially a collection of bits, each representing a specific event. Tasks can wait on certain bits within the event group to be set (or cleared), and the RTOS will unblock them once the required condition is met.

Example: Event Group Synchronization

Consider a scenario where we have multiple tasks:

  1. Sensor Task: Reads sensor data and sets an event when data is available.
  2. Network Task: Connects to a network and sets an event when connected.
  3. Processing Task: Starts processing only if both the Sensor Task has provided data and the Network Task is connected.

In this example, Processing Task will wait for both the Sensor and Network events to be set before proceeding.

Code Example

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

// Event Group handle
EventGroupHandle_t xEventGroup;

// Event bits
#define SENSOR_READY_BIT (1 << 0)  // 0x01
#define NETWORK_READY_BIT (1 << 1) // 0x02

// Sensor Task: Sets SENSOR_READY_BIT when sensor data is available
void vSensorTask(void *pvParameters) {
    while (1) {
        // Simulate sensor data reading
        printf("Sensor: Data is ready\n");

        // Set the SENSOR_READY_BIT in the event group
        xEventGroupSetBits(xEventGroup, SENSOR_READY_BIT);

        // Delay to simulate sensor reading interval
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

// Network Task: Sets NETWORK_READY_BIT when network is connected
void vNetworkTask(void *pvParameters) {
    while (1) {
        // Simulate network connection
        printf("Network: Connected\n");

        // Set the NETWORK_READY_BIT in the event group
        xEventGroupSetBits(xEventGroup, NETWORK_READY_BIT);

        // Delay to simulate network check interval
        vTaskDelay(pdMS_TO_TICKS(2000));
    }
}

// Processing Task: Waits until both SENSOR_READY_BIT and NETWORK_READY_BIT are set
void vProcessingTask(void *pvParameters) {
    const EventBits_t xBitsToWaitFor = SENSOR_READY_BIT | NETWORK_READY_BIT;

    while (1) {
        // Wait for both bits to be set in the event group
        printf("Processing Task: Waiting for both Sensor and Network readiness...\n");
        EventBits_t uxBits = xEventGroupWaitBits(
            xEventGroup,           // Event group handle
            xBitsToWaitFor,         // Bits to wait for
            pdTRUE,                 // Clear bits on exit
            pdTRUE,                 // Wait for all bits
            portMAX_DELAY           // Wait indefinitely
        );

        // Check if both bits are set
        if ((uxBits & xBitsToWaitFor) == xBitsToWaitFor) {
            printf("Processing Task: Both Sensor and Network are ready. Processing data...\n");
            // Simulate data processing
            vTaskDelay(pdMS_TO_TICKS(500));
        }
    }
}

void app_main() {
    // Create the event group
    xEventGroup = xEventGroupCreate();

    // Create tasks
    xTaskCreate(vSensorTask, "Sensor Task", 2048, NULL, 1, NULL);
    xTaskCreate(vNetworkTask, "Network Task", 2048, NULL, 1, NULL);
    xTaskCreate(vProcessingTask, "Processing Task", 2048, NULL, 1, NULL);
}

Explanation

  1. Event Group Initialization:
    • xEventGroup is created with xEventGroupCreate() in app_main(). This event group will be used to synchronize the three tasks.
  2. Sensor Task (vSensorTask):
    • Simulates reading data from a sensor and sets the SENSOR_READY_BIT in xEventGroup using xEventGroupSetBits().
    • This bit indicates that sensor data is available.
    • Runs every 1 second, simulating the availability of data from a sensor at this interval.
  3. Network Task (vNetworkTask):
    • Simulates a network connection and sets the NETWORK_READY_BIT using xEventGroupSetBits().
    • This bit indicates that the network connection is established.
    • Runs every 2 seconds, representing a delay in network connection establishment.
  4. Processing Task (vProcessingTask):
    • Waits until both SENSOR_READY_BIT and NETWORK_READY_BIT are set using xEventGroupWaitBits().
    • The xEventGroupWaitBits() function waits indefinitely (portMAX_DELAY) until both bits are set, meaning both the sensor and network are ready.
    • The task clears these bits (specified by pdTRUE) after they are read to reset the state, preparing it for the next cycle.
    • Once both events are available, it prints a message indicating that processing has begun.

Key Points

  • Event Group is used to wait for complex conditions involving multiple events, as opposed to single-flag synchronization like binary semaphores.
  • xEventGroupSetBits(): Used to set specific bits in the event group when an event occurs.
  • xEventGroupWaitBits(): Allows a task to wait for one or more bits to be set in the event group before continuing.
  • pdTRUE in xEventGroupWaitBits(): Clears the event bits after reading, making it suitable for tasks that should wait for fresh events each time.

Output Simulation

The output will look like:

Explanation

  1. Event Group Initialization:
    • xEventGroup is created with xEventGroupCreate() in app_main(). This event group will be used to synchronize the three tasks.
  2. Sensor Task (vSensorTask):
    • Simulates reading data from a sensor and sets the SENSOR_READY_BIT in xEventGroup using xEventGroupSetBits().
    • This bit indicates that sensor data is available.
    • Runs every 1 second, simulating the availability of data from a sensor at this interval.
  3. Network Task (vNetworkTask):
    • Simulates a network connection and sets the NETWORK_READY_BIT using xEventGroupSetBits().
    • This bit indicates that the network connection is established.
    • Runs every 2 seconds, representing a delay in network connection establishment.
  4. Processing Task (vProcessingTask):
    • Waits until both SENSOR_READY_BIT and NETWORK_READY_BIT are set using xEventGroupWaitBits().
    • The xEventGroupWaitBits() function waits indefinitely (portMAX_DELAY) until both bits are set, meaning both the sensor and network are ready.
    • The task clears these bits (specified by pdTRUE) after they are read to reset the state, preparing it for the next cycle.
    • Once both events are available, it prints a message indicating that processing has begun.

Key Points

  • Event Group is used to wait for complex conditions involving multiple events, as opposed to single-flag synchronization like binary semaphores.
  • xEventGroupSetBits(): Used to set specific bits in the event group when an event occurs.
  • xEventGroupWaitBits(): Allows a task to wait for one or more bits to be set in the event group before continuing.
  • pdTRUE in xEventGroupWaitBits(): Clears the event bits after reading, making it suitable for tasks that should wait for fresh events each time.

Output Simulation

The output will look like:

Sensor: Data is ready
Network: Connected
Processing Task: Waiting for both Sensor and Network readiness...
Processing Task: Both Sensor and Network are ready. Processing data...
Sensor: Data is ready
Processing Task: Waiting for both Sensor and Network readiness...
Network: Connected
Processing Task: Both Sensor and Network are ready. Processing data...

This example shows how Event Groups allow synchronization between multiple tasks, waiting until both conditions are met before performing a final task.

    Leave a Reply

    Your email address will not be published.

    Need Help?