// Include header files of FreeRTOS and event groups
#include <Arduino_FreeRTOS.h> // Thêm thư viện FreeRTOS cho Arduino
#include "event_groups.h" // Thêm thư viện quản lý Event Group của FreeRTOS
// define three event flag bit variable
#define TASK1_BIT (1UL << 0UL) // Định nghĩa bit 0 cho sự kiện Task 1 (dịch bit 1 sang trái 0 vị trí)
#define TASK2_BIT (1UL << 1UL) // Định nghĩa bit 1 cho sự kiện Task 2 (dịch bit 1 sang trái 1 vị trí)
#define TASK3_BIT (1UL << 2UL) // Định nghĩa bit 2 cho sự kiện Task 3 (dịch bit 1 sang trái 2 vị trí)
// declare a event grounp handler variable
EventGroupHandle_t xEventGroup; // Khai báo biến kiểu EventGroupHandle_t để lưu trữ handle của Event Group
// A constant to define 500ms delay
//because we use to periodically execute each task
//after every 500ms
const TickType_t xDelay500ms = pdMS_TO_TICKS(500); // Hằng số lưu trữ thời gian delay 500ms (chuyển đổi từ ms sang TickType_t)
void setup()
{
// intialize uart module with baud rate of 9600
Serial.begin(9600); // Khởi tạo Serial với baud rate 9600
//create event group and assign it a earlier created referene handler
xEventGroup = xEventGroupCreate(); // Tạo Event Group và gán handle cho biến xEventGroup
// Create three tasks which are used to release event with
// the help of above defined event flags
xTaskCreate(InputTask1, "Input Task 1", 100,NULL,1,NULL); // Tạo Task 1 (Input)
xTaskCreate(InputTask2, "Input Task 2", 100, NULL, 1, NULL ); // Tạo Task 2 (Input)
xTaskCreate(InputTask3, "Input Task 3", 100, NULL, 1,NULL); // Tạo Task 3 (Input)
//Create output task that will execute only when all three events occured
xTaskCreate(OutputTask, "Output Task", 100, NULL, 1, NULL); // Tạo Output Task (chạy khi cả 3 sự kiện xảy ra)
}
// defintion of input task1
void InputTask1(void *pvParameters)
{
while(1)
{
// set flag bit TASK1_BIT
xEventGroupSetBits(xEventGroup, TASK1_BIT); // Set bit TASK1_BIT trong Event Group
//delay this task for 500ms
vTaskDelay(xDelay500ms); // Tạm dừng task trong 500ms
}
}
// defintion of input task2
void InputTask2(void *pvParameters)
{
while(1)
{
// set flag bit TASK2_BIT
xEventGroupSetBits(xEventGroup, TASK2_BIT); // Set bit TASK2_BIT trong Event Group
//delay this task for 500ms
vTaskDelay(xDelay500ms); // Tạm dừng task trong 500ms
}
}
// defintion of input task3
void InputTask3(void *pvParameters)
{
while(1)
{
// set flag bit TASK2_BIT
xEventGroupSetBits(xEventGroup,TASK3_BIT); // Set bit TASK3_BIT trong Event Group
//delay this task for 500ms
vTaskDelay(xDelay500ms); // Tạm dừng task trong 500ms
}
}
// Definition of output task
void OutputTask(void *pvParameters)
{
// define a variable which holds the state of events
const EventBits_t xBitsToWaitFor = (TASK1_BIT | TASK2_BIT | TASK3_BIT); // Biến lưu giá trị bit mong muốn (cả 3 bit)
EventBits_t xEventGroupValue;
while(1)
{
// Chờ cho đến khi tất cả các bit trong xBitsToWaitFor được set trong xEventGroup
xEventGroupValue = xEventGroupWaitBits(xEventGroup,
xBitsToWaitFor, // Các bit cần chờ
pdTRUE, // Xóa các bit đã được set sau khi đọc
pdTRUE, // Chờ tất cả các bit
portMAX_DELAY // Chờ vô hạn
);
if((xEventGroupValue & TASK1_BIT) !=0) // Kiểm tra xem bit TASK1_BIT đã được set hay chưa
{
Serial.println("Task1 event occured"); // In thông báo nếu bit TASK1_BIT đã được set
}
if((xEventGroupValue & TASK2_BIT !=0)) // Kiểm tra xem bit TASK2_BIT đã được set hay chưa
{
Serial.println("Task2 event occured"); // In thông báo nếu bit TASK2_BIT đã được set
}
if((xEventGroupValue & TASK3_BIT !=0)) // Kiểm tra xem bit TASK3_BIT đã được set hay chưa
{
Serial.println("Task3 event occured"); // In thông báo nếu bit TASK3_BIT đã được set
}
}
}
void loop(){} // Hàm loop rỗng, không sử dụng trong trường hợp này