ログイン トップページ
ソースコードの参照 : mutex01 (作成者: 三浦 元喜)
Hash:
注:このページのURLをシェアすると、他のユーザも参照したり、自分用にコピーしたりできるようになります。
#include <M5Unified.h>

// 1 にするとミューテックス有効、0 にすると無効
#define USE_MUTEX 1

SemaphoreHandle_t mutex;

// 複数タスクで共有する資源
int sharedCounter = 0;

void workerTask(void *pvParam) {
  const char* taskName = (const char*)pvParam;

  while (true) {
#if USE_MUTEX
    xSemaphoreTake(mutex, portMAX_DELAY);   // 共有資源をロック
#endif

    // 共有カウンタを更新(ここも共有資源)
    int myNo = ++sharedCounter;

    // ここから下は「1つのまとまり」で表示したい処理
    Serial.printf("\n[%s] ENTER  #%d\n", taskName, myNo);
    M5.Display.printf("\n[%s] ENTER  #%d\n", taskName, myNo);

    for (int i = 1; i <= 5; i++) {
      Serial.printf("[%s] step %d/5  (counter=%d)\n", taskName, i, myNo);
      M5.Display.printf("[%s] step %d/5  (counter=%d)\n", taskName, i, myNo);

      // わざと少し待つことで、排他なしだと混ざりやすくする
      vTaskDelay(pdMS_TO_TICKS(200));
    }

    Serial.printf("[%s] LEAVE  #%d\n", taskName, myNo);
    M5.Display.printf("[%s] LEAVE  #%d\n", taskName, myNo);

#if USE_MUTEX
    xSemaphoreGive(mutex);                  // ロック解除
#endif

    // 次の順番まで少し待つ
    vTaskDelay(pdMS_TO_TICKS(500));
  }
}

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.setTextScroll(true);
  M5.Display.clear();

  Serial.println("Mutex demo start");
  M5.Display.println("Mutex demo start");
  M5.Display.println("USE_MUTEX = 1 なら整然、0 なら混ざる");

#if USE_MUTEX
  mutex = xSemaphoreCreateMutex();
  if (mutex == NULL) {
    Serial.println("mutex create failed");
    M5.Display.println("mutex create failed");
    while (1) { delay(1000); }
  }
#endif

  // 3つのタスクを起動
  xTaskCreatePinnedToCore(workerTask, "TaskA", 4096, (void*)"TaskA", 1, NULL, 1);
  xTaskCreatePinnedToCore(workerTask, "TaskB", 4096, (void*)"TaskB", 1, NULL, 1);
  xTaskCreatePinnedToCore(workerTask, "TaskC", 4096, (void*)"TaskC", 1, NULL, 1);
}

void loop() {
  // タスク側で動くので loop() は何もしない
  vTaskDelay(pdMS_TO_TICKS(1000));
}