#include <Arduino_FreeRTOS.h>
#include <semphr.h>
#define LED_PIN 13
#define INTERRUPT_PIN 2
#define LED_DELAY_MS 3000 // 3秒間
SemaphoreHandle_t xSemaphore;
void Task1(void *pvParameters);
void Task2(void *pvParameters);
void handleInterrupt();
TaskHandle_t Task2Handle = NULL;
void setup() {
Serial.begin(115200); // デバッグ用シリアル通信開始
pinMode(LED_PIN, OUTPUT);
pinMode(INTERRUPT_PIN, INPUT_PULLUP); // 外部割り込みピンを入力に設定し、内部のプルアップ抵抗を有効化する
// 外部割り込みを設定し、立ち下がりエッジ(SWを押したタイミング)に反応するようにする
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), handleInterrupt, FALLING);
// 2つのタスク間でバイナリセマフォンを作成する
xSemaphore = xSemaphoreCreateBinary();
// タスク1を作成 (優先度が高い)
xTaskCreate(
Task1,
"Task1", // LEDを点灯させるタスク
128, // スタックサイズ
NULL,
2, // 優先度
NULL
);
// タスク2を作成 (優先度が低い)
xTaskCreate(
Task2,
"Task2", // セマフォを返却するタスク
128, // スタックサイズ
NULL,
1, // 優先度
&Task2Handle
);
}
void loop() {
// 空のループ。処理はタスク内で実行される
}
void Task1(void *pvParameters) {
(void) pvParameters;
for (;;) {
// セマフォを待ち続け、割り込みで解放されるまで停止する
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
Serial.println("Task1: セマフォを取得しました LEDを3秒点灯します");
digitalWrite(LED_PIN, HIGH); // LEDを点灯させる
vTaskDelay(LED_DELAY_MS / portTICK_PERIOD_MS); // 指定された時間待機する
digitalWrite(LED_PIN, LOW); // LEDを消灯させる
Serial.println("Task1: LEDを消灯しました。セマフォ待ちに戻ります");
}
}
}
void Task2(void *pvParameters) {
(void) pvParameters;
for (;;) {
// タスクが一時停止から再開されるのを待つ
vTaskSuspend(NULL); // タスクを一時停止する
Serial.println("Task2: セマフォを返却します");
xSemaphoreGive(xSemaphore);
}
}
// 割り込みハンドラ
void handleInterrupt() {
// 割り込みハンドラからTask2を再開する
Serial.println("スイッチにより割り込みハンドラが起動し、Task2を再開します。");
xTaskResumeFromISR(Task2Handle);
}