Download FreeRTOS
 

Quality RTOS & Embedded Software

KERNEL
WHAT'S NEW
Simplifying Authenticated Cloud Connectivity for Any Device.
Designing an energy efficient and cloud-connected IoT solution with CoAP.
Introducing FreeRTOS Kernel version 11.0.0:
FreeRTOS Roadmap and Code Contribution process.
OPC-UA over TSN with FreeRTOS.

Event Bits (or flags) and Event Groups
[Inter-task communication and synchronisation]


On this page:


Event Bits (Event Flags)

Event bits are used to indicate if an event has occurred or not. Event bits are often referred to as event flags. For example, an application may:
  • Define a bit (or flag) that means "A message has been received and is ready for processing" when it is set to 1, and "there are no messages waiting to be processed" when it is set to 0.

  • Define a bit (or flag) that means "The application has queued a message that is ready to be sent to a network" when it is set to 1, and "there are no messages queued ready to be sent to the network" when it is set to 0.

  • Define a bit (or flag) that means "It is time to send a heartbeat message onto a network" when it is set to 1, and "it is not yet time to send another heartbeat message" when it is set to 0.


Event Groups

An event group is a set of event bits. Individual event bits within an event group are referenced by a bit number. Expanding the example provided above:
  • The event bit that means "A message has been received and is ready for processing" might be bit number 0 within an event group.

  • The event bit that means "The application has queued a message that is ready to be sent to a network" might be bit number 1 within the same event group.

  • The event bit that means "It is time to send a heartbeat message onto a network" might be bit number 2 within the same event group.


Event Group and Event Bits Data Types

Event groups are referenced by variables of type EventGroupHandle_t.

The number of bits (or flags) implemented within an event group depends on whether configUSE_16_BIT_TICKS or configTICK_TYPE_WIDTH_IN_BITS is used to control the type of TickType_t:

  • The number of bits (or flags) implemented 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 number of bits (or flags) implemented within an event group is 8 if configTICK_TYPE_WIDTH_IN_BITS is set to TICK_TYPE_WIDTH_16_BITS, or 24 if configTICK_TYPE_WIDTH_IN_BITS is set to TICK_TYPE_WIDTH_32_BITS, or 56 if configTICK_TYPE_WIDTH_IN_BITS is set to TICK_TYPE_WIDTH_64_BITS.

The dependency on configUSE_16_BIT_TICKS or configTICK_TYPE_WIDTH_IN_BITS results from the data type used for thread local storage in the internal implementation of RTOS tasks.

All the event bits in an event group are stored in a single unsigned variable of type EventBits_t. Event bit 0 is stored in bit position 0, event bit 1 is stored in bit position 1, and so on.

The image below represents a 24-bit event group that uses three bits to hold the three example events already described. In the image only event bit 2 is set.

An event group containing 24 event flags
An event group containing 24-event bits, only three of which are in use


Event Group RTOS API Functions

Event group API functions are provided that allow a task to, among other things, set one or more event bits within an event group, clear one or more event bits within an event group, and pend (enter the Blocked state so the task does not consume any processing time) to wait for a set of one or more event bits to become set within an event group.

Event groups can also be used to synchronise tasks, creating what is often referred to as a task 'rendezvous'. A task synchronisation point is a place in application code at which a task will wait in the Blocked state (not consuming any CPU time) until all the other tasks taking part in the synchronisation also reached their synchronisation point.


The Challenges an RTOS Must Overcome When Implementing Event Groups

The two main challenges an RTOS must overcome when implementing event groups are:
  1. Avoiding the creation of race conditions in the user's application:

    An event group implementation will create a race condition in the application if:

    • It is not clear who is responsible for clearing individual bits (or flags).

    • It is not clear when a bit is to be cleared.

    • It is not clear if a bit was set or clear at the time a task exited the API function that tested the bit's value (it could be that another task or interrupt has since changed the bit's state).

    The FreeRTOS event groups implementation removes the potential for race conditions by including built in intelligence to ensure setting, testing and clearing of bits appears atomic. Thread local storage and careful use of API function return values make this possible.

  2. Avoiding non-determinism:

    The event group concept implies non-deterministic behaviour because it is not know how many tasks are blocked on an event group, and therefore it is not known how many conditions will need to be tested or tasks unblocked when an event bit is set.

    The FreeRTOS quality standards do not permit non-deterministic actions to be performed while interrupts are disabled, or from within interrupt service routines. To ensure these strict quality standards are not breached when an event bit is set:

    • The RTOS scheduler's locking mechanism is used to ensure interrupts remain enabled when an event bit is set from an RTOS task.

    • The centralised deferred interrupt mechanism is used to defer the action of setting a bit to a task when an attempt is made to set an event bit from an interrupt service routine.


Example Code

Example code snippets are provided in the API documentation, and a comprehensive example is provided in the EventGroupsDemo.c set of standard demo tasks (the source file is located in the FreeRTOS/Demo/Common/Minimal directory of the main FreeRTOS download).



Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.