📖 Scenario: You are building a simple embedded system using FreeRTOS. The system should respond to button presses by sending events to a task that processes them. This simulates how event-driven architecture works in real devices.
🎯 Goal: Create a FreeRTOS program that uses an event queue to handle button press events. You will set up the event queue, send events from an interrupt handler, and process them in a task.
📋 What You'll Learn
Create an event queue called eventQueue with space for 5 events
Define an event type ButtonEvent as an integer
Create a task called EventProcessorTask that waits for events from eventQueue
Simulate sending a button press event with value 1 to eventQueue
Print the received event value inside EventProcessorTask
💡 Why This Matters
🌍 Real World
Event-driven architecture is common in embedded systems where tasks react to hardware events like button presses or sensor signals.
💼 Career
Understanding event queues and task communication is essential for embedded software developers working with real-time operating systems like FreeRTOS.
Progress0 / 4 steps
1
Setup Event Queue and Event Type
Create a FreeRTOS queue called eventQueue that can hold 5 integers. Define a type ButtonEvent as int.
FreeRTOS
Hint
Use xQueueCreate to make the queue. The queue holds 5 items of type ButtonEvent.
2
Create Event Processor Task
Write a FreeRTOS task function called EventProcessorTask that waits indefinitely to receive a ButtonEvent from eventQueue. Inside the task, declare a variable event of type ButtonEvent to receive the event.
FreeRTOS
Hint
Use xQueueReceive with portMAX_DELAY to wait forever for an event.
3
Send Button Press Event
Inside the setup function, send a button press event with value 1 to eventQueue using xQueueSend.
FreeRTOS
Hint
Create a variable pressEvent with value 1 and send it to eventQueue with zero wait time.
4
Print Event in Task
Add a main function that calls setup(), creates the EventProcessorTask with priority 1, and starts the FreeRTOS scheduler. The program should print Received event: 1 when the event is processed.
FreeRTOS
Hint
Use xTaskCreate to create the task and vTaskStartScheduler() to start FreeRTOS. The program prints the event when received.
Practice
(1/5)
1. What is the main benefit of using event-driven architecture in FreeRTOS?
easy
A. It makes the program run all tasks continuously without waiting.
B. It requires more CPU power to check all events constantly.
C. The program reacts only when an event occurs, saving CPU time.
D. It disables multitasking to focus on one task at a time.
Event-driven architecture means the program waits and reacts only when events happen, not running tasks all the time.
Step 2: Connect to FreeRTOS event groups
FreeRTOS event groups let tasks wait efficiently for events, saving CPU time by not running unnecessarily.
Final Answer:
The program reacts only when an event occurs, saving CPU time. -> Option C
Quick Check:
Event-driven = React on event, save CPU [OK]
Hint: Event-driven means react only on events, not always running [OK]
Common Mistakes:
Thinking event-driven runs all tasks continuously
Believing it uses more CPU by checking constantly
Confusing event-driven with disabling multitasking
2. Which of the following is the correct way to create an event group in FreeRTOS?
easy
A. EventGroup xEventGroup = xCreateEventGroup();
B. EventGroupHandle_t xEventGroup = xEventGroupCreate();
C. xEventGroup = EventGroupCreate();
D. EventGroupHandle_t xEventGroup = createEventGroup();
Solution
Step 1: Recall FreeRTOS event group creation syntax
The official FreeRTOS function to create an event group is xEventGroupCreate(), returning EventGroupHandle_t.
Step 2: Match the correct syntax
EventGroupHandle_t xEventGroup = xEventGroupCreate(); uses the correct function name and type: EventGroupHandle_t xEventGroup = xEventGroupCreate();
Final Answer:
EventGroupHandle_t xEventGroup = xEventGroupCreate(); -> Option B
Quick Check:
Correct function and type = EventGroupHandle_t xEventGroup = xEventGroupCreate(); [OK]
Hint: FreeRTOS event groups use xEventGroupCreate() function [OK]
Common Mistakes:
Using wrong function names like createEventGroup()
Missing the correct handle type EventGroupHandle_t
Incorrect capitalization or function syntax
3. Given the code snippet: <pre>EventGroupHandle_t xEventGroup = xEventGroupCreate();
// Task A waits for bit 0 and bit 1
EventBits_t uxBits = xEventGroupWaitBits(xEventGroup, (1 << 0) | (1 << 1), pdTRUE, pdTRUE, portMAX_DELAY);
// Task B sets bit 0
xEventGroupSetBits(xEventGroup, (1 << 0));
// Task C sets bit 1
xEventGroupSetBits(xEventGroup, (1 << 1));
// What is the value of uxBits after Task A unblocks?
medium
A. 0x03 (both bits 0 and 1 set)
B. 0x01 (only bit 0 set)
C. 0x02 (only bit 1 set)
D. 0x00 (no bits set)
Solution
Step 1: Understand xEventGroupWaitBits parameters
Task A waits for bits 0 and 1 together (bitmask 0x03), clears bits on exit (pdTRUE), waits for all bits (pdTRUE), and waits indefinitely.
Step 2: Analyze bit setting by Task B and Task C
Task B sets bit 0 (0x01), Task C sets bit 1 (0x02). When both bits are set, Task A unblocks and uxBits contains both bits set (0x03).
Final Answer:
0x03 (both bits 0 and 1 set) -> Option A
Quick Check:
Wait for bits 0 & 1 set = 0x03 [OK]
Hint: WaitBits returns all requested bits set when unblocked [OK]
Common Mistakes:
Assuming only one bit is set when unblocked
Ignoring that wait is for all bits (pdTRUE)
Confusing bit masks with decimal values
4. Identify the error in this FreeRTOS event group usage:
A. xEventGroupSetBits requires a pointer, not a handle.
B. Bit mask (1 << 0) is invalid.
C. Event groups cannot set bits directly.
D. xEventGroup is not created before use.
Solution
Step 1: Check event group initialization
xEventGroup is declared but never created with xEventGroupCreate(), so it is uninitialized (likely NULL).
Step 2: Understand consequences of uninitialized handle
Calling xEventGroupSetBits with an uninitialized handle causes undefined behavior or crash.
Final Answer:
xEventGroup is not created before use. -> Option D
Quick Check:
Create event group before use [OK]
Hint: Always create event group before setting bits [OK]
Common Mistakes:
Forgetting to call xEventGroupCreate()
Thinking bit mask is invalid
Misunderstanding handle vs pointer usage
5. You want a FreeRTOS task to wait for either bit 2 or bit 3 to be set in an event group, but not both. Which call correctly implements this behavior?