#include <M5Unified.h>

xSemaphoreHandle mutex; //ミューテックス(排他制御用)

void withArgTask(void *pvParam) {
  int num = *(int*) pvParam; // 引数は、グローバル変数のアドレスをポインタで渡す
  BaseType_t mStatus;
  char* tsknm = pcTaskGetTaskName(NULL); //自タスク名を取得するならNULL、他タスク名を取得するならタスクハンドルを引数に指定する。
  while (1) {
    mStatus = xSemaphoreTake(mutex, 500); // ミューテックスを取得
    if (mStatus == pdPASS) {
      Serial.println("----");
      Serial.printf("[%s] ", tsknm );
      M5.Display.println("----");
      M5.Display.printf("[%s] ", tsknm );
      delay(500);
      for (int i = 1; i < 6; i++) {
        Serial.printf("%d ", i * num);
        M5.Display.printf("%d ", i * num);
        delay(300);
      }
      delay(300);
      Serial.printf("done \n");
      M5.Display.printf("done \n");
      delay(300);
      xSemaphoreGive(mutex); // ミューテックスを解放
      vTaskDelete(NULL); // 自タスクを削除する
    } else {
      delay(random(10,100)); //ミューテックスがとれなかったらランダムに待つ
    }
  }
}

int arg[] = {2, 3, 5, 7, 11} ;
char tskname[5];

void setup() {
  auto cfg = M5.config();
  cfg.serial_baudrate = 115200;
  M5.begin(cfg);
  M5.Display.setRotation(3); //横向き
  M5.Display.setFont(&fonts::lgfxJapanGothic_16);
  M5.Display.println("シリアルにも出力します");
  M5.Display.setTextScroll(true);

  mutex = xSemaphoreCreateMutex(); // ミューテックス作成
}

void loop() {
  Serial.println("-------");
  if (mutex != NULL) { // ミューテックスの作成に成功していたら
    for (int i = 0; i < 5; i++) {
      sprintf(tskname, "x%d", arg[i]);
      xTaskCreatePinnedToCore(withArgTask, tskname, 4096, &arg[i], 1, NULL , 1);
    }
  }
  M5.delay(20 * 1000); // 次のタスクの仕込みまで、20秒待つ
}
