#include <Arduino_FreeRTOS.h>

// Định nghĩa handle cho các task
TaskHandle_t Task1Handle;
TaskHandle_t Task2Handle;

// Định nghĩa hằng số cho thời gian đình chỉ Task1
const TickType_t suspensionTime = 10000 / portTICK_PERIOD_MS; // 10s
const int Task1Repeat = 5; // Số lần Task1 thực hiện

// Task1: In ra "Hello, world!"
void Task1(void *pvParameters) {
  for (;;) {
    for (int i = 0; i < Task1Repeat; i++) {
      Serial.println("Hello, world!");
      vTaskDelay(1000 / portTICK_PERIOD_MS); // Chờ 1 giây
    }
    xTaskNotifyGive(Task2Handle); // Thông báo cho Task2
    vTaskSuspend(NULL); // Đình chỉ chính mình
  }
}

// Task2: In ra "Bye Task1" và đình chỉ Task1 trong 10s
void Task2(void *pvParameters) {
  for (;;) {
    // Đợi cho đến khi nhận được thông báo từ Task1
    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

    Serial.println("Bye Task1");
    vTaskSuspend(Task1Handle); // Đình chỉ Task1

    // Chờ 10s
    vTaskDelay(suspensionTime);

    // Tiếp tục Task1
    vTaskResume(Task1Handle);
  }
}

void setup() {
  // Khởi tạo Serial Monitor
  Serial.begin(9600);
  while (!Serial) {} // Đợi Serial Monitor mở

  // Tạo Task1 và Task2 với mức ưu tiên tương đương
  xTaskCreate(Task1, "Task1", 128, NULL, 1, &Task1Handle);
  xTaskCreate(Task2, "Task2", 128, NULL, 1, &Task2Handle);

  // In ra mức ưu tiên của các task
  Serial.print("Priority of Task1: ");
  Serial.println(uxTaskPriorityGet(Task1Handle));
  Serial.print("Priority of Task2: ");
  Serial.println(uxTaskPriorityGet(Task2Handle));

  // Bắt đầu scheduler của FreeRTOS
  vTaskStartScheduler();
}

void loop() {
  // Không cần làm gì trong hàm loop
}